Python

Podstawy programowania w języku Python

17 listopada 2015 20:00
Paweł Kucmus

Python jako język

Podstawy

Python większość działań związanych ze sprawdzeniem kodu wykonuje podczas działania tego kodu. Błędny lecz nigdy nie wykonany kod nie musi zawieść. Przykładem jest poniższy skrypt:

def run_pypila():
    return 'PyPila'

some_flag = True

if some_flag:
    print run_pypila()
else:
    print run_non_existing_function()

Mimo tego, że w naszym kodzie znajduje się funkcja, która nie jest nigdzie zadeklarowana kod wykona się bez przeszkód gdyż nigdy nie wejdzie do bloku else.

Praca z kodem

Najlepszym sposobem na szybkie sprawdzenie pewnych zachowań Pythona jest uruchomienie konsoli interpretera. Prosto z linii poleceń - terminala wywołujemy komendę:

$ python

Systemy na których pracujecie oparte są o dystrybucję Linux o nazwie Ubuntu, która zawiera domyślnie zainstalowaną wersję 2.7.6 interpretera.

I już widzimy symbol zachęty >>> Python:

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Od tej pory pracujecie z językiem (opuszczamy terminal kombinacją [ctrl] + [d]). Średnik na końcu linii nie jest wymagany - mało tego jest niepożądany.

Pierwszy program

Pliki źródłowe Pythona używają rozszerzenia .py. Dla przykładu: najprostszym sposobem na uruchomienie programu zapisanego w pliku hello.py jest wywołanie polecenia:

$ python hello.py

Plik hello.py zawiera następującą treść:

#!/usr/bin/python

import sys

def main():
    print 'Hello there', sys.argv[1]

if __name__ == '__main__':
    main()

Pierwsza linia to tgz. shebang wskazuje, którego interpretera (można mieć kilka w obrębie jednego systemu) użyć kiedy plik jest oznaczony jako wykonywalny jako skrypt - ale o tym później. Następna linia zawiera import umożliwia nam korzystanie z kody już napisanego w innych bibliotekach lub modułach. W tym przypadku importujemy sys który zawiera narzędzia pomagająca oddziaływać z interpreterem. Od def zaczyna się blok kodu definiujący funkcję main która nie przyjmuje żadnych parametrów. Wyświetla tekst Hello there oraz zawartość zmiennej sys.argv[1].

sys.argv to lista argumentów podanych przy uruchamianiu interpretera, np. wywołanie python hello.py Ewa spowoduje, że w sys.argv znajdziemy ['hello.py', 'Ewa'].

Ostatni blok to warunek sprawdzający czy nasz kod z modułu hello jest importowany czy wykonywany bezpośrednio, gdyż tylko w tym drugim przypadku chcemy aby funkcja main została wywołana.

Wywołajmy teraz nasz kod:

$ python hello.py Ewa
Hello there Ewa

Wcięcia

Python pozbawiony jest znaków rozpoczynających i kończących bloki kodu, wcięcia wyznaczają granice tych bloków - znacznie poprawia to czytelność kodu.

if something in a_list:
    do_something()

def some_function():
    for item in items:
        process_item(item)

class NewClass(object):
    pass

Należy zachowywać konsekwencję wcięć - nie używać raz tabulatorów, a raz spacji. Popularnym stylem jest używanie 4 spacji.

Zmienne

Python charakteryzuje się dynamicznym i silnym typowaniem.

Dynamika typowania

Typy zmiennych deklarowane są razem z deklaracją ich wartości - są dynamiczne.

>>> first_name = 'Paweł'
>>> type(first_name)
<type 'str'>

>>> import datetime
>>> date_of_birth = datetime.date(1989, 2, 20)
>>> type(date_of_birth)
<type 'datetime.date'>

>>> age = datetime.date.today().year - date_of_birth.year
>>> type(age)
<type 'int'>

>>> has_children = True
>>> type(has_children)
<type 'bool'>

>>> zmienna = 1
>>> type(zmienna)
<type 'int'>

>>> zmienna = 'String'
>>> type(zmienna)
<type 'str'>

Siła typowania

Python porównuje typy

>>> 1 != '1'
>>> type(1) != type('1')

String - Ciągi znaków

Deklaracja string'ów:

>>> s = 'Hello!'

Preferowane jest używanie apostrofów, ale znaki cudzysłowu też są dozwolone. Możemy dowolnie używać jednych w drugich lub używać znaku \.

>>> s1 = "I didn't do it"
>>> s2 = 'He said: "Feed the dog."'
>>> s3 = 'I didn\'t do it'


Jak każdy obiekt, string'i też można wyświetlać za pomocą instrukcji print. Mamy dostęp to każdego znaku w string'u poprzez indeks.

Dostęp przez indeks odbywa się przy pomocy nawiasów kwadratowych [ i ]. Liczymy znaki od zera np. 'Ewa'[0] zwróci 'E'. Możemy liczyć od tyłu 'Ewa'[-1] wyniesie 'a'. Dostępne są również zakresy 'PyPila'[0:2] zwróci od "zerowego" znaku do znaku przed drugim czyli 'Py'.

>>> s = 'zmienna'
>>> print s
zmienna

>>> s = 'Jestem robotem' >>> print s[0] J >>> print s[-1] m >>> print s[2:5] ste >>> print s[:-1] Jestem robote


Zdarza się, że np. dla czytelności powinniśmy "złamać" długiego string'a - możemy to zrobić na kilka sposobów:

>>> s = (
... 'Długi tekst '
... 'bardzo długi'
... )
>>> print s
Długi tekstbardzo długi

>>> s = """Długi tekst ... bardzo długi""" >>> print s Długi tekst bardzo długi


Zmienne w stringach:

>>> age = 25
>>> name = 'Paweł'
>>> text = '{} is {} years old'.format(name, age)
>>> print text
Paweł is 25 years old

>>> age = 25 >>> name = 'Paweł' >>> text = '{name} is {age} years old'.format( ... age=age, name=name ... ) >>> print text Paweł is 25 years old

Struktury danych

Listy

Listę deklarujemy za pomocą nawiasów kwadratowych [, ]. Elementami listy mogą być wszelakie typy danych (w tym same listy). Poniżej przykład deklaracji listy składającej się z ośmiu elementów typu integer.

>>> moje_numery = [4, 6, 3, 5, 6, 8, 1, 2]

Należy pamiętać, że zmienna list jest zarezerwowana i nie powinna być nadpisywana.

Listę można modyfikować np dodając wartość do jej końca:

>>> lista = [1, 2, 3]
>>> lista.append(4)
>>> print lista
[1, 2, 3, 4]

lub w dowolne jej miejsce (wybierając dokładne miejsce poprzez indeks):

>>> lista = [1, 2, 3]
>>> lista.insert(2, 'asd')
>>> print lista
[1, 2, 'asd', 3]

Wróćmy na chwilę do indeksów gdyż to pojęcie, które będzie się często pojawiało. Chcąc wybierać daną "poprzez indeks" stosujemy nawiasy kwadratowe przy zmiennej z zadeklarowaną strukturą. Indeks liczymy od zera więc aby wyciągnąć pierwszy element z listy używamy moja_lista[0]. Można też liczyć od końca używając liczb ujemnych lub wybierać wycinki z listy: Przykłady:

>>> lista = [1, 2, 3, 4, 5, 6, 7, 8]
>>> print lista[1]
2
>>> print lista[-1]
8
>>> print lista[0:4]
[1, 2, 3, 4]
>>> print lista[6:]
[7, 8]
>>> print lista[-2:]
[7, 8]

Poczytaj o range i xrange, sortowaniu list i różnicy między list.sort a sorted.

Tupla

W skrócie tupla to taka lista, której nie można edytować. Brak możliwości edycji jest czasami ważny, np. jeśli pracujemy nad wartością, która nigdy podczas pracy aplikacji nie powinna być zmieniona. Funkcje zwracające kilka zmiennych zwracają je w tupli. Tuplą posługujemy się tak jak listą (pamiętając o niemożności edycji).

>>> krotka = (1,2,3)
>>> print krotka
(1, 2, 3)
>>> print krotka[-1]
3

Ważne jest to, że kiedy tworzymy jednoelementową tuplę, musimy zapisać ją z przecinkiem na końcu:

>>> mala_krotka = (1,)
(1,)

Słowniki

Słownik to taki ciąg danych z kluczami. Różni się od list i tupli zapisem i tym jak się z nim pracuje. Deklaracja słownika:

>>> rodzina = {'mama': 'Ula', 'tata': 'Jacek', 'brat': 'Woodie'}
>>> print rodzina['tata']
Jacek

Do danych znajdujących się w słowniku dostajemy po kluczu - zapis jest jaki sam jak w przypadku indeksów.

>>> rodzina = {'mama': 'Ula', 'tata': 'Jacek', 'brat': 'Woodie'}
>>> rodzina['zona'] = 'Ewa'
>>> rodzina['corka'] = 'Lenka'
>>> print rodzina
{'mama': 'Ula', 'zona': 'Ewa', 'tata': 'Jacek', 'corka': 'Lenka', 'brat': 'Woodie'}

Należy uważać na przypadki, w których szukany klucz nie istnieje:

>>> rodzina = {
    'mama': 'Ula',
    'zona': 'Ewa',
    'tata': 'Jacek',
    'corka': 'Lenka',
    'brat': 'Woodie'
}
>>> print rodzina['siostra']
KeyError: 'siostra'
>>> print rodzina.get('siostra')
None
>>> print rodzina.get('syn', 'Jeszcze nie wybrałeś imienia...')

Instrukcje warunkowe

Po raz pierwszy wyznaczymy blok kodu, więc warto tu przypomnieć o czymś ważnym:

>>> from __future__ import braces
SyntaxError: not a chance

Twórcy Pythona dają wyraźnie do zrozumienia, że nawiasy { }do wyznaczania bloków kodu nigdy nie wystąpią w tym języku. Panowanie nad wcięciami jest bardzo ważne.

Posługując się zmiennymi typu bool czyli True i False wykonajmy naszego pierwszego if'a.

>>> if True and False:
...     print 'To nie powinno się wykonać'
... elif True or False:
...     print 'To się wykona'
... else:
...     print 'To też się nie wykona'
...
To się wykona

Napisz prosty skrypt na sprawdzanie wieku w sklepie przy próbie zakupu alkoholu:

>>> age = 25
>>> under_age = age < 18
>>> beard = True
>>> wrinkles = False
>>> looks_old = beard and wrinkles

>>> if not looks_old:
...     print 'Poproszę dowód osobisty...'
...     if under_age:
...         print 'Nie sprzedam Ci alkoholu'
...     else:
...         print 'Ok, oddaję dowód i podaję alkohol.'
... else:
...     print 'Proszę, bardzo.'
...
Poproszę dowód osobisty...
Ok, oddaję dowód i podaję alkohol.

Pętle

While

Podstawowa pętla, która wykonuje się dopóki dostarczona jej zmienna będzie równa True.

>>> index = 0
>>> while index < 5:
...     print index
...     index = index + 1
0
1
2
3
4
>>> index = 0
>>> while index < 5:
...     if index % 2 == 0:
...         print index
...     index = index + 1
0
2
4

For

Pętla iterująca po zmiennej która jest iteratorem. Temat jest raczej złożony ale można go uprościć w następujący sposób: iteratorem jest np. lista gdyż możemy przeiterować kolejno po każdym jej elemencie, podobnie string - można iterować po każdej jego literze.

>>> for index in [0, 1, 2, 3, 4, 5]:
...     print index
0
1
2
3
4
5

>>> for char in 'Ewa':
...     print char
E
w
a

>>> for kto, imie in rodzina.iteritems():
...     print '{} to mój {}'.format(imie, kto)
Ula to mój mama
Jacek to mój tata
Woodie to mój brat

>>> for kto, imie in rodzina.iteritems():
...     zwrot = 'moja' if imie[-1] == 'a' else 'mój'
...     print '{} to {} {}'.format(imie, zwrot, kto)
Ula to moja mama
Jacek to mój tata
Woodie to mój brat

List comprehension

W Pythonie istnieje możliwość skróconego zapisu pętli for. Możemy dzięki niemu tworzyć listy, tuple czy słowniki z możliwością wykonywania kodu na każdym z przetwarzanych elementów.

>>> print range(0,9)
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> print [i * 2 for i in range(0,9)]
[0, 2, 4, 6, 8, 10, 12, 14, 16]
>>> print [i for i in [1, 5, 9, 14, 66] if i % 2 == 0]
[14, 66]

Comments