admin 4Comment

Tytuł tego tekstu jest oczywiście nieco podchwytliwy, ale dobrze obrazuje pewną pułapkę, w którą wpada wiele osób, chcących nauczyć się…no właśnie, tak naprawdę – czego?

Przyznaję, że sam na początku wpadłem w tę pułapkę, decydując kilka miesięcy temu, że „spróbuję nauczyć się tego Pythona”.  Na początku programowanie było przeze mnie rozumiane jako nauka języka, w którym mogę skomunikować się z komputerem, zamiast nauki zasad na jakich ta komunikacja jest oparta.

Konsekwencją tego błędnego podejścia do tematu jest, tak popularne w internetach, pytanie „Którego języka programowania się uczyć?”, jakby to właśnie odpowiedź na nie w 99% determinowała czy odniesiemy sukces czy porażkę w naszych zamiarach. Tymczasem wydaje mi się, że uczyć się języka programowania chcąc zostać programistą to trochę jak uczyć się na pamięć słownika, chcąc mówić w danym języku. Nie do końca na tym całość polega. Sam (najpewniej zbyt) dużo czasu spędziłem, zastanawiając się, którego języka zacząć się uczyć.

Ucząc się programowania, tak naprawdę uczymy się przynajmniej dwóch rzeczy. Jedną z nich jest, będący na tapecie, „język programowania”, czyli głównie składnia języka programowania – jego słowa kluczowe, symbole, to, jak wyglądają konkretne komendy, w jaki sposób oddzielamy elementy naszego programu (np. odpowiednim wcięciem lub nawiasem klamrowym) etc.

Jednak to tylko część zagadnienia, i coraz bardziej wydaje mi sie, że ta mniejsza. Drugą kwestią jest to, co możemy nazwać logiką programowania, czyli wiedza jak poskładać wymienione wyżej „klocki” ze sobą, aby osiągnąć zamierzony cel oraz jak zrobić to możliwie klarownie i optymalnie. W praktyce jest to umiejętność rozebrania problemu na części składowe i zajęcia się nimi jedna po drugiej, nie zapominając jednak, że sposób rozwiązania danego podproblemu może nam poważnie ułatwić lub utrudnić rozwiązanie kolejnego z częściowych problemów.

Brzmi to dość abstrakcyjnie, warto więc przedstawić to na jakimś prostym przykładzie. Nawet, jeśli jeszcze nie miałeś okazji poznać podstaw Pythona, czytaj dalej, powinieneś zrozumieć większość prezentowanego kodu oraz różnice między rozwiązaniami.

Weźmy ten temat, w którym opisuję sposób rozwiązania jednego z praktycznych zadań fantastycznego kursu Automate the Boring Stuff with Python. Przedstawię dwie wersje programu, który osiąga zamierzony cel jednak różnią się one nieco jeśli chodzi o zastosowane rozwiązania. Drugi z nich zdecydowanie góruje, jeśli chodzi o ‚logikę’ podejścia do zadania.

W telegraficznym skrócie: w zadaniu chodzi o to by napisany przez nas program konwertował dowolną listę, na przykład:

spam = ['apples', 'bananas', 'tofu', 'cats']

Do stringa w postaci:

"apples, bananas, tofu, and cats"

Pierwsze, nienajlepsze rozwiązanie:

def function(list):
    newlist = list[-1]
    del list[-1]
    for i in range(len(list)):
        print(list[i], end=', ')
    print('and ', end='')
    print(newlist)
spam = ['apples', 'bananas', 'tofu', 'cats']
function(spam)

Niby cel jest osiągnięty. Jednak kuleje tutaj klarowność rozwiązania. Nazwa funkcji nie odzwierciedla tego, co ma ona osiągać, wynik podawany jest w formie serii wyświetleń w tej samej linii – dużo sensowniej jest, kiedy dana funkcja zwraca (poprzez return) wynik, łatwiej z niej dzięki temu skorzystać w innym kontekście. Same rozwiązanie wewnątrz funkcji także mogłoby być osiągnięte sensowniej, na przykład tak:

def convertsToString(list):
    newString = ''
    for i in range(len(list)-1):
        newString += list[i] + ', '
    newString += 'and ' + list[-1]
    return newString

spam = ['apples', 'bananas', 'tofu', 'cats']
print(convertsToString(spam))

To druga, już sensowniejsza wersja rozwiązania problemu. Nadal można by szukać krótszego rozwiązania, ale już tutaj widoczny jest postęp wobec powyższego przykładu. Po nazwie funkcji widzimy co dzięki niej osiągniemy i zwraca ona (poprzez return) zamiast wyświetlić (poprzez print) wynik. Nie mnoży też niepotrzebnie list.

Korzystamy więc z niemal tych samych klocków – komend i elementów języka Python – osiągam niby ten sam cel (wyświetla się to, co miało być wyświetlone zgodnie z założeniem zadania) ale osiągamy go na różne sposoby.

Co więcej, znajomość sposobu rozwiązania danego problemu w jednym języku oznacza, że podobną logikę prowadzącą do celu mogę zastosować w innym języku programowania. Jakiś czas po rozpoczęciu nauki Pythona rozpocząłem też naukę podstaw języka Java i okazało się to dużo łatwiejsze, niż gdybym od razu rozpoczął od Javy. Teraz, wiedząc jak rozwiązać dany problem w Pythonie, mimo znajomości wyłącznie podstaw Javy, mogę spróbować rozwiązać go też za pomocą drugiego języka. Zobacz przykład rozwiązania zadania z tego tematu za pomocą języka Python:

def collatz(number):
    if number % 2 == 0:
        return number // 2
    else:
        return 3 * number + 1
    
while True:
    print('Input number')
    n = input()
    try:
        n = int(n)
    except:
        print('Please enter an integer')
        continue
    while n != 1:
        n = collatz(n)
        print(n)
    break

I program o zbliżonym działaniu w języku Java:

class Collatz {
    public Collatz(int number) {
        while (number != 1) {
            number = useCollatz(number);
            System.out.println(number); 
        }
    }
    int useCollatz(int num) {
        if (num % 2 == 0) {
            return num / 2;
        } else {
            return 3 * num + 1;
        }
    }
}

Wcześniejsza nauka programowania w języku Python dała mi podstawy w zastosowaniu programistycznego podejścia do analizy problemu, dzięki czemu teraz o wiele łatwiej rozwiązuje mi się kolejne zadania w Javie.

Wnioski? Jeśli zastanawiasz się, który język programowania będzie łatwiejszy do nauki, może sensowniej jest żebyś zaczął zastanawiać się nad tym, który język będzie bardziej przydatny do tego, czym chciałbyś się zajmować jako programista? Dzisiaj to pytanie wydaje mi się dużo sensowniejsze. Dopiero z perspektywy tych kilku miesięcy w pełni rozumiem, że uczę się programowania a nie języka Python albo Java.

4 thoughts on “Uczenie się języka programowania jest bez sensu

  1. Luk4 napisał(a):

    Bardzo fajny artykuł. Z biegiem lat siedząc w tworzeniu softu, życie weryfikuje, że jeden język programowania to za mało. Jak już wiesz o co chodzi to napisanie czegoś w innym języku nie stanowi problemu. Składni nie trzeba uczyć się na pamięć, zawsze można korzystać z manuali, bo nikt od Ciebie nie będzie oczekiwał znajomości na tzw. „blache” kilku języków. Co do metody w Javie useCollatz() muszę się przyczepić ponieważ dobra praktyka jest aby metoda miała tylko jeden return. Fakt metoda jest krótka i prosta ale gdyby była bardziej złożona to znacznie utrudnia to późniejszy refactoring kodu. Pozdrawiam

    1. admin napisał(a):

      Wielkie dzięki za opinię i za uwagę 🙂 Dotknąłeś też tematu, który ostatnio siedzi mi w głowie (i pewnie niedługo o nim napiszę), mianowicie – na ile Wy, doświadczeni programiści (albo szerzej – programiści pracujący w zawodzie) piszecie swój kod „z palca”?
      Co do zasady jednego return-a – bardzo ważna dla mnie uwaga, dzięki! Nie ukrywam, że jestem początkującym wannabe-programistą, a w Javie są to w ogóle początki początków i właśnie z nadzieją na takie uwagi (cenne dla mnie i dla innych samouków) zacząłem pisać tego bloga.
      Pozdrawiam!

Dodaj komentarz