[python] otázka ohladom mojho štýlu písania v OOP
Jan Bednařík
jan.bednarik na gmail.com
Sobota Leden 12 21:51:52 CET 2013
Rád bych ti poradil konkrétněji, ale tím že nedodržuješ PEP8 a nestandardně
mícháš různé způsoby zápisu kódu dohromady (CamelCase v zázvech proměnných
apod.), je ten tvůj kód na první pohled nepřehledný, alespoň já to tak
vnímám. A těžko se to luští.
Nicméně rozhodně by ses měl vyvarovat importování hvězdiček (from tkinter
import *). Měl bys mít přehled o tom co importuješ - měl bys konkrétně
importovat jen třídy, funkce, atd., které používáš.
Definování funkcí uvnitř metod je myslím taky na pováženou - měl by si
spíše využít pomocné metody. Jak si sám napsal, rozkouskování pro
zpřehlednění programu určitě neuškodí - přehlednost a srozumitelnost by
měla být na prvním místě, protože až se k tomu kódu budeš někdy vracet,
oceníš, když se v něm snadno zorientuješ.
Ono to rozkouskování na metody a funkce je hlavně otázka citu a zkušeností,
které nabereš časem. Případně se zkus přiučit čtením zdrojových kódů
nějakých větších open-source projektů.
2013/1/12 Roman Beno <romanbeno273 na gmail.com>
> Dobrý den,
>
> zmienený dokument som už prezeral.
> Ako editor používam Stany Python editor, a pri kopírovaní sa kód mohol
> trošku zdeformovat (na zarovnanie, zalomenia riadkov atd)..
>
> V mojej otázke som mal viac na mysli, či je vhodné písat jednu velkú
> metódu bez atribútov ako program, prípadne viac metód na rozkúskovanie a
> trochu sprehladnenie programu, resp. sa snažit aby čast kódu pri vytváranií
> instancie triedy (čiže už za dokončením definície triedy) bola čo
> najstručnejšia?
>
> Tieto konkrétne informácie som bohužial zatial nikde nenašiel :-(
> Ďakujem za odpoved
>
>
> Dňa 12. január 2013 18:23, Jan Bednařík <jan.bednarik na gmail.com>napísal(-a):
>
> Ahoj,
>>
>> v prvé řadě bych doporučil nastudovat si PEP-8, což je doporučení
>> (de-facto standard) jak psát kód v Pythonu.
>> http://www.python.org/dev/peps/pep-0008/
>>
>> Honza
>>
>>
>>
>> 2013/1/12 Roman Beno <romanbeno273 na gmail.com>
>>
>>> <http://programujte.com/anonymni-profil/170094/>
>>>
>>> Dobrý deň,
>>>
>>> chcel by som sa spýtať na váš názor ohľadne môjho štýlu písania
>>> programov v OOP.
>>> Rád prijmem akukolvek kritiku, mojim cielom je sa v tomto ohľade zlepšit
>>> a v tejto oblasti som si nie som príliš istý.
>>>
>>> Tu sú ukážky mojich kódov:
>>>
>>> # -*- coding: utf-8 -*-
>>> #################Definícia triedy#######################
>>> class Fibonacci:
>>> "Fibonacciho trieda"
>>> def __init__(self,a=0,b=1,pocet_cisiel=10,default=0):
>>> "Vyrobíme stavebný materiál pre fibonaccciho postupnosť."
>>> self.a=a
>>> self.b=b
>>> self.pocet_cisiel=pocet_cisiel
>>> self.default=default
>>> def proces(self):
>>> print(self.a,self.b,end=" ")
>>> while True:
>>> self.a=(self.a+self.b)
>>> self.default+=1
>>> if self.default>=self.pocet_cisiel:
>>> print("\n")
>>> break
>>> print(self.a,end=" ")
>>> # postupnost bude a,b,a,b,a,b... tento blok je pre všetky a
>>> self.b=(self.a+self.b)
>>> self.default+=1
>>> if self.default>=self.pocet_cisiel:
>>> print("\n")
>>> break
>>> print(self.b,end=" ")
>>> # a tento pre všetky b
>>> #################Hlavný program##########################
>>> MojaInstancia=Fibonacci(pocet_cisiel=20)
>>> MojaInstancia.proces()
>>>
>>>
>>> ************************************************************************************************************
>>> Tu je další:
>>>
>>> # -*- coding: utf-8 -*-
>>> # program Záznamník adries
>>> # tréning Tkinter + OOP
>>> # autor JA, dnes
>>> # ver. 1.0
>>> # * opravená chyba pri vytvárani poľa pre zadávaní adresy, použitá
>>> neexistujúca farba okna
>>> # * opravená chyba pri vytváraní tlačítka ukončujúceho okno zadávania,
>>> použitý neexistujúci názov prvku
>>> # * zmenené umiestnenie a veľkosť tlačítka pre zavretie okna pri
>>> pridávaní adries
>>> # ver. 1.1
>>> # * opravená chyba pri potvrdení voľby mena pri pridávaní mena, použitá
>>> neexistujúca premenná
>>> # * opravená chyba pri potvrdení voľby mena pri pridávaní adresy,
>>> použitá neexistujúca premenná
>>> # ver. 1.2
>>> # * polia pre zadávaní mena aj adresy sa po zadaní oboch údajov teraz
>>> vymažú (ich hodnota)m
>>> # uživatel ich teraz nemusí zadávať sám
>>> # * opravená chyba pri načítaní údajov zo zoznamu, použitá neexistujúca
>>> premenná
>>> # ver. 1.2.1
>>> # * opravená chyba pri zobrazovaní načítaných údajov,použitá
>>> neexistujúca premenná
>>> # ver. 1.3
>>> # * opravená chyba pri vytváraní tlačítka na zavretie okna načítania
>>> údajov, použitá neexistujúca
>>> # premenná
>>> # * opravená chyba pri zobrazovaní načítaných údajov (druhá chyba v
>>> tomto), použitá neexistujúca premenná
>>> # * zmenený text niektorých tlačítok v úvodnom menu
>>> # * v popisku okna sa teraz zobrazuje aj aktuálna verzia programu
>>> # ver. 1.3.1
>>> # * pri načítaní údajov upravená oddelovacia čiara údajov
>>> # * zmenené rozmery tlačítka ukončujúceho okno načítania údajov
>>> # ver. 1.3.2
>>> # * v okne ukladania súboru zmenená farba informačného textu na
>>> prehľadnejšiu
>>> # * opravená chyba pri ukladaní súborov, použitá neexistujúca premenná
>>> # ver. 1.4
>>> # * opravená chyba pri ukladaní súborov, použitá ďalšia neexistujúca
>>> premenná
>>> # * zmenená farba riadku pre chybové hlásenia v okne ukladania dát na
>>> prirodzenú bledomodrú
>>> # * pridaná možnosť odstránenia položiek zo zoznamu
>>>
>>> from tkinter import *
>>> import sys
>>> import os
>>>
>>> class Zaznamnik:
>>> "Toto je trieda môjho záznamníku"
>>>
>>> def __init__(self):
>>> self.hlavneOkno=Tk()
>>> self.hlavneOkno.title("Záznamník, Ver. 1.4")
>>> self.adresy=[]
>>> self.zoznamMena=[]
>>>
>>> def program(self):
>>> "Táto časť programu bude mať za úlohu čisto len grafiku hlavného
>>> menu (nie logiku)."
>>>
>>> self.HOuvodnypopisokLabel=Label(self.hlavneOkno,bg="lightblue",text="Vitajte
>>> v mojom záznamníku adries.\nDúfam, že sa vám bude páčiť.")
>>> self.HOuvodnypopisokLabel.grid(row=0,column=0,sticky=W+E+N+S)
>>> # uvodny popisok - label - ktorý nás privíta v programe
>>>
>>> self.HOtlacitkoZadavatAdresy=Button(self.hlavneOkno,bg="lightblue",activebackground="lightgreen",text="Pridať
>>> adresy do záznamníka")
>>> self.HOtlacitkoZadavatAdresy.grid(row=1,column=0,sticky=W+E+N+S)
>>> # tlačítko, ktoré by malo umožniť zadávanie adries
>>>
>>> self.HOtlacitkoOdstranitAdresy=Button(self.hlavneOkno,bg="lightblue",activebackground="lightgreen",text="Odstrániť
>>> adresu zo záznamníka")
>>>
>>> self.HOtlacitkoOdstranitAdresy.grid(row=2,column=0,sticky=W+E+N+S)
>>> # tlačítko, ktoré by malo umožniť odstránenie adries
>>>
>>> self.HOtlacitkoUlozit=Button(self.hlavneOkno,bg="lightblue",activebackground="lightgreen",text="Uložiť
>>> do súboru")
>>> self.HOtlacitkoUlozit.grid(row=3,column=0,sticky=W+E+N+S)
>>> # tlačítko, ktoré by malo umožnit uloženie do súboru
>>>
>>> self.HOtlacitkoNacitat=Button(self.hlavneOkno,bg="lightblue",activebackground="lightgreen",text="Načítať
>>> dáta zo zoznamu")
>>> self.HOtlacitkoNacitat.grid(row=4,column=0,sticky=W+E+N+S)
>>> # tlačítko, ktoré by malo umožniť načítanie dát zo súboru
>>>
>>> self.HOtlacitkoNapoveda=Button(self.hlavneOkno,bg="lightblue",activebackground="lightgreen",text="Zobrazenie
>>> nápovedy")
>>> self.HOtlacitkoNapoveda.grid(row=5,column=0,sticky=W+E+N+S)
>>> # tlačítko, ktoré by malo zobraziť nápovedu
>>>
>>> self.HOtlacitkoUkoncit=Button(self.hlavneOkno,bg="lightblue",activebackground="lightgreen",text="Ukončiť
>>> program",command=self.hlavneOkno.quit)
>>> self.HOtlacitkoUkoncit.grid(row=6,column=0,sticky=W+E+N+S)
>>> # tlačítko, ktoré by malo ukončiť program
>>>
>>> def zadavanie_adries():
>>> "Táto časť bude zachytávať logiku programu. Kvoli velkému
>>> rozsahu rozdelenú na niekoľko častí. Konkrétne zadávanie adries."
>>> # prvá časť tejto funkcie
>>> # vzhľad podokna na zadávanie
>>> self.OknoZadavanie=Toplevel()
>>> self.OknoZadavanie.title("Zadávanie adries")
>>>
>>> self.OknoZadavanieLabel=Label(self.OknoZadavanie,bg="lightblue",text="
>>> Aktuálna činnosť: Zadávanie adries \nPre potvrdenie údaju z
>>> okna stlačte ENTER.\n")
>>>
>>> self.OknoZadavanieLabel.grid(row=0,column=0,columnspan=4,sticky=W+E+N+S)
>>> # Vytvorenie podokna na zadávanie adries, nastavený titulok
>>> + úvodný Label
>>> self.VarPPCH=StringVar()
>>>
>>> self.OknoZadavanieLabelChybHlasky=Label(self.OknoZadavanie,bg="lightblue",textvariable=self.VarPPCH)
>>>
>>> self.OknoZadavanieLabelChybHlasky.grid(row=1,column=0,columnspan=4,sticky=W+E+N+S)
>>> # Vytvorená textová premenná pre prípadné chybové hlášky.
>>> Pre začiatok sa bude tváriť ako
>>> # neviditeľná súčasť okna
>>>
>>> self.RamecZadajMeno=Frame(self.OknoZadavanie,bd=3,bg="lightblue")
>>>
>>> self.RamecZadajMeno.grid(row=2,column=0,columnspan=4,sticky=W+E+N+S)
>>> self.VarPZM=StringVar()
>>> # Vytvorený rámec pre zadanie mena + popisok k nemu. Taktiež
>>> premenná pre políčko
>>> # pre vstup
>>>
>>> self.RamecPopisokPola=Label(self.RamecZadajMeno,text="Zadajte meno
>>> dotyčného:",bg="lightblue")
>>> self.RamecPopisokPola.grid(row=2,column=0,sticky=W+E+N+S)
>>>
>>> self.PolePreVstupMena=Entry(self.RamecZadajMeno,bg="lightyellow",textvariable=self.VarPZM,font="Arial
>>> 8")
>>>
>>> self.PolePreVstupMena.grid(row=2,column=1,columnspan=3,sticky=W+E+N+S)
>>> # Vytvorený popisok pre pole pre vstup + políčko samotné
>>>
>>> self.RamecZadajAdresu=Frame(self.OknoZadavanie,bd=4,bg="lightblue")
>>>
>>> self.RamecZadajAdresu.grid(row=3,column=0,columnspan=4,sticky=W+E+N+S)
>>>
>>> self.LabelPreDruhePole=Label(self.RamecZadajAdresu,bg="lightblue",text="Zadajte
>>> adresu dotyčného: ")
>>> self.LabelPreDruhePole.grid(row=3,column=0,sticky=W+E+N+S)
>>> self.VarPPA=StringVar()
>>>
>>> self.PolePreAdresu=Entry(self.RamecZadajAdresu,bg="lightyellow",textvariable=self.VarPPA,font="Arial
>>> 8")
>>> self.PolePreAdresu.grid(row=3,column=1,columnspan=3)
>>> # Vytvorený rámec pre zadanie adresy, popis pre neho,
>>> premennú pre neho a taktiež pole
>>> # samé.
>>>
>>> self.ZadavacieTlacitkoUkoncit=Button(self.OknoZadavanie,bg="lightblue",activebackground="lightgreen",command=self.OknoZadavanie.destroy,text="Zavrieť
>>> toto okno")
>>>
>>> self.ZadavacieTlacitkoUkoncit.grid(row=4,column=0,columnspan=4,sticky=W+E+N+S)
>>> self.OverovaciToken=0
>>> # Vytvorené tlačítko pre zavretie tohto okna pre zadanie
>>> adresy.
>>> def enter(BoloStlacene):
>>> BoloStlacene.widget.configure(state=DISABLED)
>>> self.udajMeno=str(self.PolePreVstupMena.get())
>>> self.OverovaciToken+=1
>>> if self.OverovaciToken==2:
>>> self.PolePreVstupMena.configure(state=NORMAL)
>>> self.PolePreAdresu.configure(state=NORMAL)
>>> self.zoznamMena.append(self.udajMeno)
>>> self.VarPZM.set("")
>>> self.VarPPA.set("")
>>> self.adresy.append([self.udajMeno,self.udajAdresu])
>>> self.OverovaciToken=0
>>> # funkcia, čo sa má stať po zdarnom zadaní informácie do
>>> políčka Meno. Dané políčko
>>> # sa disabluje, údaj z neho sa uloží. + špecialita overovací
>>> token. Ak dosiahne hodnotu 2,
>>> # program zistí, že má spravit ďalšiu "obrátku" pri
>>> pridávaní do zoznamu
>>> def entri(StlaceneBolo):
>>> StlaceneBolo.widget.configure(state=DISABLED)
>>> self.udajAdresu=str(self.PolePreAdresu.get())
>>> self.OverovaciToken+=1
>>> if self.OverovaciToken==2:
>>> self.PolePreVstupMena.configure(state=NORMAL)
>>> self.PolePreAdresu.configure(state=NORMAL)
>>> self.zoznamMena.append(self.udajMeno)
>>> self.VarPZM.set("")
>>> self.VarPPA.set("")
>>> self.adresy.append([self.udajMeno,self.udajAdresu])
>>> self.OverovaciToken=0
>>> # táto funkcia zase slúži na definovanie činnosti políčka
>>> Adresy. Zapíše údaj
>>> # do zoznamu a disabluje políčko. Malo by to zabezpečiť
>>> zadávanie.
>>> self.PolePreVstupMena.bind("<Return>",enter)
>>> self.PolePreAdresu.bind("<Return>",entri)
>>> # čo sa má stať po stlačení Entrov v rôznych okienkach
>>>
>>> def nacitanie_dat():
>>> "Táto funkcia by mala zabezpečiť zobrazenie, resp. načítanie
>>> dát zo zoznamu."
>>> self.OknoNacitanie=Toplevel()
>>> self.OknoNacitanie.title("Načítanie dát")
>>> # vytvorené vlastné okno pre načítanie dát, kde by sa
>>> teoreticky mali zobrazovať
>>> # dáta uložené v zozname adries
>>>
>>> self.oknoNacitanieZobrazenie=Label(self.OknoNacitanie,bg="lightblue",text="")
>>> self.oknoNacitanieZobrazenie.grid(row=0,column=0)
>>>
>>> self.premenna="""\tMená\t\tAdresy\n***************************************\n"""
>>> if len(self.adresy)==0:
>>> self.oknoNacitanieZobrazenie.configure(text="Zoznam je
>>> prázdny.")
>>> else:
>>> for p in self.adresy:
>>> self.coNacitaj="\t{0}\t\t{1}\n".format(p[0],p[1])
>>> self.premenna+=self.coNacitaj
>>>
>>> self.oknoNacitanieZobrazenie.configure(text=self.premenna)
>>> # toto by malo zabezpečiť zdarné zobrazovanie položiek
>>> zoznamu
>>>
>>>
>>> self.tlacitkoUkoncitON=Button(self.OknoNacitanie,bg="lightblue",activebackground="lightgreen",text="Zavrieť
>>> toto okno",command=self.OknoNacitanie.destroy)
>>> self.tlacitkoUkoncitON.grid(row=1,column=0,sticky=N+S+E+W)
>>> # toto tvorí tlačítko, ktoré by mohlo zavrieť okno
>>>
>>> def ulozenie_do_suboru():
>>> "Toto má na starosti zdarné uloženie dát do súboru. Trošku
>>> nám pomôže predošlá funkcia, načítanie dát."
>>> self.OknoUlozenie=Toplevel()
>>> self.OknoUlozenie.title("Uloženie do súboru")
>>>
>>> self.OknoUlozenieLabelVyber=Label(self.OknoUlozenie,text="Vyberte meno
>>> súboru, do ktorého chcete uložiť dáta zo súboru.",bg="lightblue")
>>>
>>> self.OknoUlozenieLabelVyber.grid(row=0,column=0,columnspan=2,sticky=W+E+N+S)
>>> # vytvorené ukladacie okno, nastavený popisok pre neho +
>>> popisok pre políčko pre zadanie mena ukladacieho súboru
>>> self.OUPPV=StringVar()
>>>
>>> self.OUPolePreVstup=Entry(self.OknoUlozenie,bg="lightyellow",font="Arial
>>> 8",textvariable=self.OUPPV)
>>>
>>> self.OUPolePreVstup.grid(row=0,column=2,columnspan=2,sticky=W+E+N+S)
>>> # pole, kam môžeme zadávať samotný názov súboru
>>>
>>> self.OUPosudzovaciaHlaska=Label(self.OknoUlozenie,bg="lightblue",text="")
>>>
>>> self.OUPosudzovaciaHlaska.grid(row=1,column=0,columnspan=4,sticky=W+E+N+S)
>>> # tu sa vypíš prípadná chybová hláška, v závislosti od toho,
>>> čo zadáme do zmieneného políčka
>>> def entricek(ppv):
>>> self.result=str(self.OUPolePreVstup.get())
>>> if len(self.result)==0:
>>> self.OUPosudzovaciaHlaska.configure(text="Nezadali
>>> ste meno žiadneho súboru.")
>>> self.OUPPV.set("")
>>> return
>>> # ak ste nezadali nič, tak vypíše hlášku, znuluje
>>> hodnotu pola a zavrie funkciu
>>> if len(self.adresy)==0:
>>> self.OUPosudzovaciaHlaska.configure(text="Zoznam
>>> adries je prázdny.")
>>> self.OUPPV.set("")
>>> return
>>> # podobné ako v predchádzajúcom prípade, ibaže ak je
>>> zoznam adries prázdny
>>> self.subor=open(self.result,"wt")
>>> try:
>>> self.subor.write(self.premenna)
>>> except:
>>> self.OUPosudzovaciaHlaska.configure(text="Zatial ste
>>> nenačítali žiadne dáta. Urobte tak cez hlavné menu.")
>>> self.subor.close()
>>> self.OUPPV.set("")
>>> return
>>> # stale je možnost že uživatel nenačítal požadované
>>> dáta na vloženie
>>> self.OUPosudzovaciaHlaska.configure(text="Zatial ste
>>> nenačítali žiadne dáta. Urobte tak cez hlavné menu.")
>>> self.subor.close()
>>> self.OUPolePreVstup.configure(state=DISABLED)
>>> # toto sa stane v pripade že chyba nenastala,
>>> self.OknoUlozenie.bind("<Return>",entricek)
>>>
>>> self.OUTlacitkoZavri=Button(self.OknoUlozenie,bg="lightblue",activebackground="lightgreen",text="Zavrieť
>>> toto okno",command=self.OknoUlozenie.destroy)
>>>
>>> self.OUTlacitkoZavri.grid(row=2,column=0,columnspan=4,sticky=W+E+N+S)
>>> # urobené tlačítko, ktoré zavrie okno
>>>
>>> def odstranenie_poloziek():
>>> "Odstránenie jedného záznamu zo zoznamu adries a mien"
>>> self.OknoOdstranenie=Toplevel()
>>> self.OknoOdstranenie.title("Odstranenie poloziek")
>>> self.OOpripravenytext=[]
>>> # vytvorené okno odstránenia, nastavený popisok + náradíčko
>>> = prázdny zoznam
>>> for x in self.zoznamMena:
>>> self.OOpripravenytext.append(x)
>>>
>>> self.OOodstranenieLabel=Label(self.OknoOdstranenie,bg="lightblue",text="Vyberte
>>> si položku zoznamu,ktorú\nchcete odstrániť:")
>>> self.OOodstranenieLabel.grid(row=0,column=0)
>>> # pripraví zoznam položiek pre neskoršie odstranovanie +
>>> vytvorenie labelu na odstranenie
>>> # položky
>>> self.OOPPO=StringVar()
>>>
>>> self.OOPolePreOdstranenie=Entry(self.OknoOdstranenie,bg="lightyellow",textvariable=self.OOPPO,font="Arial
>>> 8")
>>>
>>> self.OOPolePreOdstranenie.grid(row=0,column=1,columnspan=2,sticky=W+E+S+N)
>>>
>>> self.OOLabelChybovaHlaska=Label(self.OknoOdstranenie,bg="lightblue",text="")
>>>
>>> self.OOLabelChybovaHlaska.grid(row=1,column=0,columnspan=3,sticky=W+E+S+N)
>>> # samotné políčko, kam možete zadat meno položky (meno
>>> konk.osoby, ktorú chcete odstrániť
>>> def stlacil_entri(gangnam):
>>> coBoloStlacenee=str(self.OOPolePreOdstranenie.get())
>>> if coBoloStlacenee in self.zoznamMena:
>>>
>>> indexCoBoloStlacenee=self.zoznamMena.index(coBoloStlacenee)
>>> else:
>>>
>>> self.OOLabelChybovaHlaska.configure(text="Neexistujúce meno.")
>>> self.OOPPO.set("")
>>> del self.adresy[indexCoBoloStlacenee]
>>> del
>>> self.zoznamMena[self.zoznamMena.index(coBoloStlacenee)]
>>> self.OOPPO.set("")
>>> # zoberieme to z políčka pre vstup, ak je v zozname
>>> mien, odstrán z oboch zoznamov
>>> # ak nie, vyhod chybove hlasky. Samozrejmostou je
>>> nasledne premazanie policka
>>> self.OOPolePreOdstranenie.bind("<Return>",stlacil_entri)
>>>
>>> self.OOZavriOkno=Button(self.OknoOdstranenie,bg="lightblue",activebackground="lightgreen",text="Zavrieť
>>> toto okno",command=self.OknoOdstranenie.destroy)
>>>
>>> self.OOZavriOkno.grid(row=2,column=0,columnspan=3,sticky=W+E+S+N)
>>> # zabezpečená akcia pre pole pre vstup po stlačení Enteru.
>>> # vytvorené tlačítko na zavretie okna
>>>
>>>
>>> self.HOtlacitkoNacitat.configure(command=nacitanie_dat)
>>> self.HOtlacitkoUlozit.configure(command=ulozenie_do_suboru)
>>> self.HOtlacitkoZadavatAdresy.configure(command=zadavanie_adries)
>>>
>>> self.HOtlacitkoOdstranitAdresy.configure(command=odstranenie_poloziek)
>>>
>>> self.hlavneOkno.mainloop()
>>>
>>> #########################################################
>>>
>>> inst=Zaznamnik()
>>> inst.program()
>>>
>>> Ďakujem za akúkolvek odpoved
>>>
>>> _______________________________________________
>>> Python mailing list
>>> Python na py.cz
>>> http://www.py.cz/mailman/listinfo/python
>>>
>>
>>
>> _______________________________________________
>> Python mailing list
>> Python na py.cz
>> http://www.py.cz/mailman/listinfo/python
>>
>
>
> _______________________________________________
> Python mailing list
> Python na py.cz
> http://www.py.cz/mailman/listinfo/python
>
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://www.py.cz/pipermail/python/attachments/20130112/49339129/attachment.html>
Další informace o konferenci Python