summaryrefslogtreecommitdiffhomepage
path: root/cs-cz/python3.html.markdown
blob: e842321b97d9c01a8fb12e9d7dd75bff2f21eb84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
---
language: python3
contributors:
    - ["Louie Dinh", "http://pythonpracticeprojects.com"]
    - ["Steven Basart", "http://github.com/xksteven"]
    - ["Andre Polykanine", "https://github.com/Oire"]
    - ["Tomáš Bedřich", "http://tbedrich.cz"]
translators:
    - ["Tomáš Bedřich", "http://tbedrich.cz"]
filename: learnpython3.py
---

Python byl vytvořen Guidem Van Rossum v raných 90. letech. Nyní je jedním z nejpopulárnějších jazyků.
Zamiloval jsem si Python pro jeho syntaktickou čistotu - je to vlastně spustitelný pseudokód.

Vaše zpětná vazba je vítána! Můžete mě zastihnout na [@louiedinh](http://twitter.com/louiedinh) nebo louiedinh [at] [email od googlu] anglicky,
autora českého překladu pak na [@tbedrich](http://twitter.com/tbedrich) nebo ja [at] tbedrich.cz

Poznámka: Tento článek je zaměřen na Python 3. Zde se můžete [naučit starší Python 2.7](http://learnxinyminutes.com/docs/python/).

```python

# Jednořádkový komentář začíná křížkem

""" Víceřádkové komentáře používají tři uvozovky nebo apostrofy
    a jsou často využívány jako dokumentační komentáře k metodám
"""

####################################################
## 1. Primitivní datové typy a operátory
####################################################

# Čísla
3  # => 3

# Aritmetické operace se chovají běžným způsobem
1 + 1   # =>  2
8 - 1   # =>  7
10 * 2  # => 20

# Až na dělení, které vrací desetinné číslo
35 / 5  # => 7.0

# Při celočíselném dělení je desetinná část oříznuta (pro kladná i záporná čísla)
5 // 3       # => 1
5.0 // 3.0   # => 1.0  #  celočíselně dělit lze i desetinným číslem
-5 // 3      # => -2
-5.0 // 3.0  # => -2.0

# Pokud použiteje desetinné číslo, výsledek je jím také
3 * 2.0  # => 6.0

# Modulo
7 % 3  # => 1

# Mocnění (x na y-tou)
2**4  # => 16

# Pro vynucení priority použijte závorky
(1 + 3) * 2  # => 8

# Logické hodnoty
True
False

# Negace se provádí pomocí not
not True   # => False
not False  # => True

# Logické operátory
# U operátorů záleží na velikosti písmen
True and False  # => False
False or True   # => True

# Používání logických operátorů s čísly
0 and 2     # => 0
-5 or 0     # => -5
0 == False  # => True
2 == True   # => False
1 == True   # => True

# Rovnost je ==
1 == 1  # => True
2 == 1  # => False

# Nerovnost je !=
1 != 1  # => False
2 != 1  # => True

# Další porovnání
1 < 10  # => True
1 > 10  # => False
2 <= 2  # => True
2 >= 2  # => True

# Porovnání se dají řetězit!
1 < 2 < 3  # => True
2 < 3 < 2  # => False


# Řetězce používají " nebo ' a mohou obsahovat UTF8 znaky
"Toto je řetězec."
'Toto je také řetězec.'

# Řetězce se také dají sčítat, ale nepoužívejte to
"Hello " + "world!"  # => "Hello world!"
# Dají se spojovat i bez '+'
"Hello " "world!"  # => "Hello world!"

# Řetězec lze považovat za seznam znaků
"Toto je řetězec"[0]  # => 'T'

# .format lze použít ke skládání řetězců
"{} mohou být {}".format("řetězce", "skládány")

# Formátovací argumenty můžete opakovat
"{0} {1} stříkaček stříkalo přes {0} {1} střech".format("tři sta třicet tři", "stříbrných")
# => "tři sta třicet tři stříbrných stříkaček stříkalo přes tři sta třicet tři stříbrných střech"

# Pokud nechcete počítat, můžete použít pojmenované argumenty
"{jmeno} si dal {jidlo}".format(jmeno="Franta", jidlo="guláš")  # => "Franta si dal guláš"

# Pokud zároveň potřebujete podporovat Python 2.5 a nižší, můžete použít starší způsob formátování
"%s se dají %s jako v %s" % ("řetězce", "skládat", "jazyce C")


# None je objekt (jinde NULL, nil, ...)
None  # => None

# Pokud porovnáváte něco s None, nepoužívejte operátor rovnosti "==",
# použijte raději operátor "is", který testuje identitu.
"něco" is None  # => False
None is None    # => True

# None, 0, a prázdný řetězec/seznam/slovník se vyhodnotí jako False
# Vše ostatní se vyhodnotí jako True
bool(0)   # => False
bool("")  # => False
bool([])  # => False
bool({})  # => False


####################################################
## 2. Proměnné a kolekce
####################################################

# Python má funkci print
print("Jsem 3. Python 3.")

# Proměnné není třeba deklarovat před přiřazením
# Konvence je používat male_pismo_s_podtrzitky
nazev_promenne = 5
nazev_promenne  # => 5
# Názvy proměnných mohou obsahovat i UTF8 znaky
název_proměnné = 5

# Přístup k předtím nepoužité proměnné vyvolá výjimku
# Odchytávání vyjímek - viz další kapitola
neznama_promenna  # Vyhodí NameError

# Seznam se používá pro ukládání sekvencí
sez = []
# Lze ho rovnou naplnit
jiny_seznam = [4, 5, 6]

# Na konec seznamu se přidává pomocí append
sez.append(1)    # sez je nyní [1]
sez.append(2)    # sez je nyní [1, 2]
sez.append(4)    # sez je nyní [1, 2, 4]
sez.append(3)    # sez je nyní [1, 2, 4, 3]
# Z konce se odebírá se pomocí pop
sez.pop()        # => 3 a sez je nyní [1, 2, 4]
# Vložme trojku zpátky
sez.append(3)    # sez je nyní znovu [1, 2, 4, 3]

# Přístup k prvkům funguje jako v poli
sez[0]  # => 1
# Mínus počítá odzadu (-1 je poslední prvek)
sez[-1]  # => 3

# Přístup mimo seznam vyhodí IndexError
sez[4]  # Vyhodí IndexError

# Pomocí řezů lze ze seznamu vybírat různé intervaly
# (pro matematiky: jedná se o uzavřený/otevřený interval)
sez[1:3]  # => [2, 4]
# Odříznutí začátku
sez[2:]  # => [4, 3]
# Odříznutí konce
sez[:3]  # => [1, 2, 4]
# Vybrání každého druhého prvku
sez[::2]  # =>[1, 4]
# Vrácení seznamu v opačném pořadí
sez[::-1]  # => [3, 4, 2, 1]
# Lze použít jakoukoliv kombinaci parametrů pro vytvoření složitějšího řezu
# sez[zacatek:konec:krok]

# Odebírat prvky ze seznamu lze pomocí del
del sez[2]   # sez je nyní [1, 2, 3]

# Seznamy můžete sčítat
# Hodnoty sez a jiny_seznam přitom nejsou změněny
sez + jiny_seznam   # => [1, 2, 3, 4, 5, 6]

# Spojit seznamy lze pomocí extend
sez.extend(jiny_seznam)   # sez je nyní [1, 2, 3, 4, 5, 6]

# Kontrola, jestli prvek v seznamu existuje, se provádí pomocí in
1 in sez  # => True

# Délku seznamu lze zjistit pomocí len
len(sez)  # => 6


# N-tice je jako seznam, ale je neměnná
ntice = (1, 2, 3)
ntice[0]      # => 1
ntice[0] = 3  # Vyhodí TypeError

# S n-ticemi lze dělat většinu operací, jako se seznamy
len(ntice)         # => 3
ntice + (4, 5, 6)  # => (1, 2, 3, 4, 5, 6)
ntice[:2]          # => (1, 2)
2 in ntice         # => True

# N-tice (nebo seznamy) lze rozbalit do proměnných jedním přiřazením
a, b, c = (1, 2, 3)  # a je nyní 1, b je nyní 2 a c je nyní 3
# N-tice jsou vytvářeny automaticky, když vynecháte závorky
d, e, f = 4, 5, 6
# Prohození proměnných je tak velmi snadné
e, d = d, e  # d je nyní 5, e je nyní 4


# Slovníky ukládají klíče a hodnoty
prazdny_slovnik = {}
# Lze je také rovnou naplnit
slovnik = {"jedna": 1, "dva": 2, "tři": 3}

# Přistupovat k hodnotám lze pomocí []
slovnik["jedna"]  # => 1

# Všechny klíče dostaneme pomocí keys() jako iterovatelný objekt. Nyní ještě
# potřebujeme obalit volání v list(), abychom dostali seznam. To rozebereme
# později. Pozor, že jakékoliv pořadí klíčů není garantováno - může být různé.
list(slovnik.keys())  # => ["dva", "jedna", "tři"]

# Všechny hodnoty opět jako iterovatelný objekt získáme pomocí values(). Opět
# tedy potřebujeme použít list(), abychom dostali seznam. Stejně jako
# v předchozím případě, pořadí není garantováno a může být různé
list(slovnik.values())  # => [3, 2, 1]

# Operátorem in se lze dotázat na přítomnost klíče
"jedna" in slovnik  # => True
1 in slovnik        # => False

# Přístup k neexistujícímu klíči vyhodí KeyError
slovnik["four"]  # Vyhodí KeyError

# Metoda get() funguje podobně jako [], ale vrátí None místo vyhození KeyError
slovnik.get("jedna")   # => 1
slovnik.get("čtyři")   # => None
# Metodě get() lze předat i výchozí hodnotu místo None
slovnik.get("jedna", 4)   # => 1
slovnik.get("čtyři", 4)   # => 4

# metoda setdefault() vloží prvek do slovníku pouze pokud tam takový klíč není
slovnik.setdefault("pět", 5)  # slovnik["pět"] je nastaven na 5
slovnik.setdefault("pět", 6)  # slovnik["pět"] je pořád 5

# Přidání nové hodnoty do slovníku
slovnik["čtyři"] = 4
# Hromadně aktualizovat nebo přidat data lze pomocí update(), parametrem je opět slovník
slovnik.update({"čtyři": 4})  # slovnik je nyní {"jedna": 1, "dva": 2, "tři": 3, "čtyři": 4, "pět": 5}

# Odebírat ze slovníku dle klíče lze pomocí del
del slovnik["jedna"]  # odebere klíč "jedna" ze slovnik


# Množiny ukládají ... překvapivě množiny
prazdna_mnozina = set()
# Také je lze rovnou naplnit. A ano, budou se vám plést se slovníky. Bohužel.
mnozina = {1, 1, 2, 2, 3, 4}  # mnozina je nyní {1, 2, 3, 4}

# Přidání položky do množiny
mnozina.add(5)  # mnozina je nyní {1, 2, 3, 4, 5}

# Průnik lze udělat pomocí operátoru &
jina_mnozina = {3, 4, 5, 6}
mnozina & jina_mnozina  # => {3, 4, 5}

# Sjednocení pomocí operátoru |
mnozina | jina_mnozina  # => {1, 2, 3, 4, 5, 6}

# Rozdíl pomocí operátoru -
{1, 2, 3, 4} - {2, 3, 5}  # => {1, 4}

# Operátorem in se lze dotázat na přítomnost prvku v množině
2 in mnozina  # => True
9 in mnozina  # => False


####################################################
## 3. Řízení toku programu, cykly
####################################################

# Vytvořme si proměnnou
promenna = 5

# Takto vypadá podmínka. Na odsazení v Pythonu záleží!
# Vypíše "proměnná je menší než 10".
if promenna > 10:
    print("proměnná je velká jak Rusko")
elif promenna < 10:  # Část elif je nepovinná
    print("proměnná je menší než 10")
else:                # Část else je také nepovinná
    print("proměnná je právě 10")


"""
Smyčka for umí iterovat (nejen) přes seznamy
vypíše:
    pes je savec
    kočka je savec
    myš je savec
"""
for zvire in ["pes", "kočka", "myš"]:
    # Můžete použít formát pro složení řetězce
    print("{} je savec".format(zvire))

"""
range(cislo) vrací iterovatelný objekt čísel od 0 do cislo
vypíše:
    0
    1
    2
    3
"""
for i in range(4):
    print(i)

"""
range(spodni_limit, horni_limit) vrací iterovatelný objekt čísel mezi limity
vypíše:
    4
    5
    6
    7
"""
for i in range(4, 8):
    print(i)

"""
Smyčka while se opakuje, dokud je podmínka splněna.
vypíše:
    0
    1
    2
    3
"""
x = 0
while x < 4:
    print(x)
    x += 1  # Zkrácený zápis x = x + 1. Pozor, žádné x++ neexisuje.


# Výjimky lze ošetřit pomocí bloku try/except(/else/finally)
try:
    # Pro vyhození výjimky použijte raise
    raise IndexError("Přistoupil jste k neexistujícímu prvku v seznamu.")
except IndexError as e:
    print("Nastala chyba: {}".format(e))
    # Vypíše: Nastala chyba: Přistoupil jste k neexistujícímu prvku v seznamu.
except (TypeError, NameError):  # Více výjimek lze zachytit najednou
    pass  # Pass znamená nedělej nic - nepříliš vhodný způsob ošetření chyb
else:  # Volitelný blok else musí být až za bloky except
    print("OK!")  # Vypíše OK! v případě, že nenastala žádná výjimka
finally:  # Blok finally se spustí nakonec za všech okolností
    print("Uvolníme zdroje, uzavřeme soubory...")

# Místo try/finally lze použít with pro automatické uvolnění zdrojů
with open("soubor.txt") as soubor:
    for radka in soubor:
        print(radka)

# Python běžně používá iterovatelné objekty, což je prakticky cokoliv,
# co lze považovat za sekvenci. Například to, co vrací metoda range(),
# nebo otevřený soubor, jsou iterovatelné objekty.

slovnik = {"jedna": 1, "dva": 2, "tři": 3}
iterovatelny_objekt = slovnik.keys()
print(iterovatelny_objekt)  # => dict_keys(["jedna", "dva", "tři"]). Toto je iterovatelný objekt.

# Můžeme použít cyklus for na jeho projití
for klic in iterovatelny_objekt:
    print(klic)    # vypíše postupně: jedna, dva, tři

# Ale nelze přistupovat k prvkům pod jejich indexem
iterovatelny_objekt[1]  # Vyhodí TypeError

# Všechny položky iterovatelného objektu lze získat jako seznam pomocí list()
list(slovnik.keys())  # => ["jedna", "dva", "tři"]

# Z iterovatelného objektu lze vytvořit iterátor
iterator = iter(iterovatelny_objekt)

# Iterátor je objekt, který si pamatuje stav v rámci svého iterovatelného objektu
# Další hodnotu dostaneme voláním next()
next(iterator)  # => "jedna"

# Iterátor si udržuje svůj stav v mezi jednotlivými voláními next()
next(iterator)  # => "dva"
next(iterator)  # => "tři"

# Jakmile interátor vrátí všechna svá data, vyhodí výjimku StopIteration
next(iterator)  # Vyhodí StopIteration


####################################################
## 4. Funkce
####################################################

# Pro vytvoření nové funkce použijte def
def secist(x, y):
    print("x je {} a y je {}".format(x, y))
    return x + y  # Hodnoty se vrací pomocí return

# Volání funkce s parametry
secist(5, 6)  # => Vypíše "x je 5 a y je 6" a vrátí 11

# Jiný způsob, jak volat funkci, je použít pojmenované argumenty
secist(y=6, x=5)  # Pojmenované argumenty můžete předat v libovolném pořadí

# Lze definovat funkce s proměnným počtem (pozičních) argumentů
def vrat_argumenty(*argumenty):
    return argumenty

vrat_argumenty(1, 2, 3)  # => (1, 2, 3)

# Lze definovat také funkce s proměnným počtem pojmenovaných argumentů
def vrat_pojmenovane_argumenty(**pojmenovane_argumenty):
    return pojmenovane_argumenty

vrat_pojmenovane_argumenty(kdo="se bojí", nesmi="do lesa")
# => {"kdo": "se bojí", "nesmi": "do lesa"}


# Pokud chcete, lze použít obojí najednou
# Konvence je používat pro tyto účely názvy *args a **kwargs
def vypis_vse(*args, **kwargs):
    print(args, kwargs)  # print() vypíše všechny své parametry oddělené mezerou

vypis_vse(1, 2, a=3, b=4)  # Vypíše: (1, 2) {"a": 3, "b": 4}

# * nebo ** lze použít k rozbalení N-tic nebo slovníků!
ntice = (1, 2, 3, 4)
slovnik = {"a": 3, "b": 4}
vypis_vse(ntice)  # Vyhodnotí se jako vypis_vse((1, 2, 3, 4)) – jeden parametr, N-tice
vypis_vse(*ntice)  # Vyhodnotí se jako vypis_vse(1, 2, 3, 4)
vypis_vse(**slovnik)  # Vyhodnotí se jako vypis_vse(a=3, b=4)
vypis_vse(*ntice, **slovnik)  # Vyhodnotí se jako vypis_vse(1, 2, 3, 4, a=3, b=4)


# Viditelnost proměnných - vytvořme si globální proměnnou x
x = 5

def nastavX(cislo):
    # Lokální proměnná x překryje globální x
    x = cislo  # => 43
    print(x)  # => 43

def nastavGlobalniX(cislo):
    global x
    print(x)  # => 5
    x = cislo  # Nastaví globální proměnnou x na 6
    print(x)  # => 6

nastavX(43)
nastavGlobalX(6)


# Funkce jsou first-class objekty
def vyrobit_scitacku(pricitane_cislo):
    def scitacka(x):
        return x + pricitane_cislo
    return scitacka

pricist_10 = vyrobit_scitacku(10)
pricist_10(3)  # => 13

# Klíčové slovo lambda vytvoří anonymní funkci
(lambda parametr: parametr > 2)(3)  # => True

# Lze použít funkce map() a filter() z funkcionálního programování
map(pricist_10, [1, 2, 3])
# => <map object at 0x0123467> - iterovatelný objekt s obsahem: [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7])
# => <filter object at 0x0123467> - iterovatelný objekt s obsahem: [6, 7]

# S generátorovou notací lze dosáhnout podobných výsledků, ale vrací seznam
[pricist_10(i) for i in [1, 2, 3]]  # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5]   # => [6, 7]
# Generátorová notace funguje i pro slovníky
{x: x**2 for x in range(1, 5)}  # => {1: 1, 2: 4, 3: 9, 4: 16}
# A také pro množiny
{pismeno for pismeno in "abeceda"}  # => {"d", "a", "c", "e", "b"}


####################################################
## 5. Třídy
####################################################

# We subclass from object to get a class.
class Human(object):

    # A class attribute. It is shared by all instances of this class
    species = "H. sapiens"

    # Basic initializer, this is called when this class is instantiated.
    # Note that the double leading and trailing underscores denote objects
    # or attributes that are used by python but that live in user-controlled
    # namespaces. Methods(or objects or attributes) like: __init__, __str__,
    # __repr__ etc. are called magic methods (or sometimes called dunder methods)
    # You should not invent such names on your own.
    def __init__(self, name):
        # Assign the argument to the instance's name attribute
        self.name = name

    # An instance method. All methods take "self" as the first argument
    def say(self, msg):
        return "{name}: {message}".format(name=self.name, message=msg)

    # A class method is shared among all instances
    # They are called with the calling class as the first argument
    @classmethod
    def get_species(cls):
        return cls.species

    # A static method is called without a class or instance reference
    @staticmethod
    def grunt():
        return "*grunt*"


# Instantiate a class
i = Human(name="Ian")
print(i.say("hi"))     # prints out "Ian: hi"

j = Human("Joel")
print(j.say("hello"))  # prints out "Joel: hello"

# Call our class method
i.get_species()   # => "H. sapiens"

# Change the shared attribute
Human.species = "H. neanderthalensis"
i.get_species()   # => "H. neanderthalensis"
j.get_species()   # => "H. neanderthalensis"

# Call the static method
Human.grunt()   # => "*grunt*"


####################################################
## 6. Modules
####################################################

# You can import modules
import math
print(math.sqrt(16))  # => 4

# You can get specific functions from a module
from math import ceil, floor
print(ceil(3.7))  # => 4.0
print(floor(3.7))   # => 3.0

# You can import all functions from a module.
# Warning: this is not recommended
from math import *

# You can shorten module names
import math as m
math.sqrt(16) == m.sqrt(16)   # => True

# Python modules are just ordinary python files. You
# can write your own, and import them. The name of the
# module is the same as the name of the file.

# You can find out which functions and attributes
# defines a module.
import math
dir(math)


####################################################
## 7. Advanced
####################################################

# Generators help you make lazy code
def double_numbers(iterable):
    for i in iterable:
        yield i + i

# A generator creates values on the fly.
# Instead of generating and returning all values at once it creates one in each
# iteration.  This means values bigger than 15 wont be processed in
# double_numbers.
# Note range is a generator too. Creating a list 1-900000000 would take lot of
# time to be made
# We use a trailing underscore in variable names when we want to use a name that
# would normally collide with a python keyword
range_ = range(1, 900000000)
# will double all numbers until a result >=30 found
for i in double_numbers(range_):
    print(i)
    if i >= 30:
        break


# Decorators
# in this example beg wraps say
# Beg will call say. If say_please is True then it will change the returned
# message
from functools import wraps


def beg(target_function):
    @wraps(target_function)
    def wrapper(*args, **kwargs):
        msg, say_please = target_function(*args, **kwargs)
        if say_please:
            return "{} {}".format(msg, "Please! I am poor :(")
        return msg

    return wrapper


@beg
def say(say_please=False):
    msg = "Can you buy me a beer?"
    return msg, say_please


print(say())  # Can you buy me a beer?
print(say(say_please=True))  # Can you buy me a beer? Please! I am poor :(
```

## Ready For More?

### Free Online

* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
* [Ideas for Python Projects](http://pythonpracticeprojects.com)
* [The Official Docs](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
* [Python Course](http://www.python-course.eu/index.php)
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)

### Dead Tree

* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)