Zaczynamy tutorial do Pythona. W tym epizodzie – prawdziwe „podstawy podstaw” tego języka.

Zakładam, że mamy go zainstalowanego + jakieś IDE, ewentualnie korzystamy z kompilatora online (nie wszystkie funkcjonalności można tam przetestować, ale nadaje się do podstaw nauki programowania).

Do dzieła.

Hello World

Rzecz najprostsza. Służy do tego komenda print zawierająca dane typu tekstowego (czyli w cudzysłowie). Wygląda to tak:

print("Hello World")

Możemy też wypisać dane zawarte w jakiejś zmiennej

msg = "Hello World"
print(msg)

Dobrą praktyką jest opleść kod naszego programu w pewien blok, który sprawia, że kod wywoływany jest tylko jeżeli bezpośrednio uruchomimy dany plik. Chroni nas on przed wywoływaniem kodu, który może znajdować się w pliku importowanym a nie bezpośrednio uruchamianym. W edytorze PyCharm możemy automatycznie ten blok wygenerować wpisując main i wciskając enter. Wygląda to tak:

if __name__ == '__main__':
    msg = "Hello World"
    print(msg)

Tutaj musimy zachować indentację, czyli każdy element w tym bloku ma wcięcie czterech spacji (albo jednego taba, ale nie jest wskazane mieszać taby i spacje). To się później przyda. Tego bloku robić nie musimy, ale w przypadku gdy nasz plik będzie nie bezpośrednio uruchamiany lecz importowany przez inny plik, ten blok zabezpieczy nasz kod przed przypadkowym wywołaniem się.

Kolejne możliwości funkcji print – możliwość wypisywania wielu elementów na raz oraz użycie separatora.

print("John", "Jane", "Jim", sep=", ")
#John, Jane, Jim

W komentarzu napisałem wynik tego kodu. Komentarze w Pythonie zaczynamy znakiem #. Takie linie nie są wykonywane i służą tylko i wyłącznie nam do robienia zapisków, które mogą okazać się pomocne.

Operatory w Pythonie

num = 10
print(num) #10
print(num + 1) #11
print(num * 2) #20
print(num - 1) #9
print(num / 2) #5.0
print(num // 2) #5
print(num % 2) #0
print("*" * 10)
#**********
print("Hello" + " World")
#Hello World

Operatory dodawania, mnożenia i odejmowania chyba nie powinny budzić jakichś emocji, działają tak jak można się po nich spodziewać. Dzielenie jest ciekawą sprawą. Można dzielić za pomocą „/” i uzyskać liczbę z wartością po przecinku (float, zupełnie inny typ niż int, czyli liczba całkowita bez wartości po przecinku) albo dzielić przy pomocy „//” co całkowicie eliminuje wartość po przecinku (w takim wypadku 5 / 2 to 2.5 zaś 5 // 2 to… 2).

Wart uwagi jest jeszcze operator, który podaje resztę z dzielenia. Reszta z dzielenia 10 przez 2 to zero. Zawsze, gdy reszta z dzielenia przez 2 wynosi zero mamy do czynienia z liczbą parzystą. Warto to sobie zapamiętać.

Uwagę zwrócić można też na mnożenie napisów (pomnożyliśmy znak „*” dziesięć razy). Dość osobliwe, ale możliwe i czasem używane. Również znak „+” w przypadku napisów służy do tzw. konkatenacji czyli po ludzku do łączenia w jeden napis. W przypadku liczb zaś mamy do czynienia ze zwykłym dodawaniem. To większość najczęściej w Pythonie używanych operatorów, choć jest ich jeszcze trochę.

Zabawy ze zmiennymi

Możemy przypisać kilka zmiennej w jednej linii, korzystając z przecinka:

a,b = 5,10
print(a, b, sep=", ")
#5, 10

W Pythonie łatwo możemy zamienić zawartość zmiennych, również przy użyciu przecinka:

a = 5
b = 10
print(a,b, sep=", ")
#5, 10
a,b = b,a
print(a,b, sep=", ")
#10, 5

Możemy dodawać wartość do zmiennych przy użyciu notacji skróconej (+=) albo pełnej, w ten sposób:

a = 5
print(a)
#5
a = a + 5
print(a)
#10
a+= 5
print(a)
#15

Odejmowanie, mnożenie i dzielenie działa analogicznie. Możemy też rzutować zmienne do danego typu. Tutaj zmienną liczbową (int) zamienimy na zmienną tekstową (str) i dostaniemy sklejony tekst:

a = "1"
b = 1
print(a + str(b))
#11

Teraz zrobimy odwrotnie i zmienną tekstową (str) zamienimy na liczbową (int) i dostaniemy wynik dodawania 1 + 1:

a = "1"
b = 1
print(int(a) + b)
#2

Możemy także liczbę zmiennoprzecinkową (float) zamienić na liczbę całkowitą:

a = 5.0000
print(int(a))
#5
b = 2.5
print(int(b))
#2

Jak widać ucina nie tylko zera ale wszystko, co się po przecinku znajduje. Tak działa int. Do typu float też możemy konwertować:

a = 5
print(float(a))
#5.0

Warto zauważyć, że z pewnego rodzaju niejawną konwersją mamy do czynienia gdy dzielimy liczby operatorem „/”. Oto przykłady:

a = 10
print(a / 2)
#5.0
b = 5
print(b / 2)
#2.5

User input

Do zbierania informacji z klawiatury służy funkcja input. Wyświetla ona prompt, czyli to, co wpiszemy do niej, następnie zatrzymuje program i czeka na wpisanie naszego napisu i wciśnięcie enter:

name = input("What's your name? ")
print(name)

Warto zauważyć, że możemy użyć cudzysłowów pojedynczych, ale musimy znajdujący się wewnątrz apostrof opatrzyć znakiem „\” (program musi wiedzieć, gdzie zaczyna a gdzie kończy się „prawdziwy” cudzysłów, czyli ten, który oplata cały nasz tekst):

name = input('What\'s your name? ')
print(name)

Znak „\” wykorzystywany jest do różnego rodzaju „ucieczkowych” znaków. Użyjmy taba (\t) oraz entera, znaku nowej linii (\n):

name = input('\tWhat\'s your name?\n ')
print(name)

Whats your name wyświetli się po tabie (czterech spacjach) zaś nasz tekst będziemy wpisywać „od entera” czyli nowej linii. To w zasadzie wszystko, jeżeli chodzi o „uczieczkowe” znaki – mamy nową linię (\n), tab (\t) oraz znak apostrofa, który „uciekamy” znakiem \.

Warto również poznać sposoby na formatowanie tekstu. Możemy oczywiście korzystać ze znaku plusa:

name = input("Whats your name?")
print("Hi " + name)

Nie jest to jednak wygodne. Są dwa inne sposoby na formatowanie. Pierwszy, nieco starszy, to funkcja format:

name = input("Whats your name?")
print("Hi {}!".format(name))

Nie będę tego tłumaczyć, jeżeli wygląda dziwnie, to mamy już nowszy sposób jakim są tzw. f-stringi:

name = input("Whats your name?")
print(f"Hi {name}!")

Zanim napiszemy cudzysłów musimy zaznaczyć f-string literką f zaś wewnątrz nawiasów wąsatych wpisujemy nazwę zmiennej, która ma się tam pojawić.

Typy, długość, funkcje

Dane wprowadzane przez input zawsze będą typu str (string czyli napis, łańcuch znaków). W przypadku naszego imienia nie powinno to dziwić:

name = input("Whats your name?")
print(f"Hi {name}!")
print(type(name))
#<class 'str'>

Jednak jeżeli zapytamy o wiek, możemy się zdziwić. Wpisanie liczby nie sprawi bowiem, że dane magicznie zamienią się w typ int (integer, liczba całkowita). To nadal jest napis:

age = input("How old are you?")
print(f"You are {age}!")
#You are 30!
print(type(age))
#<class 'str'>

Jeżeli zatem chcemy na przykład podać wiek naszego użytkownika w miesiącach (czyli pomnożyć wiek razy 12, bo tyle miesięcy ma jeden rok) to musimy najpierw tę liczbę jednak mimo wszystko podaną jako tekst do naszego inputa zamienić z napisu (str) na typ liczbowy (int):

age = int(input("How old are you?"))
print(f"You are {age}!")
#You are 30!
age_in_months = age * 12
print(f"You are {age_in_months} months old!")
#You are 360 months old!
print(type(age))
#<class 'int'>
print(type(age_in_months))
#<class 'int'>

Oczywiście możemy to zrobić w innym miejscu. Dla czytelności możemy to rozbić na dwie linijki:

age = input("How old are you?")
age = int(age)
print(f"You are {age}!")
#You are 30!
age_in_months = age * 12
print(f"You are {age_in_months} months old!")
#You are 360 months old!
print(type(age))
#<class 'int'>
print(type(age_in_months))
#<class 'int'>

Mało tego. Możemy zmienną age zostawić jako typ tekstowy, ponieważ z nią nie wykonujemy de facto żadnych obliczeń. Dokonujemy obliczenia w zmiennej age_in_months z jej wartością, którą możemy przekonwertować właśnie tam:

age = input("How old are you?")
print(f"You are {age}!")
#You are 30!
age_in_months = int(age) * 12
print(f"You are {age_in_months} months old!")
#You are 360 months old!
print(type(age))
#<class 'str'>
print(type(age_in_months))
#<class 'int'>

Warto znać też funkcję len, która pozwala nam dobrać się do długości danego tekstu:

name = input("Whats your name?")
name_len = len(name)
print(f"Your name is {name}.")
#Your name is Konrad.
print(f"Length of your name is {name_len}.")
#Length of your name is 6.

Istnieją inne funkcje, które możemy wywołać na tekście. Warto znać upper (podnosi wszystko do wielkiej litery), lower (odwrotnie, do małej), capitalize (pierwsza litera wielka) oraz swapcase (wielka zamieniona na małą a mała na wielką)

name = "john"
print(name.upper())
#JOHN
print(name.lower())
#john
print(name.capitalize())
#John
print(name.swapcase())
#JOHN

Nie musimy tego wywoływać na zmiennej. Na zwykłym tekście też możemy:

print("john".upper())
#JOHN
print("JOHN".lower())
#john
print("john".capitalize())
#John
print("jOHN".swapcase())
#John

Są też funkcje, które można wywołać tylko na liczbach. Np. abs (absolute value, wartość bezwzględna czyli bez minusów):

print(abs(3)) #3
print(abs(-3)) #3
print(abs(0)) #0

Jakby ktoś chciał się zagłębiać w matematykę na poziomie szkoły podstawowej (co wcale do programowania aż tak konieczne nie jest) to wartość bezwzględna to odległość od miejsca zero na osi liczbowej. I dla zarówno 3 jak i -3 ta odległość wynosi 3. Dla zera zero.

Są też funkcje na innych typach, na przykład typ lista. Dobrym przykładem jest tu max, min oraz sum a także len, które działa i na napisach i na listach podając ich długość:

my_list = [1,2,20,3]
print(max(my_list)) #20
print(min(my_list)) #1
print(sum(my_list)) #26
print(len(my_list)) #4

Blok warunkowy

Napiszemy sobie krótki program, który sprawdza, czy liczba jest parzysta czy nie. Parzysta to taka, której reszta z dzielenia przez 2 wynosi zero (swoją drogą obiecuję, że im dalej w programowanie tym zazwyczaj mniej matematyki niż więcej, choć pewien rodzaj logiki i myślenia jest wymagany, ale jeżeli kogoś te matematyczne wygibasy zrażają to zupełnie niepotrzebnie).

A zatem tak: bierzemy input od użytkownika. Zamieniamy typ tekstowy na liczbę. Tworzymy blok warunkowy z odpowiednim wcięciem (4 spacje albo jeden tab) z odpowiednią informacją.

number = input("Give me your number")
number = int(number)
if number % 2 == 0:
    print(f"{number} is even number")
else:
    print(f"{number} is odd number")

If oznacza „jeżeli”, else to „w przeciwnym wypadku”. Mamy jeszcze konstrukcję elif, która oznacza „a jeżeli to nie to może tamto”.

Prosty przykład, mamy admina o nazwie „Jim”. Jeżeli poda swoje imię poprawnie, otrzyma odpowiedź „Hi Admin”. A jeżeli poda swoje imię małą literą to otrzyma „hi admin”. A jeżeli jego imię to coś zupełnie innego to dostanie informację, że dostęp zabroniony:

name = input("Whats your name?")
if name == "Jim":
    print("Hi Admin")
elif name == "jim":
    print("hi admin")
else:
    print("Youre not an admin! Go away!")

Warto zauważyć, że do przypisywania wartości do zmiennej używamy jednego znaku „=” zaś do porównywania „==” czyli dwóch znaków równości.

Porównywać możemy też czy coś jest większe, mniejsze, większe lub równe i tak dalej. Symbole użyte raczej nie będą zaskoczeniem:

age = input("How old are you?")
age = int(age)
if age >= 18:
    print("Youre adult")
elif age >= 13:
    print("Youre 13 or older")
else:
    print("Youre below 13.")

Tutaj sprawdzamy, czy ktoś ma minimum 18 lat, jeżeli nie, to czy ma minimum 13 lat (te liczby całkiem z palca wyjęte nie są, według pewnego prawa dot. ochrony danych małoletnich np. z platformy PythonAnywhere nie mogą korzystać osoby poniżej 13 roku życia).

Ciekawą rzeczą obecną w Pythonie jest natomiast porównywanie łańcuchowe. Pokażę na tym samym przykładzie i nie będę się rozwodzić gdzie akurat może nam się ono przydać, warto po prostu o nim wiedzieć i tyle:

age = input("How old are you?")
age = int(age)
if 17 < age >= 18:
    print("Youre adult")
elif 12 < age >= 13:
    print("Youre 13 or older")
else:
    print("Youre below 13.")

Pętla for, obiekt range i enumerate, indeksy

Pętla for pozwala nam „przelecieć” po wszystkich elementach. Łatwiej to pokazać na przykładzie. Tutaj pętla wypisuje każdy element napisu, czyli każdą literę:

msg ="abcdef"
for letter in msg:
    print(letter)

Możemy też w pętli postawić warunek i użyć słówka kluczowego „continue” które oznacza pominięcie danego elementu:

msg ="AaBbCcDdEeFf"
for letter in msg:
    if letter.islower():
        continue
    print(letter)

Ta pętla w momencie, w którym napotka literę zapisaną małą literą po prostu ją pominie. W innym przypadku wypisze literę. Pamiętajmy o dodatkowych wcięciach. Warto też zauważyć, że tutaj żadne „else” nie jest nam potrzebne, aczkolwiek dla czytelności możemy je zapisać, pamiętając o wcięciu oczywiście:

msg ="AaBbCcDdEeFf"
for letter in msg:
    if letter.islower():
        continue
    else:
        print(letter)

Możemy też „iterować” czyli przechodzić w pętli po elementach listy. Oto przykład:

nums = [1,2,3,4,5,6]
for num in nums:
    print(num)

Możemy zastosować logikę, która będzie nakazywać pomijać liczby nieparzyste.

nums = [1,2,3,4,5,6]
for num in nums:
    if num % 2 != 0:
        continue
    print(num)

Warto zwrócić uwagę, że znak „!=” oznacza „nie jest równe”. Zaś % 2 to „daj resztę z dzielenia przez 2”. Każda liczba, której reszta z dzielenia przez 2 nie jest równa 0 to liczba nieparzysta. Słówko continue oznacza „pomiń ten obrót pętli”.

Możemy także użyć takiego obiektu, jakim jest range. Oto liczby od 0 do 9:

for num in range(10):
    print(num)

range(10) daje nam tak jakby listę liczb od 0 do 9. Tak sobie twórcy Pythona wymyślili i nie ma co się w to zagłębiać dlaczego. Natomiast jeżeli chcemy liczby od 1 do 10 to musimy to podać w ten sposób:

for num in range(1, 11):
    print(num)

Pierwszy argument to liczba, od której zaczynamy, drugi to liczba, której już ma nie być, ta, gdzie mamy skończyć ale bez niej. Tak działa range. Można też użyć trzeciego argumentu, jakim jest krok czyli „o ile” skaczemy:

for num in range(1, 11, 2):
    print(num)

Dostaniemy 1,3,5,7 i 9. Jeżeli chcemy parzystych (zero też jest parzyste warto przypomnieć) to musimy zmodyfikować nieco ten nasz range:

for num in range(0, 11, 2):
    print(num)

I mamy 0,2,4,6,8,10. Jeżeli z jakichś powodów chcemy mieć liczby tylko parzyste większe od zera to zaczynamy od 2:

for num in range(2, 11, 2):
    print(num)

I mamy 2,4,6,8,10. Pierwszy i trzeci argument range jest akurat intuicyjny, to drugi może trochę w błąd wprowadzać, ponieważ drugi to jest dokąd, do którego elementu, ale już bez niego. Więc 11 oznacza „do 11 bez 11”. Albo „do 10 włącznie”. Dziwne i nie we wszystkich językach programowania tak to wygląda, natomiast tak to działa i nawet nie ma co przesadnie się zastanawiać dlaczego akurat tak. Po prostu przyjąć z dobrodziejstwem inwentarza tę wiedzę jak działa range i z niego korzystać.

Warto wspomnieć o czymś takim jak enumerate. Pozwala nam to obracać w pętli zarówno po indeksie jak i elemencie. Wygląda to tak:

for idx, letter in enumerate("Jim"):
    print(idx, letter)
#0 J
#1 i
#2 m

Obiekty takie jak lista albo napis posiadają swoje indeksy. Indeksowanie zaczyna się od 0 i idzie w górę. Oto przykład:

name = "John"
print(name[0]) #J
print(name[1]) #o 
print(name[2]) #h
print(name[3]) #n

Możemy też tworzyć pewne zakresy podobnie do obiektu range. Pamiętamy że indeksowanie zaczyna się od 0 zaś drugi argument to miejsce, gdzie chcemy skończyć. Jeżeli zatem chcemy z napisu „John” wyciągnąć „oh” to zaczynamy od 1 (indeks o) zaś kończymy na 3 (indeks n, którego już nie będzie):

name = "John"
print(name[1:3])
#oh

Dziwne, ale tak to działa. Możemy też np. zacząć od drugiej litery i polecieć „aż do samego końca”. Druga litera ma indeks 1 (pierwsza to 0) i tak to wygląda:

name = "John"
print(name[1:])
#ohn

Warto zauważyć, że niezależnie od długości tekstu, istnieją sposoby, aby „dobrać się” do jego ostatniej litery. Wiemy, że funkcja len zwraca nam długość tekstu, zaś tekst jest indeksowany od 0. Czyli tekst o długości 4 ma swoją ostatnią literę na indeksie 3. Można to wykorzystać:

name = "John"
print(name[len(name)-1])
#n

To tak, jakbyśmy zapisali:

name = "John"
print(name[3])
#n

Ale istnieje jeszcze inny sposób. Ostatnia litera zawsze jest dostępna pod indeksem „-1” (przedostatnia to „-2” i tak dalej). A zatem:

name = "John"
print(name[-1])
#n

Tak jak w range mieliśmy „krok” jako trzeci argument tak i tutaj mieć możemy:

name = "John"
print(name[0::2])
#Jh

Kod idzie od początku (0) do końca i „skacze” co 2 literę. Dziwne, w dodatku da się to uprościć:

name = "John"
print(name[::2])
#Jh

Ale jeszcze dziwniejsze jest to, że możemy wziąć napis od początku do końca i kazać mu „skakać” o -1 czyli podać napis od tyłu:

name = "John"
print(name[::-1])
#nhoJ

Z „dziwnych” notacji, na które możemy się natknąć mamy jeszcze „od początku do końca”, które pozwala nam przekopiować całą zawartość jednej listy do drugiej:

list1 = [1,2,3]
list2 = list1[:]
print(list1)
#[1, 2, 3]
print(list2)
#[1, 2, 3]

Oczywiście kopiować możemy jak chcemy, na przykład od drugiego elementu (o indeksie 1):

list1 = [1,2,3]
list2 = list1[1:]
print(list1)
#[1, 2, 3]
print(list2)
#[2, 3]

W następnym artykule poznamy dalsze podstawy Pythona. Na razie niech to wystarczy, ponieważ jest to pewien element wiedzy, którą warto sobie przyswoić.