4. Więcej narzędzi kontroli przepływu
*************************************

Besides the "while" statement just introduced, Python knows the usual
control flow statements known from other languages, with some twists.


4.1. "if" Statements
====================

Prawdopodobnie najbardziej znanym typem instrukcji jest instrukcja
"if". Na przykład:

   >>> x = int(input("Please enter an integer: "))
   Please enter an integer: 42
   >>> if x < 0:
   ...     x = 0
   ...     print('Negative changed to zero')
   ... elif x == 0:
   ...     print('Zero')
   ... elif x == 1:
   ...     print('Single')
   ... else:
   ...     print('More')
   ...
   More

There can be zero or more "elif" parts, and the "else" part is
optional.  The keyword '"elif"' is short for 'else if', and is useful
to avoid excessive indentation.  An  "if" ... "elif" ... "elif" ...
sequence is a substitute for the "switch" or "case" statements found
in other languages.


4.2. "for" Statements
=====================

The "for" statement in Python differs a bit from what you may be used
to in C or Pascal.  Rather than always iterating over an arithmetic
progression of numbers (like in Pascal), or giving the user the
ability to define both the iteration step and halting condition (as
C), Python's "for" statement iterates over the items of any sequence
(a list or a string), in the order that they appear in the sequence.
For example (no pun intended):

   >>> # Measure some strings:
   ... words = ['cat', 'window', 'defenestrate']
   >>> for w in words:
   ...     print(w, len(w))
   ...
   cat 3
   window 6
   defenestrate 12

If you need to modify the sequence you are iterating over while inside
the loop (for example to duplicate selected items), it is recommended
that you first make a copy.  Iterating over a sequence does not
implicitly make a copy.  The slice notation makes this especially
convenient:

   >>> for w in words[:]:  # Loop over a slice copy of the entire list.
   ...     if len(w) > 6:
   ...         words.insert(0, w)
   ...
   >>> words
   ['defenestrate', 'cat', 'window', 'defenestrate']

With "for w in words:", the example would attempt to create an
infinite list, inserting "defenestrate" over and over again.


4.3. Funkcja "range()"
======================

Jeśli potrzebujesz iterować po sekwencji liczb, przydatna jest
wbudowana funkcja "range()". Generuje ciągi arytmetyczne:

   >>> for i in range(5):
   ...     print(i)
   ...
   0
   1
   2
   3
   4

Podany punkt końcowy nigdy nie jest częścią generowanej sekwencji;
"range(10)" generuje 10 wartości, poprawne indeksy dla elementów
sekwencji o długości 10. Możliwe jest zacząć zakres od innej liczby
lub podać inne zwiększenie (nawet ujemne; czasem jest to nazywane
„krokiem”):

   range(5, 10)
      5, 6, 7, 8, 9

   range(0, 10, 3)
      0, 3, 6, 9

   range(-10, -100, -30)
     -10, -40, -70

By przeiterować po indeksach sekwencji możesz połączyć "range()" i
"len()" w następujący sposób:

   >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
   >>> for i in range(len(a)):
   ...     print(i, a[i])
   ...
   0 Mary
   1 had
   2 a
   3 little
   4 lamb

Jednak w większości takich przypadków wygodnie jest użyć funkcji
"enumerate()", patrz Techniki pętli.

Dzieje się dziwna rzecz jeśli po prostu wydrukujesz zakres:

   >>> print(range(10))
   range(0, 10)

Pod wieloma względami obiekt zwracany przez "range()" zachowuje się,
jakby był listą, ale w rzeczywistości nią nie jest. Jest obiektem,
który zwraca kolejne elementy żądanej sekwencji w trakcie twojego
iterowania po nim, lecz naprawdę nie tworzy listy, tak więc oszczędza
miejsce w pamięci komputera.

We say such an object is *iterable*, that is, suitable as a target for
functions and constructs that expect something from which they can
obtain successive items until the supply is exhausted. We have seen
that the "for" statement is such an *iterator*. The function "list()"
is another; it creates lists from iterables:

   >>> list(range(5))
   [0, 1, 2, 3, 4]

Later we will see more functions that return iterables and take
iterables as argument.


4.4. "break" and "continue" Statements, and "else" Clauses on Loops
===================================================================

Instrukcja "break", tak jak w C, wychodzi z najbardziej wewnętrznej
pętli "for" lub "while" zawierającej tę instrukcję.

Loop statements may have an "else" clause; it is executed when the
loop terminates through exhaustion of the list (with "for") or when
the condition becomes false (with "while"), but not when the loop is
terminated by a "break" statement.  This is exemplified by the
following loop, which searches for prime numbers:

   >>> for n in range(2, 10):
   ...     for x in range(2, n):
   ...         if n % x == 0:
   ...             print(n, 'equals', x, '*', n//x)
   ...             break
   ...     else:
   ...         # loop fell through without finding a factor
   ...         print(n, 'is a prime number')
   ...
   2 is a prime number
   3 is a prime number
   4 equals 2 * 2
   5 is a prime number
   6 equals 2 * 3
   7 is a prime number
   8 equals 2 * 4
   9 equals 3 * 3

(Tak, to poprawny kod. Przyjrzyj się: klauzula "else" należy do pętli
"for", **nie** do instrukcji "if".)

When used with a loop, the "else" clause has more in common with the
"else" clause of a "try" statement than it does that of "if"
statements: a "try" statement's "else" clause runs when no exception
occurs, and a loop's "else" clause runs when no "break" occurs. For
more on the "try" statement and exceptions, see Obsługa wyjątków.

Instrukcja "continue", również pożyczona z C, kontynuuje następną
iterację pętli:

   >>> for num in range(2, 10):
   ...     if num % 2 == 0:
   ...         print("Found an even number", num)
   ...         continue
   ...     print("Found a number", num)
   Found an even number 2
   Found a number 3
   Found an even number 4
   Found a number 5
   Found an even number 6
   Found a number 7
   Found an even number 8
   Found a number 9


4.5. "pass" Statements
======================

Instrukcja "pass" nie robi nic. Można jej użyć, gdy składnia wymaga
instrukcji a program nie wymaga działania. Na przykład:

   >>> while True:
   ...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
   ...

Często jej się używa do tworzenia minimalnych klas:

   >>> class MyEmptyClass:
   ...     pass
   ...

Another place "pass" can be used is as a place-holder for a function
or conditional body when you are working on new code, allowing you to
keep thinking at a more abstract level.  The "pass" is silently
ignored:

   >>> def initlog(*args):
   ...     pass   # Remember to implement this!
   ...


4.6. Definiowanie funkcji
=========================

Możemy stworzyć funkcję, która wypisuje ciąg Fibonacciego do wskazanej
granicy:

   >>> def fib(n):    # write Fibonacci series up to n
   ...     """Print a Fibonacci series up to n."""
   ...     a, b = 0, 1
   ...     while a < n:
   ...         print(a, end=' ')
   ...         a, b = b, a+b
   ...     print()
   ...
   >>> # Now call the function we just defined:
   ... fib(2000)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Słowo kluczowe "def" oznacza *definicję* funkcji. Po nim musi
następować nazwa funkcji oraz lista formalnych parametrów otoczona
nawiasami. Instrukcje, które stanowią ciało funkcji zaczynają się w
następnej linii i muszą być wcięte.

Opcjonalnie, pierwszy wiersz ciała funkcji może być gołym napisem
(literałem): jest to tzw. napis dokumentujący lub inaczej *docstring*.
(Więcej o docstringach znajdziesz w sekcji Napisy dokumentujące.)
Istnieją pewne narzędzia, które używają docstringów do automatycznego
tworzenia drukowanej lub dostępnej online dokumentacji albo pozwalają
użytkownikowi na interaktywne przeglądanie kodu. Dobrym zwyczajem jest
pisane napisów dokumentacyjnych w czasie pisania programu: spróbuj się
do tego przyzwyczaić.

The *execution* of a function introduces a new symbol table used for
the local variables of the function.  More precisely, all variable
assignments in a function store the value in the local symbol table;
whereas variable references first look in the local symbol table, then
in the local symbol tables of enclosing functions, then in the global
symbol table, and finally in the table of built-in names. Thus, global
variables cannot be directly assigned a value within a function
(unless named in a "global" statement), although they may be
referenced.

The actual parameters (arguments) to a function call are introduced in
the local symbol table of the called function when it is called; thus,
arguments are passed using *call by value* (where the *value* is
always an object *reference*, not the value of the object). [1] When a
function calls another function, a new local symbol table is created
for that call.

A function definition introduces the function name in the current
symbol table. The value of the function name has a type that is
recognized by the interpreter as a user-defined function.  This value
can be assigned to another name which can then also be used as a
function.  This serves as a general renaming mechanism:

   >>> fib
   <function fib at 10042ed0>
   >>> f = fib
   >>> f(100)
   0 1 1 2 3 5 8 13 21 34 55 89

Przychodząc z innych języków, mógłbyś oponować, że "fib" nie jest
funkcją, ale procedurą, jako że nie zwraca wartości. Tak naprawdę
nawet funkcje bez instrukcji "return" zwracają wartość, chociaż dość
nudną. Tę wartość nazywamy "None" (to wbudowana nazwa). Wypisywanie
wartości "None" jest normalnie pomijane przez interpreter, jeśli
miałaby to jedyna wypisywana wartość. Możesz ją zobaczyć, jeśli bardzo
chcesz, używając "print()":

   >>> fib(0)
   >>> print(fib(0))
   None

Prosto można napisać funkcję, która zwraca listę numerów ciągu
Fibonnaciego zamiast go wyświetlać:

   >>> def fib2(n):  # return Fibonacci series up to n
   ...     """Return a list containing the Fibonacci series up to n."""
   ...     result = []
   ...     a, b = 0, 1
   ...     while a < n:
   ...         result.append(a)    # see below
   ...         a, b = b, a+b
   ...     return result
   ...
   >>> f100 = fib2(100)    # call it
   >>> f100                # write the result
   [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Ten przykład, jak zazwyczaj, prezentuje nowe cechy Pythona:

* The "return" statement returns with a value from a function.
  "return" without an expression argument returns "None". Falling off
  the end of a function also returns "None".

* Instrukcja "result.append(a)" wywołuje *metodę* listy obiektów
  "result". Metoda to funkcja, która „należy” do obiektu i jest
  nazwana "obj.methodname", gdzie "obj" jest jakimś obiektem (może też
  być wyrażeniem) a "methodname" jest nazwą metody, które jest
  zdefiniowana przez typ obiektu. Różne typy definiują różne metody.
  Metody różnych typów mogą mieć te same nazwy bez powodowania
  dwuznaczności. (Da się definiować własne typy obiektów i metody,
  używając *klas*, patrz Klasy.) Metoda "append()" pokazana w
  przykładzie jest zdefiniowana dla listy obiektów; dodaje nowy
  element na końcu listy. W tym przykładzie jest równoważna "result =
  result + [a]", ale bardziej wydajna.


4.7. Więcej o definiowaniu funkcji
==================================

Można też definiować funkcje ze zmienną liczbą argumentów. Są trzy
sposoby, które można łączyć.


4.7.1. Domyślne wartości argumentów
-----------------------------------

Najbardziej przydatnym sposobem jest podanie domyślnej wartości dla
jednego lub więcej argumentów. Tworzy to funkcję, która może zostać
wywołana z mniejszą liczbą argumentów, niż jest podane w jej
definicji. Na przykład:

   def ask_ok(prompt, retries=4, reminder='Please try again!'):
       while True:
           ok = input(prompt)
           if ok in ('y', 'ye', 'yes'):
               return True
           if ok in ('n', 'no', 'nop', 'nope'):
               return False
           retries = retries - 1
           if retries < 0:
               raise ValueError('invalid user response')
           print(reminder)

Tę funkcję można wywołać na kilka sposobów:

* podając tylko wymagany argument: "ask_ok('Do you really want to
  quit?')"

* podając jeden z opcjonalnych argumentów: "ask_ok('OK to overwrite
  the file?', 2)"

* lub podając wszystkie argumenty: "ask_ok('OK to overwrite file?', 2,
  'Come on, only yes or no!')"

Ten przykład wprowadza słowo kluczowe "in". Sprawdza ono, czy
sekwencja zawiera szczególną wartość.

Wartości domyślne są ewaluowane w momencie definiowania funkcji w
scopie *defining*, więc

   i = 5

   def f(arg=i):
       print(arg)

   i = 6
   f()

wyświetli "5".

**Ważna uwaga**: Wartość domyślna jest wyliczana tylko raz. Ma to
znaczenie, gdy domyślna wartość jest obiektem mutowalnym takim jak
lista, słownik lub instancje większości klas. Na przykład następująca
funkcja akumuluje argumenty przekazane do niej w kolejnych
wywołaniach:

   def f(a, L=[]):
       L.append(a)
       return L

   print(f(1))
   print(f(2))
   print(f(3))

To wyświetli

   [1]
   [1, 2]
   [1, 2, 3]

Jeśli nie chcesz, żeby domyślna wartość była współdzielona pomiędzy
kolejnymi wywołaniami, możesz napisać funkcję w ten sposób:

   def f(a, L=None):
       if L is None:
           L = []
       L.append(a)
       return L


4.7.2. Argumenty nazwane
------------------------

Funkcje mogą być również wywoływane przy użyciu *argumentów nazwanych*
w formie "kwarg=value". Na przykład poniższa funkcja:

   def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
       print("-- This parrot wouldn't", action, end=' ')
       print("if you put", voltage, "volts through it.")
       print("-- Lovely plumage, the", type)
       print("-- It's", state, "!")

akceptuje jeden wymagany argument ("voltage") i trzy opcjonalne
argumenty ("state", "action" i "type"). Funkcja może być wywołana w
dowolny z poniższych sposobów:

   parrot(1000)                                          # 1 positional argument
   parrot(voltage=1000)                                  # 1 keyword argument
   parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
   parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
   parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
   parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

ale wszystkie poniższe wywołania byłyby niepoprawne:

   parrot()                     # required argument missing
   parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
   parrot(110, voltage=220)     # duplicate value for the same argument
   parrot(actor='John Cleese')  # unknown keyword argument

W wywołaniu funkcji argumenty nazwane muszą znajdować się za
argumentami pozycyjnymi. Wszystkie przekazane argumenty nazwane muszą
pasować do jednego argumentu akceptowanego przez funkcję (na przykład
"actor" nie jest poprawnym argumentem dla funkcji "parrot") a ich
kolejność nie ma znaczenia. Dotyczy to również nie-opcjonalnych
argumentów (na przykład "parrot(voltage=1000)" też jest poprawne).
Żaden argument nie może otrzymać wartości więcej niż raz. Tutaj jest
przykład, który się nie powiedzie z powodu tego ograniczenia:

   >>> def function(a):
   ...     pass
   ...
   >>> function(0, a=0)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: function() got multiple values for keyword argument 'a'

When a final formal parameter of the form "**name" is present, it
receives a dictionary (see Mapping Types --- dict) containing all
keyword arguments except for those corresponding to a formal
parameter.  This may be combined with a formal parameter of the form
"*name" (described in the next subsection) which receives a tuple
containing the positional arguments beyond the formal parameter list.
("*name" must occur before "**name".) For example, if we define a
function like this:

   def cheeseshop(kind, *arguments, **keywords):
       print("-- Do you have any", kind, "?")
       print("-- I'm sorry, we're all out of", kind)
       for arg in arguments:
           print(arg)
       print("-" * 40)
       for kw in keywords:
           print(kw, ":", keywords[kw])

Można ją wywołać w ten sposób:

   cheeseshop("Limburger", "It's very runny, sir.",
              "It's really very, VERY runny, sir.",
              shopkeeper="Michael Palin",
              client="John Cleese",
              sketch="Cheese Shop Sketch")

i oczywiście wyświetli się nam:

   -- Do you have any Limburger ?
   -- I'm sorry, we're all out of Limburger
   It's very runny, sir.
   It's really very, VERY runny, sir.
   ----------------------------------------
   shopkeeper : Michael Palin
   client : John Cleese
   sketch : Cheese Shop Sketch

Zwróć uwagę, że kolejność w jakim argumenty są wyświetlane dokładnie
odpowiada kolejności w jakim zostały one podane w wywołaniu funkcji.


4.7.3. Arbitralne listy argumentów
----------------------------------

Najmniej często wykorzystywaną opcją jest specyfikowanie, że funkcja
może być wywoływana z arbitralną liczbą argumentów. Takie argumenty
zostaną opakowane w krotkę (zobacz Krotki i sekwencje). Przed zmienną
liczbą argumentów, można wymusić jeden lub więcej argumentów.

   def write_multiple_items(file, separator, *args):
       file.write(separator.join(args))

Zazwyczaj takie "wariadyczne" argumenty będą na koniec listy
formalnych parametrów, ponieważ zbierają one wszystkie pozostałe
argumenty przekazane funkcji. Każdy formalny argument po "*args" może
być  'tylko-kluczowy', to znaczy da się go wprowadzić tylko poprzez
słowo kluczowe a nie przez pozycję.

   >>> def concat(*args, sep="/"):
   ...     return sep.join(args)
   ...
   >>> concat("earth", "mars", "venus")
   'earth/mars/venus'
   >>> concat("earth", "mars", "venus", sep=".")
   'earth.mars.venus'


4.7.4. Rozpakowywanie listy argumentów
--------------------------------------

Odwrotna sytuacja wystąpi, gdy argumenty już są listą albo krotką a
muszą być rozpakowane gdyż funkcja wymaga argumentów przekazanych
pozycyjnie, jeden po drugim .  Dla przykładu, wbudowana funkcja
"range()" oczekuje oddzielnych argumentów *start* oraz *stop*. Jeśli
nie są dostępne oddzielnie, wywołaj funkcją z operatorem  "*" aby
wypakować argumenty z listy lub krotki:

   >>> list(range(3, 6))            # normal call with separate arguments
   [3, 4, 5]
   >>> args = [3, 6]
   >>> list(range(*args))            # call with arguments unpacked from a list
   [3, 4, 5]

W podobny sposób, słowniki moga dostarczać argumentów kluczowych
poprzez operator "**":

   >>> def parrot(voltage, state='a stiff', action='voom'):
   ...     print("-- This parrot wouldn't", action, end=' ')
   ...     print("if you put", voltage, "volts through it.", end=' ')
   ...     print("E's", state, "!")
   ...
   >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
   >>> parrot(**d)
   -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !


4.7.5. Wyrażenia Lambda
-----------------------

Niewielkie anonimowe funkcje mogą byś tworzone z wykorzystaniem słowa
kluczowego  "lambda". Wykorzystując tą notację: "lambda a, b: a+b"
powstanie funkcja sumująca podane argumenty. Funkcje lambda mogą być
wykorzystywane zawsze wtedy gdy potrzebne są objekty funkcji. Są
synaktycznie ograniczone do jednego wyrażenia. Semantycznie, jest to
tylko lukier składniowy normalnej definicji funkcji. Podobnie jak
funkcje zagnieżdżone funkcje lambda mogą odwoływać się do zmiennych z
otaczającego zakresu

   >>> def make_incrementor(n):
   ...     return lambda x: x + n
   ...
   >>> f = make_incrementor(42)
   >>> f(0)
   42
   >>> f(1)
   43

Powyższy przykład wykorzystuje ekspresję lambda aby zwrócić funkcję.
Inne wykorzystanie to przekazanie małej funkcji jako argumentu:

   >>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
   >>> pairs.sort(key=lambda pair: pair[1])
   >>> pairs
   [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]


4.7.6. Napisy dokumentujące
---------------------------

Oto kilka konwencji dotyczących zawartości i formatowania ciągów
dokumentacji.

Pierwsza linijka powinna zawierać zwięzłe streszczenie sensu jaki stoi
za obiektem. Nie powinna wprost zawierać nazwy obiektu ani typu, gdyż
te są dostępne w inny sposób (chyba, że nazwa jest czasownikiem
opisujęcym działanie funkcji). Ta linijka powinna zaczynać się z dużej
litery i kończyć kropką.

Jeśli w docstringu jest więcej niż jedna linijka, druga linijka
powinna być pusta, aby rozdzielić ją od reszty opisu. Następne linijki
powinny zawierać konwencje nazwenicze, efekty uboczne itd.

Parser Pythona nie usuwa wcięć z literału stringu wielolinijkowego,
więc jeśli to jest pożądane, to narzędzia obrabiające dokumentację
powinny usuwać wcięcia. Robi się to, wykorzystując następujące.
Pierwsza nie-pusta linijka *po* pierwszej określa jak dużo wcięcia
jest w całym docstringu. (Nie można do tego wykorzystać pierwszej
linijki, ponieważ ta zazwyczaj przylega do cudzysłowów, więc sposób
wcięcia jest nieoczywisty.) "Ilość wcięcia" z tej linijki jest
następnie usuwana z tej i wszystkich następnych linijek. W kolejnych
linijkach nie powinno być mniej wcięć ale jeśli tak będzie to całość
wcięcia powinna być usunięta. Ilość wcięcia powinna być usuwana po
zamianie tabulatorów na spacje (zazwyczaj na 8 spacji).

Poniżej przykład wielolinijkowego docstringu:

   >>> def my_function():
   ...     """Do nothing, but document it.
   ...
   ...     No, really, it doesn't do anything.
   ...     """
   ...     pass
   ...
   >>> print(my_function.__doc__)
   Do nothing, but document it.

       No, really, it doesn't do anything.


4.7.7. Adnotacje funkcji
------------------------

Adnotacje funkcji to całkowicie opcjonalne metadane dające informacje
o funkcjach zdefiniowanych przez użytkowników (zobacz **PEP 3107**
oraz **PEP 484** aby uzyskać więcej informacji).

Annotations are stored in the "__annotations__" attribute of the
function as a dictionary and have no effect on any other part of the
function.  Parameter annotations are defined by a colon after the
parameter name, followed by an expression evaluating to the value of
the annotation.  Return annotations are defined by a literal "->",
followed by an expression, between the parameter list and the colon
denoting the end of the "def" statement.  The following example has a
positional argument, a keyword argument, and the return value
annotated:

   >>> def f(ham: str, eggs: str = 'eggs') -> str:
   ...     print("Annotations:", f.__annotations__)
   ...     print("Arguments:", ham, eggs)
   ...     return ham + ' and ' + eggs
   ...
   >>> f('spam')
   Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
   Arguments: spam eggs
   'spam and eggs'


4.8. Intermezzo: Styl kodowania
===============================

Teraz, kiedy już jesteś gotowa aby pisać dłuższe, bardziej złożone
Pythonowe dzieła, dobrze żebyśmy porozmawiali o *stylu kodowania*.
Większość języków może być pisana (a mówiąc precyzyjniej,
*formatowana*) w różnym stylu; bardziej lub mniej czytelnym. Zawsze
dobrze jest dążyć, aby Twój kod był łatwy do czytania przez innych a w
tym bardzo pomaga   stosowanie fajnego stylu kodowania.

Dla Pythona **PEP 8** stał się wzorcem stylu, którego trzyma się
większość projektów; szerzy czytelny i miły dla oka styl kodowania. W
którymś momencie, powinien go przeczytać każdy developer Pythona,
poniżej przedstawiliśmy jego najistotniejsze elementy:

* Jako wcięcie, wykorzystuj cztery spacje, nie tabulator.

  Cztery spacje są dobrym kompromisem pomiędzy płytkim wcięciem
  (pozwala na więcej kroków zagnieżdżania ) a głębokim wcięciem (jest
  łatwiejsze do przeczytania). Tabulatorów najlepiej nie używać,
  wprowadzają zamiesznie.

* Zawijaj linie tak, aby nie ich długość nie przekraczała 79 znaków.

  To pomoże użytkownikom z małymi wyświetlaczami a na większych
  ekranach pozwoli mieć kilka plików obok siebie na ekranie.

* Wstawiaj puste linie aby oddzielić od siebie funkcje, klasy lub
  większe bloki kodu wewnątrz funkcji.

* Jeśli jest to możliwe, wstawiaj komentarze na oddzielnej lini.

* Wykorzystuj docstringi

* Korzystaj ze spacji naokoło operatorów oraz za przecinkami, ale nie
  przy nawiasach:   "a = f(1, 2) + g(3, 4)".

* Name your classes and functions consistently; the convention is to
  use "CamelCase" for classes and "lower_case_with_underscores" for
  functions and methods.  Always use "self" as the name for the first
  method argument (see A First Look at Classes for more on classes and
  methods).

* Nie wykorzystuj ambitnych zestawów znaków (encoding) jeśli Twój kod
  będzie wykorzystywany międzynarodowo. Najepiej trzymać się
  domyślnych w Pythonie: UTF-8 lub nawet ASCII.

* Podobnie, nie korzystaj ze znaków innych niż ASCII jako
  identyfikatorów, jeśli jest chociaż szansa, że osoby mówiące innym
  językiem będą czytać lub rozwijać Twój kod.

-[ Przypisy ]-

[1] Tak właściwie, *wywołanie przez referencję obiektu* byłoby lepszym
    opisem, jako że jeśli mutowalny obiekt jest przekazany, wszystkie
    zmiany które wywoływany robi (elementy wstawiane na listę) będą
    widziane przez wywołującego.
