Python - dobré rady a praktiky

Radek Miček

Re:Python - dobré rady a praktiky
« Odpověď #90 kdy: 28. 03. 2016, 11:24:31 »
Zkus si přečíst sekci Hnutí za dobrý kód z http://www.abclinuxu.cz/blog/bystroushaak/2014/7/python-poznamky

Jinak osobně jsem v pythonu dělal na projektu, který měl přes 40k řádek podle CLOC (tzn bez prázdných řádků, komentářů, docstringů a tak). Nebyl s tím vůbec žádný problém, dělali jsme to ve dvou a šlo to v pohodě. Možná za to mohla microservices architektura, ale prostě žádné hroucení na hlavu se nekonalo. Ani co se týče kódu, ani co se týče výkonu, naopak se to krásně škáluje. Umím si představit, že by to stejným způsobem šlo klidně o řád dál bez nějakého stresu.

IDE nebo jiné nástroje pro Python vám při refaktoringu typicky pomohou mnohem méně než kompilátory moderních staticky typovaných jazyků (a nezmění to ani pokročilejší IDE jako PyCharm). IMO udržovat kód v Pythonu je tedy o dost náročnější (na druhé straně to zřejmě kompenzuje dostatek programátorů).

IDE jako PyCharm obsahuje gramatiku jazyka a ve spojení například s debuggerem má všechny předpoklady k tomu, aby si typy zjistilo samo a uložilo například do slovníku, nebo formou anotací do zdrojového textu. Není proto těžké udělat plugin, který by to obstaral včetně vazby na refaktoring.

Udělat takový plugin je prakticky nemožné, neboť typová rekonstrukce i pro jednoduché typové systémy (jako je například System F) je nerozhodnutelná. A pro (rozumné) otypování netriviálních programů v Pythonu potřebujete mnohem složitější typový systém (hádám minimálně na úrovni DOT).


Radek Miček

Re:Python - dobré rady a praktiky
« Odpověď #91 kdy: 28. 03. 2016, 12:00:01 »
BTW kromě statického typového systému mi v Pythonu chybí podpora pro vytváření neměnných tříd a neměnné kolekce.

Re:Python - dobré rady a praktiky
« Odpověď #92 kdy: 28. 03. 2016, 12:02:01 »
V pythonu občas lidi (hlavně začátečníci) vrací z funkcí dicty a píšou funkce, které berou dicty, protože je to jednoduché a rychlé. Pokud k tomu nedodají extenzivní dokumentaci, bývá to časem totálně neudržitelné. Tohle není problém Pythonu, ale špatného návrhu.
Ono to je ale úplně jedno, jestli vrací slovník, pole nebo n-tici. Problém je v tom, že do jakékoliv složitější datové struktury se časem může zatoulat typ, který tam být neměl. Pokud má být špatným návrhem používat jakékoliv složitější/složené datové struktury, tak je něco špatně...

Všude kde člověk pracuje s daty, které nemají (vynucované) schéma, jako třeba XML / XSD / DTD
Schema ale můžeš mít jenom mimo python. Jakmile ta data nahraješ do pythonu, můžeš stčit cokoli kamkoli a žádné schema k dispozici nemáš. Pokud si nenapíšeš objekt, který bude validovat typ při každé operaci s tou strukturou.

, tak bude narážet na problémy stejného druhu. Pokud si uděláš třeba JSON API, nebo connector na microservices v Javě, budeš to muset taky řešit a reagovat na všechno možné, co ti tam kdo posílá chybovými hláškami. Řešením imho není tohle prohlásit za nemožné a zapovězené, ale naučit se, že vyvolání výjimky, když program data neumí zpracovat je prostě součást protokolu komunikace.
Pokud nějaké službě podstrčím nevalidní data, tak je samozřejmě správně, když zareaguje chybovou hláškou, o tom vůbec není řeč, to je v pořádku a jinak to udělat nejde. Při komunikaci zvnějšku to nikdo za zapovězené neprohlašuje, proč by to dělal?!

Jediný problém je v tom, že unittesty z principu nikdy nemůžou otestovat všechno a tímpádem máš vždycky šanci, že to v produkci spadne (což máš i u té Javy, díky mj. null-u).

Vážně? Pro mě je největší bolest Unicode, překlepy se mi od doby co v editoru používám linter (pep8, pyflakes a pylint) prakticky nestávají.
To taky, ale to je návrhová nedostatečnost Pythonu 2 (vzhledem k době vzniku to nebyla chyba). On to nemusí být překlep typu místo "abcde" napíšu "abcd". Může to být třeba to, že omylem použiješ jinou proměnnou/metodu.

Re:Python - dobré rady a praktiky
« Odpověď #93 kdy: 28. 03. 2016, 12:05:34 »
O žádných serverových věcech tazatel nenapsal ani písmeno. To si tam dofantazírovali ostatní zdejší kecálisté a na základě těchto a podobně vykonstruovaných fantasmagorií dospěli k závěru, že Python není vhodný jazyk na větší projekty.
No "větší věc" je skoro vždycky serverová věc. Pokud to není velká desktopová aplikace typu LibreOffice apod., pro kterou by platilo skoro to samý jako pro serverovou aplikaci. Akorát tam pády vadí o trochu míň, protože když to spadne, spadne to jednomu člověku.

Jde o větší projekt? Ano. Je pro něj Python vhodný? Ano. Je tedy pravdivé tvrzení, že se Python k takovým věcem nehodí? Ne.
Q.E.D.
Pro interní projekty, kde se vůbec nic nestane, když to občas spadne, je Python úplně v pohodě. O tom myslím není sporu.

Re:Python - dobré rady a praktiky
« Odpověď #94 kdy: 28. 03. 2016, 12:16:01 »
Toto je chybný přístup, IDE jako PyCharm to nedělá, protože neexistuje praktická potřeba to dělat
To jako že když píšu v Pythonu, tak se nestává, že zjistím, že mi nějaká třída narostla a bylo by fajn ji rozdělit?!

Najít v Pythonu, kde všude se používá první část a kde druhá, je peklo.

, jinak IDE jako PyCharm obsahuje gramatiku jazyka a ve spojení například s debuggerem má všechny předpoklady k tomu, aby si typy zjistilo samo a uložilo například do slovníku, nebo formou anotací do zdrojového textu. Není proto těžké udělat plugin, který by to obstaral včetně vazby na refaktoring.
Ale v Pythonu žádné typy zjistit nejde, protože formálně/striktně žádné neexistují, resp. existuje jich nekonečně mnoho. Pokud mám k dispozici možnost vytvářet úplně libovolné objekty s libovolnými atributy, tak vůbec nejde o gramatiku. Maximálně můžu použít nepovinné/volné typové anotace s tím, že jakmile checker narazí na operaci, kterou neumí rozsoudit (např. json.load), tak je typ neznámý na všech místech, kde ta data použiju, minimálně do první anotace. A i když narazím na první anotaci, bude to zase jenom předpoklad - v produkci to pořád klidně může spadnout.


Ivan Nový

Re:Python - dobré rady a praktiky
« Odpověď #95 kdy: 28. 03. 2016, 12:18:40 »
Zkus si přečíst sekci Hnutí za dobrý kód z http://www.abclinuxu.cz/blog/bystroushaak/2014/7/python-poznamky

Jinak osobně jsem v pythonu dělal na projektu, který měl přes 40k řádek podle CLOC (tzn bez prázdných řádků, komentářů, docstringů a tak). Nebyl s tím vůbec žádný problém, dělali jsme to ve dvou a šlo to v pohodě. Možná za to mohla microservices architektura, ale prostě žádné hroucení na hlavu se nekonalo. Ani co se týče kódu, ani co se týče výkonu, naopak se to krásně škáluje. Umím si představit, že by to stejným způsobem šlo klidně o řád dál bez nějakého stresu.

IDE nebo jiné nástroje pro Python vám při refaktoringu typicky pomohou mnohem méně než kompilátory moderních staticky typovaných jazyků (a nezmění to ani pokročilejší IDE jako PyCharm). IMO udržovat kód v Pythonu je tedy o dost náročnější (na druhé straně to zřejmě kompenzuje dostatek programátorů).

IDE jako PyCharm obsahuje gramatiku jazyka a ve spojení například s debuggerem má všechny předpoklady k tomu, aby si typy zjistilo samo a uložilo například do slovníku, nebo formou anotací do zdrojového textu. Není proto těžké udělat plugin, který by to obstaral včetně vazby na refaktoring.

Udělat takový plugin je prakticky nemožné, neboť typová rekonstrukce i pro jednoduché typové systémy (jako je například System F) je nerozhodnutelná. A pro (rozumné) otypování netriviálních programů v Pythonu potřebujete mnohem složitější typový systém (hádám minimálně na úrovni DOT).
Z teoretického hlediska to možné není, z praktického ano. Stačí zaznamenat jaké typy proměnné nabývají během běhu programu, a to lze. Bude to empirická typová závislost, která bude poskytovat informaci, které typy proměnné nabývají, nevyloučí však, že jiný typ, z méně často používané větve programu, nebo větve nepokryté testy nenabudou.

Což bude posilovat používání proměnných s danými typy, protože tu informaci při rozvíjení systému budete mít po ruce a IDE vám ji bude napovídat. Když narazíte v programu na jiný typ, budete mít možnost rozhodnout, zda je to chyba, či záměr, ale nedostanete se do situace, kdy typ bude naprosto neznámý.

To je základ filosofie dynamických programovacích systémů, rozhodovat se na základě informací, které jsou v daném čase k dispozici, nepočítat se všemi možnými eventualitami, které mohou nastat ale v praxi nastávají občas, nebo vůbec. Co je důležité, určuje pak praxe provádění programu, což se dynamicky mění, chyby se opravují postupně, opravy vylepšují systém, nevznikají z nich nové chyby, protože opravujete jen to, co aktuálně nefunguje a neřešíte, co by možná mohlo nefungovat, což bývá často zdrojem dalších chyb. Systém je programován tak, aby se uměl z chyby sám zotavit, protože se počítá s tím, že nastanou.

U statických jazyků je to naopak, snažíte se navrhnout systém tak, aby zahrnoval všechny možnosti, nemyslíte na zadní kolečka, což vede k ignorování rizika chyby a když chyba nastane, systém rovnou zkolabuje. Jístota, že systém je napsán správně je vyšší, ale zároveň je vyšší jistota, že sytém někdy bez zjevné příčiny zkolabuje díky tomu, že v něm vznikne neočekávaná chyba.
 

Re:Python - dobré rady a praktiky
« Odpověď #96 kdy: 28. 03. 2016, 12:27:41 »
ale nedostanete se do situace, kdy typ bude naprosto neznámý.
Jaký typ má fce json.load?

To je základ filosofie dynamických programovacích systémů, rozhodovat se na základě informací, které jsou v daném čase k dispozici
...přičemž ale "v daném čase" znamená "při běhu v produkci". Čili pokud se při běhu v produkci zjistí, že se někde objevil neočekávaný typ, tak to prostě celé spadne.

Systém je programován tak, aby se uměl z chyby sám zotavit, protože se počítá s tím, že nastanou.
To v pythonu prakticky nejde. Respektive kdybych to chtěl udělat dobře, dostanu se do takové složitosti, že by bylo lepší použít jiný jazyk.

U statických jazyků je to naopak, snažíte se navrhnout systém tak, aby zahrnoval všechny možnosti, nemyslíte na zadní kolečka, což vede k ignorování rizika chyby a když chyba nastane, systém rovnou zkolabuje. Jístota, že systém je napsán správně je vyšší, ale zároveň je vyšší jistota, že sytém někdy bez zjevné příčiny zkolabuje díky tomu, že v něm vznikne neočekávaná chyba.
Co to je za nesmysl?! Počítat se všemi eventualitami právě znamená neignorovat riziko chyby, byť sebemíň pravdpodobné. Statický jazyk mě prostě donutí ošetřit všechny eventuality, jinak se prostě nepřeloží. U Pythonu se můžu rozhodnout, že tohle se nikdy nestane, tak to ošetřovat nebudu - a ejhle, v produkci se zjistí, že to občas nastane :)

Ivan Nový

Re:Python - dobré rady a praktiky
« Odpověď #97 kdy: 28. 03. 2016, 12:35:08 »
Toto je chybný přístup, IDE jako PyCharm to nedělá, protože neexistuje praktická potřeba to dělat
To jako že když píšu v Pythonu, tak se nestává, že zjistím, že mi nějaká třída narostla a bylo by fajn ji rozdělit?!

Najít v Pythonu, kde všude se používá první část a kde druhá, je peklo.

, jinak IDE jako PyCharm obsahuje gramatiku jazyka a ve spojení například s debuggerem má všechny předpoklady k tomu, aby si typy zjistilo samo a uložilo například do slovníku, nebo formou anotací do zdrojového textu. Není proto těžké udělat plugin, který by to obstaral včetně vazby na refaktoring.
Ale v Pythonu žádné typy zjistit nejde, protože formálně/striktně žádné neexistují, resp. existuje jich nekonečně mnoho. Pokud mám k dispozici možnost vytvářet úplně libovolné objekty s libovolnými atributy, tak vůbec nejde o gramatiku. Maximálně můžu použít nepovinné/volné typové anotace s tím, že jakmile checker narazí na operaci, kterou neumí rozsoudit (např. json.load), tak je typ neznámý na všech místech, kde ta data použiju, minimálně do první anotace. A i když narazím na první anotaci, bude to zase jenom předpoklad - v produkci to pořád klidně může spadnout.
Proč by to v produkci nemohlo spadnout, to, že to spadne je jisté u jakéhokoliv jazyka, důležitější je automatické zotavení po chybě, zaznamenání chyby, její příčiny a následně pak možnost zasáhnout do kódu tak, aby to nenarušilo základní filozofii celého systému, aby to nebyl hack, ale přirozené rozšíření.

Klasická chyba, v xml datech místo čísla je číslo ve formě řetězce, nebo naopak, staticky typovaný přístup vede na spadnutí v produkci, dynamicky typovaný projde, protože se provede automatická konverze.

Re:Python - dobré rady a praktiky
« Odpověď #98 kdy: 28. 03. 2016, 12:41:17 »
Klasická chyba, v xml datech místo čísla je číslo ve formě řetězce, nebo naopak, staticky typovaný přístup vede na spadnutí v produkci, dynamicky typovaný projde, protože se provede automatická konverze.
To je naprostý nesmysl. Ve staticky typovaném jazyce buď dojde k načtení struktury, protože je korektní, nebo je vrácena chybová hodnota - viz http://package.elm-lang.org/packages/elm-lang/core/3.0.0/Json-Decode - dekódování vrací Result - tj buď přesně ty typy, které jsem tam chtěl mít, nebo hodnotu (Err "some error message").

V pythonu dojde k automatické konverzi? Odkdy? A jak fce json.load ví, na co má konvertovat, když jí nedávám žádné schéma?

Ivan Nový

Re:Python - dobré rady a praktiky
« Odpověď #99 kdy: 28. 03. 2016, 12:53:10 »
ale nedostanete se do situace, kdy typ bude naprosto neznámý.
Jaký typ má fce json.load?

To je základ filosofie dynamických programovacích systémů, rozhodovat se na základě informací, které jsou v daném čase k dispozici
...přičemž ale "v daném čase" znamená "při běhu v produkci". Čili pokud se při běhu v produkci zjistí, že se někde objevil neočekávaný typ, tak to prostě celé spadne.

Systém je programován tak, aby se uměl z chyby sám zotavit, protože se počítá s tím, že nastanou.
To v pythonu prakticky nejde. Respektive kdybych to chtěl udělat dobře, dostanu se do takové složitosti, že by bylo lepší použít jiný jazyk.

U statických jazyků je to naopak, snažíte se navrhnout systém tak, aby zahrnoval všechny možnosti, nemyslíte na zadní kolečka, což vede k ignorování rizika chyby a když chyba nastane, systém rovnou zkolabuje. Jístota, že systém je napsán správně je vyšší, ale zároveň je vyšší jistota, že sytém někdy bez zjevné příčiny zkolabuje díky tomu, že v něm vznikne neočekávaná chyba.
Co to je za nesmysl?! Počítat se všemi eventualitami právě znamená neignorovat riziko chyby, byť sebemíň pravdpodobné. Statický jazyk mě prostě donutí ošetřit všechny eventuality, jinak se prostě nepřeloží. U Pythonu se můžu rozhodnout, že tohle se nikdy nestane, tak to ošetřovat nebudu - a ejhle, v produkci se zjistí, že to občas nastane :)

jaký typ máfunkce json.load? Má typ struktury nejčastěji načítaných dat. Tady můžete specifikovat pravidla, které to nějakým způsobem redukují. Takže rozpoznáte, zda jde o nehomogenní data, o kterých je dáno, že mají povahu nějakého slovníku, nebo jde o konkrétní strukturu, která se stále opakuje. data získáte během ladění a provádění jednotkových testů a zaznamená je a zpracuje IDE, následně pak použije k nápovědě.

Monitorovat riziko chyby je nesmysl,  lépe je připravit systém na to, že chyba nastane, tedy definovat co nesmí nastat a připravit se na to, když to nastane. To je filozofie dynamických systémů. Kde to není možno aplikovat, tam použijete nějaký statický a automaticky verifikovaný systém, ale těch oblastí je jen velmi málo.

Prezentovat věc, že v produkci chyby nenastanou je lakování reality na růžovo, lepší je mít připravený postup, co dělat, když nastanou. Například opakovat výpočet, chybu ignorovat, doplnit náhradním pravděpodobným výsledkem, spustit nějakou havarijní činnost a podobně.


Re:Python - dobré rady a praktiky
« Odpověď #100 kdy: 28. 03. 2016, 13:00:13 »
jaký typ máfunkce json.load? Má typ struktury nejčastěji načítaných dat. Tady můžete specifikovat pravidla, které to nějakým způsobem redukují. Takže rozpoznáte, zda jde o nehomogenní data, o kterých je dáno, že mají povahu nějakého slovníku, nebo jde o konkrétní strukturu, která se stále opakuje. data získáte během ladění a provádění jednotkových testů a zaznamená je a zpracuje IDE, následně pak použije k nápovědě.
Proč zase mateš pojmy?! Prostě json.load žádný typ NEMÁ. Struktura dat, které vrací, je NEZNÁMÁ a NIJAK se nekontroluje, protože se ji NEPŘEDÁVÁ žádné schema.

Hele, já mám Python rád, je to jazyk, který používám jako druhý nejčastější, a myslím, že na některé věci (výuka, jednodušší aplikace) je naprosto skvělý a jsem rád, že se tak rozšířil, ale tyhle lži mu dělají fakt medvědí službu.

Monitorovat riziko chyby je nesmysl,  lépe je připravit systém na to, že chyba nastane, tedy definovat co nesmí nastat a připravit se na to, když to nastane.
Ano, to je filosofie Erlangu. Python pro to ale narozdíl od něj nemá prostředky. Nemá (jednoduše použitelné) procesy, supervisory, monitorování a provázání procesů, neumí restartovat část aplikace po selhání. Čili tohle by šlo, ale NEDĚJE se to. Existují snahy jako např Pykka, ale oproti Akka jí chybí některé zásadní věci, takže je to stejně nepoužitelné.

Ivan Nový

Re:Python - dobré rady a praktiky
« Odpověď #101 kdy: 28. 03. 2016, 13:04:50 »
Klasická chyba, v xml datech místo čísla je číslo ve formě řetězce, nebo naopak, staticky typovaný přístup vede na spadnutí v produkci, dynamicky typovaný projde, protože se provede automatická konverze.
To je naprostý nesmysl. Ve staticky typovaném jazyce buď dojde k načtení struktury, protože je korektní, nebo je vrácena chybová hodnota - viz http://package.elm-lang.org/packages/elm-lang/core/3.0.0/Json-Decode - dekódování vrací Result - tj buď přesně ty typy, které jsem tam chtěl mít, nebo hodnotu (Err "some error message").

V pythonu dojde k automatické konverzi? Odkdy? A jak fce json.load ví, na co má konvertovat, když jí nedávám žádné schéma?

Když jednou v xml máte EAN zboží "1231238901560" a jindy od jiného dodavatele ve stejném formátu 1231238901560, tak to chyba v datech není. To jaké typy datům přiřadíte je vnitřní abstrakce programu, a ta by měla být podřízena vnější realitě, takže když program vyhodí chybu, tak to sice není špatně, alespoň se o té chybě ví, ale požadovaná činnost v realitě vlastně neproběhla  a událost je hodnocena jako havárie. Takže program nemá skončit s chybou, ale buď provést automatickou konverzi a nebo danou větu vyřadit ze zpracování, ostatních datových vět se to týkat nemá.

Re:Python - dobré rady a praktiky
« Odpověď #102 kdy: 28. 03. 2016, 13:08:55 »
Když jednou v xml máte EAN zboží "1231238901560" a jindy od jiného dodavatele ve stejném formátu 1231238901560, tak to chyba v datech není. To jaké typy datům přiřadíte je vnitřní abstrakce programu, a ta by měla být podřízena vnější realitě, takže když program vyhodí chybu, tak to sice není špatně, alespoň se o té chybě ví, ale požadovaná činnost v realitě vlastně neproběhla  a událost je hodnocena jako havárie. Takže program nemá skončit s chybou, ale buď provést automatickou konverzi a nebo danou větu vyřadit ze zpracování, ostatních datových vět se to týkat nemá.
Pokud někde chci mít možnost stringu nebo intu, tak ten typ je "string nebo int" a pokud chci, dál si to převedu na jeden z nich. Přesně takhle se to třeba v tom Elmu dělá - viz Decode.oneOf.

Opakuju: jak dělá Python "automatickou konverzi"? Nijak. Nedělá ji. Je to další lež. Pokud chci konverzi, musím si ji tam napsat - tj. projít celou strukturu, ocheckovat všechny typy, převést některé na jiné. Čili úplně přesně totéž jako v tom Elmu, akorát to musím dělat ručně.

Sorry, už mě ta snůška polopravd a lží nebaví, končím.

Ondrej

Re:Python - dobré rady a praktiky
« Odpověď #103 kdy: 28. 03. 2016, 13:27:03 »
Hele, já mám Python rád, je to jazyk, který používám jako druhý nejčastější, a myslím, že na některé věci (výuka, jednodušší aplikace) je naprosto skvělý a jsem rád, že se tak rozšířil, ale tyhle lži mu dělají fakt medvědí službu.
Jo proto ho používá Dropbox, Google, Reddit, Bitbucket, Pinterest a mohl bych pokračovat... Určitě ho maj jen na výuku a jednodušší aplikace :-)

Re:Python - dobré rady a praktiky
« Odpověď #104 kdy: 28. 03. 2016, 13:34:34 »
Jo proto ho používá Dropbox, Google, Reddit, Bitbucket, Pinterest a mohl bych pokračovat... Určitě ho maj jen na výuku a jednodušší aplikace :-)
Pokud má někdo k dispozici stejné prostředky jako Dropbox nebo Google, tak určitě může Python zvažovat :)

Tenhle argument fakt nesnáším. Že je velká firma schopná něco uchodit neznamená, že to samé zvládne nějaká malá česká firma stejně dobře a že je to pro ni stejně dobrá volba.