{"id":38649,"date":"2019-10-31T22:25:04","date_gmt":"2019-10-31T19:25:04","guid":{"rendered":"https:\/\/prohoster.info\/blog\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\/"},"modified":"2019-10-31T22:25:04","modified_gmt":"2019-10-31T19:25:04","slug":"put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ju paraqesim pjes\u00ebn e tret\u00eb t\u00eb p\u00ebrkthimit t\u00eb materialit p\u00ebr rrug\u00ebn q\u00eb p\u00ebrshkoi Dropbox gjat\u00eb \u0432\u043d\u0435\u0434imit t\u00eb sistemit t\u00eb kontrollit t\u00eb tipeve p\u00ebr kodin Python.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Pjes\u00ebt e m\u00ebparshme: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">e para<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">Dyt\u00eb<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Arritja e 4 milion\u00eb rreshtave t\u00eb kodit t\u00eb tipizuar<\/h2>\n<p>\nNj\u00eb tjet\u00ebr detyr\u00eb e r\u00ebnd\u00ebsishme (kjo ishte problemi i dyt\u00eb m\u00eb i p\u00ebrmendur nga ata q\u00eb mor\u00ebn pjes\u00eb n\u00eb anketat e brendshme) ishte rritja e volumit t\u00eb kodit n\u00eb Dropbox t\u00eb mbuluar nga kontrolli i tipeve. Provam disa qasje p\u00ebr ta zgjidhur k\u00ebt\u00eb detyr\u00eb \u2014 nga rritja natyrore e baz\u00ebs s\u00eb kodit t\u00eb tipizuar deri te p\u00ebrqendrimi i p\u00ebrpjekjeve t\u00eb ekipit mypy n\u00eb nxjerrjen e automatizuar statike dhe dinamike t\u00eb tipeve. N\u00eb fund, u krijua p\u00ebrshtypja se k\u00ebtu nuk ka nj\u00eb strategji t\u00eb thjesht\u00eb fituese, por arrit\u00ebm t\u00eb siguronim rritje t\u00eb shpejt\u00eb t\u00eb v\u00ebllimit t\u00eb kodit t\u00eb anotuar duke kombinuar shum\u00eb qasje.<\/p>\n<p>Si rezultat, n\u00eb repository-n ton\u00eb m\u00eb t\u00eb madh Python (me kodin backend), numri i rreshtave t\u00eb kodit t\u00eb anotuar arriti pothuajse n\u00eb 4 milion\u00eb. Puna p\u00ebr tipizimin statik t\u00eb kodit u krye p\u00ebr rreth tre vjet. Mypy tani mb\u00ebshtet lloje t\u00eb ndryshme raportesh p\u00ebr mbulimin e kodit me tipe, t\u00eb cilat e b\u00ebjn\u00eb m\u00eb t\u00eb leht\u00eb ndjekjen e ecuris\u00eb s\u00eb tipizimit. N\u00eb ve\u00e7anti, ne mund t\u00eb gjenerojm\u00eb raporte p\u00ebr kodin me paqart\u00ebsi tipesh, si p\u00ebr shembull p\u00ebrdorimi i drejtp\u00ebrdrejt\u00eb i tipit <code>Any<\/code> n\u00eb anotime q\u00eb nuk mund t\u00eb verifikohen, ose raste si importimi i bibliotekave t\u00eb pal\u00ebve t\u00eb treta q\u00eb nuk kan\u00eb anotime tipesh. N\u00eb kuad\u00ebr t\u00eb projektit p\u00ebr rritjen e sakt\u00ebsis\u00eb s\u00eb kontrollit t\u00eb tipeve n\u00eb Dropbox, ne kemi kontribuar n\u00eb p\u00ebrmir\u00ebsimin e p\u00ebrkufizimeve t\u00eb tipeve (t\u00eb ashtuquajturat skedar\u00eb stub) p\u00ebr disa biblioteka t\u00eb njohura open source n\u00eb repository-n e centralizuar Python <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Ne kemi zbatuar (dhe standardizuar m\u00eb pas n\u00eb PEP) mund\u00ebsi t\u00eb reja t\u00eb sistemit t\u00eb tipeve, t\u00eb cilat lejojn\u00eb p\u00ebrdorimin e tipeve m\u00eb t\u00eb sakta p\u00ebr disa modele specifike t\u00eb Python. Nj\u00eb shembull i duksh\u00ebm i k\u00ebsaj \u00ebsht\u00eb <code>TypeDict<\/code>, i cili ofron tipe p\u00ebr fjalor\u00eb t\u00eb ngjash\u00ebm me JSON me nj\u00eb grup fiks \u00e7el\u00ebsash vargjesh, ku secili ka vler\u00eb t\u00eb tipit t\u00eb vet. Ne do t\u00eb vazhdojm\u00eb ta zgjerojm\u00eb sistemin e tipeve. Ka shum\u00eb gjasa q\u00eb hapi yn\u00eb i ardhsh\u00ebm t\u00eb jet\u00eb p\u00ebrmir\u00ebsimi i mb\u00ebshtetjes p\u00ebr mund\u00ebsit\u00eb e Python p\u00ebr pun\u00ebn me numrat.<\/p>\n<p><img decoding=\"async\" alt=\"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Numri i rreshtave t\u00eb kodit t\u00eb anotuar: server<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Numri i rreshtave t\u00eb kodit t\u00eb anotuar: klienti<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Numri total i rreshtave t\u00eb kodit t\u00eb anotuar<\/i><\/p>\n<p>Ja nj\u00eb p\u00ebrmbledhje e ve\u00e7orive kryesore t\u00eb masave q\u00eb nd\u00ebrmor\u00ebm p\u00ebr t\u00eb rritur v\u00ebllimin e kodit t\u00eb anotuar n\u00eb Dropbox:<\/p>\n<p>Rigoroziteti i anotimit. Ne i rrit\u00ebm gradualisht k\u00ebrkesat p\u00ebr rigorozitetin e anotimit t\u00eb kodit t\u00eb ri. Filluam me sugjerime nga linter-i, t\u00eb cilat rekomandonin shtimin e anotimeve n\u00eb skedar\u00ebt ku tashm\u00eb kishte disa anotime. Tani k\u00ebrkojm\u00eb pranin\u00eb e anotimeve t\u00eb tipeve n\u00eb skedar\u00ebt e rinj Python dhe n\u00eb shumic\u00ebn e skedar\u00ebve ekzistues.<\/p>\n<p>Raportet e tipizimit. \u00c7do jav\u00eb u d\u00ebrgojm\u00eb ekipeve raporte mbi nivelin e tipizimit t\u00eb kodit t\u00eb tyre dhe u japim k\u00ebshilla se \u00e7far\u00eb duhet anotuar s\u00eb pari.<\/p>\n<p>Popullarizimi i mypy. Ne flasim p\u00ebr mypy n\u00eb evente t\u00eb ndryshme dhe bashk\u00ebpunojm\u00eb me ekipet, duke i ndihmuar t\u00eb fillojn\u00eb t\u00eb p\u00ebrdorin anotimet e tipeve.<\/p>\n<p>Anketat. Ne zhvillojm\u00eb anketa periodike me p\u00ebrdoruesit p\u00ebr t\u00eb identifikuar problemet kryesore. Jemi t\u00eb gatsh\u00ebm t\u00eb shkojm\u00eb mjaft larg p\u00ebr t\u2019i zgjidhur k\u00ebto probleme (madje deri te krijimi i nj\u00eb gjuhe t\u00eb re p\u00ebr t\u00eb p\u00ebrshpejtuar mypy!).<\/p>\n<p>Performanca. Ne e kemi p\u00ebrmir\u00ebsuar ndjesh\u00ebm performanc\u00ebn e mypy fal\u00eb p\u00ebrdorimit t\u00eb daemon-it dhe mypyc. Kjo u b\u00eb p\u00ebr t\u00eb zbutur v\u00ebshtir\u00ebsit\u00eb q\u00eb lindin gjat\u00eb procesit t\u00eb anotimit dhe p\u00ebr t\u00eb b\u00ebr\u00eb t\u00eb mundur pun\u00ebn me v\u00ebllime t\u00eb m\u00ebdha kodi.<\/p>\n<p>Integrimi me editor\u00ebt. Krijuam mjete p\u00ebr t\u00eb mb\u00ebshtetur ekzekutimin e mypy n\u00eb editor\u00ebt q\u00eb p\u00ebrdoren gjer\u00ebsisht n\u00eb Dropbox. K\u00ebtu p\u00ebrfshihen PyCharm, Vim dhe VS Code. Kjo e thjeshtoi ndjesh\u00ebm procesin e anotimit t\u00eb kodit dhe t\u00eb verifikimit t\u00eb funksionimit t\u00eb tij. Veprime t\u00eb tilla jan\u00eb zakonisht tipike gjat\u00eb anotimit t\u00eb kodit ekzistues.<\/p>\n<p>Analiza statike. Krijuam nj\u00eb mjet p\u00ebr nxjerrjen e signaturave t\u00eb funksioneve duke p\u00ebrdorur mekanizma t\u00eb analiz\u00ebs statike. Ky mjet mund t\u00eb funksionoj\u00eb vet\u00ebm n\u00eb situata relativisht t\u00eb thjeshta, por na ndihmoi t\u00eb rrisim mbulimin e kodit me tipe pa shum\u00eb p\u00ebrpjekje.<\/p>\n<p>Mb\u00ebshtetja p\u00ebr bibliotekat e pal\u00ebve t\u00eb treta. N\u00eb shum\u00eb prej projekteve tona p\u00ebrdoret paketa e mjeteve SQLAlchemy. Ajo shfryt\u00ebzon ve\u00e7ori dinamike t\u00eb Python q\u00eb tipet PEP 484 nuk mund t\u2019i modelojn\u00eb drejtp\u00ebrdrejt. N\u00eb p\u00ebrputhje me PEP 561, ne krijuam stub-file p\u00ebrkat\u00ebs dhe shkruam nj\u00eb plugin p\u00ebr mypy (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">me burim t\u00eb hapur<\/a><\/noindex>), q\u00eb p\u00ebrmir\u00ebson mb\u00ebshtetjen p\u00ebr SQLAlchemy.<\/p>\n<h2>V\u00ebshtir\u00ebsit\u00eb me t\u00eb cilat u p\u00ebrball\u00ebm<\/h2>\n<p>\nRruga drejt 4 milion\u00eb rreshtave kodi t\u00eb tipizuar nuk ka qen\u00eb gjithmon\u00eb e leht\u00eb p\u00ebr ne. Gjat\u00eb k\u00ebsaj rruge has\u00ebm jo pak pengesa dhe b\u00ebm\u00eb disa gabime. Ja disa nga problemet me t\u00eb cilat u p\u00ebrball\u00ebm. Shpresojm\u00eb q\u00eb p\u00ebrshkrimi i tyre t\u2019i ndihmoj\u00eb t\u00eb tjer\u00ebt t\u2019i shmangin probleme t\u00eb ngjashme.<\/p>\n<p>Skedar\u00eb t\u00eb anashkaluar. N\u00eb fillim kontrollonim vet\u00ebm nj\u00eb num\u00ebr t\u00eb vog\u00ebl skedar\u00ebsh. Gjith\u00e7ka q\u00eb nuk b\u00ebnte pjes\u00eb n\u00eb k\u00ebt\u00eb grup skedar\u00ebsh nuk kontrollohej. Skedar\u00ebt shtoheshin n\u00eb list\u00ebn e kontrollit kur n\u00eb to shfaqeshin anotimet e para. N\u00ebse di\u00e7ka importohej nga nj\u00eb modul q\u00eb ndodhej jasht\u00eb fush\u00ebs s\u00eb kontrollit, at\u00ebher\u00eb b\u00ebhej fjal\u00eb p\u00ebr pun\u00eb me vlera t\u00eb tipit <code>Any<\/code>, t\u00eb cilat nuk kontrolloheshin fare. Kjo solli nj\u00eb humbje t\u00eb konsiderueshme t\u00eb sakt\u00ebsis\u00eb s\u00eb tipizimit, ve\u00e7an\u00ebrisht n\u00eb fazat e hershme t\u00eb migrimit. Ky qasje vazhdoi t\u00eb funksiononte \u00e7udit\u00ebrisht mir\u00eb, megjith\u00ebse ishte tipike q\u00eb shtimi i skedar\u00ebve n\u00eb fush\u00ebn e kontrollit t\u00eb zbulonte probleme n\u00eb pjes\u00eb t\u00eb tjera t\u00eb baz\u00ebs s\u00eb kodit. N\u00eb rastin m\u00eb t\u00eb keq, kur bashkoheshin dy zona t\u00eb izoluara t\u00eb kodit ku tipet, n\u00eb m\u00ebnyr\u00eb t\u00eb pavarur, ishin kontrolluar tashm\u00eb, rezultonte se tipet e k\u00ebtyre zonave nuk ishin t\u00eb p\u00ebrputhshme me nj\u00ebra-tjetr\u00ebn. Kjo sillte nevoj\u00ebn p\u00ebr t\u00eb b\u00ebr\u00eb shum\u00eb ndryshime n\u00eb anotime. Tani, duke par\u00eb pas, e kuptojm\u00eb se duhej t\u2019i kishim p\u00ebrfshir\u00eb sa m\u00eb her\u00ebt modulet baz\u00eb t\u00eb bibliotek\u00ebs n\u00eb fush\u00ebn e kontrollit t\u00eb tipeve t\u00eb mypy. Kjo do ta kishte b\u00ebr\u00eb pun\u00ebn ton\u00eb shum\u00eb m\u00eb t\u00eb parashikueshme.<\/p>\n<p>Anotimi i kodit t\u00eb vjet\u00ebr. Kur e nis\u00ebm pun\u00ebn, kishim rreth 4 milion\u00eb rreshta kod Python ekzistues. Ishte e qart\u00eb se anotimi i gjith\u00eb k\u00ebtij kodi nuk ishte aspak i leht\u00eb. Krijuam nj\u00eb mjet t\u00eb quajtur PyAnnotate, i cili mund t\u00eb mbledh\u00eb informacion p\u00ebr tipet gjat\u00eb ekzekutimit t\u00eb testeve dhe t\u00eb shtoj\u00eb n\u00eb kod anotime tipesh bazuar n\u00eb t\u00eb dh\u00ebnat e mbledhura. Megjithat\u00eb, nuk vum\u00eb re p\u00ebrdorim ve\u00e7an\u00ebrisht t\u00eb gjer\u00eb t\u00eb k\u00ebtij mjeti. Mbledhja e informacionit p\u00ebr tipet ishte e ngadalt\u00eb dhe anotimet e gjeneruara automatikisht shpesh k\u00ebrkonin shum\u00eb korrigjime manuale. Mendonim ta ekzekutonim automatikisht k\u00ebt\u00eb mjet n\u00eb \u00e7do kontroll t\u00eb kodit, ose t\u00eb mblidhnim informacion p\u00ebr tipet mbi baz\u00ebn e analiz\u00ebs s\u00eb nj\u00eb sasie t\u00eb vog\u00ebl k\u00ebrkesash reale t\u00eb rrjetit, por vendos\u00ebm t\u00eb mos e b\u00ebnim, sepse secila prej k\u00ebtyre qasjeve ishte tep\u00ebr e rrezikshme.<\/p>\n<p>N\u00eb fund, mund t\u00eb thuhet se pjesa m\u00eb e madhe e kodit u anotua manualisht nga pronar\u00ebt e tij. P\u00ebr ta orientuar k\u00ebt\u00eb proces n\u00eb drejtimin e duhur, ne p\u00ebrgatisim raporte p\u00ebr modulet dhe funksionet m\u00eb t\u00eb r\u00ebnd\u00ebsishme q\u00eb duhen anotuar. P\u00ebr shembull, \u00ebsht\u00eb e r\u00ebnd\u00ebsishme t\u00eb pajiset me anotime tipesh nj\u00eb modul biblioteke q\u00eb p\u00ebrdoret n\u00eb qindra vende. Nd\u00ebrsa nj\u00eb sh\u00ebrbim i vjet\u00ebr, q\u00eb po z\u00ebvend\u00ebsohet me nj\u00eb t\u00eb ri, nuk \u00ebsht\u00eb m\u00eb aq i r\u00ebnd\u00ebsish\u00ebm p\u00ebr t\u2019u anotuar. P\u00ebrve\u00e7 k\u00ebsaj, po eksperimentojm\u00eb me p\u00ebrdorimin e analiz\u00ebs statike p\u00ebr t\u00eb gjeneruar anotime tipesh p\u00ebr kodin e vjet\u00ebr.<\/p>\n<p>Importet ciklike. M\u00eb sip\u00ebr fola p\u00ebr importet ciklike (p\u00ebr \u201cnyjat e var\u00ebsive\u201d), ekzistenca e t\u00eb cilave e v\u00ebshtir\u00ebsoi p\u00ebrshpejtimin e mypy. P\u00ebrve\u00e7 k\u00ebsaj, na u desh t\u00eb punonim seriozisht q\u00eb ta pajisnim mypy me mb\u00ebshtetje p\u00ebr t\u00eb gjitha llojet e idiomave q\u00eb lindin pik\u00ebrisht nga k\u00ebto importe ciklike. S\u00eb fundmi p\u00ebrfunduam nj\u00eb projekt t\u00eb madh ridizajnimi t\u00eb sistemit, i cili zgjidhi shumic\u00ebn e problemeve t\u00eb mypy q\u00eb lidhen me importet ciklike. N\u00eb fakt, k\u00ebto probleme i kan\u00eb rr\u00ebnj\u00ebt q\u00eb n\u00eb dit\u00ebt shum\u00eb t\u00eb hershme t\u00eb projektit, madje q\u00eb nga Alore, gjuha m\u00ebsimore p\u00ebr t\u00eb cil\u00ebn projekti mypy ishte orientuar fillimisht. Sintaksa e Alore lejon zgjidhjen e leht\u00eb t\u00eb problemeve me komandat ciklike t\u00eb importit. mypy modern ka trash\u00ebguar disa kufizime nga implementimi i tij i hersh\u00ebm dhe i thjesht\u00eb (i cili i p\u00ebrshtatej shum\u00eb mir\u00eb Alore). Python e nd\u00ebrlikon pun\u00ebn me importet ciklike kryesisht p\u00ebr shkak t\u00eb paqart\u00ebsis\u00eb s\u00eb shprehjeve. P\u00ebr shembull, gjat\u00eb nj\u00eb veprimi caktimi vlere mund t\u00eb p\u00ebrkufizohet n\u00eb t\u00eb v\u00ebrtet\u00eb nj\u00eb pseudonim tipi. Mypy nuk \u00ebsht\u00eb gjithmon\u00eb n\u00eb gjendje t\u2019i zbuloj\u00eb gj\u00ebra t\u00eb tilla derisa t\u00eb jet\u00eb p\u00ebrpunuar pjesa m\u00eb e madhe e ciklit t\u00eb importit. N\u00eb Alore nuk kishte paqart\u00ebsi t\u00eb tilla. Vendimet e pasuksesshme t\u00eb marra n\u00eb fazat e hershme t\u00eb zhvillimit t\u00eb sistemit mund t\u2019i sjellin programuesit surpriza t\u00eb pak\u00ebndshme edhe shum\u00eb vite m\u00eb von\u00eb.<\/p>\n<h2>P\u00ebrfundime: rruga drejt 5 milion\u00eb rreshtave kodi dhe horizonteve t\u00eb reja<\/h2>\n<p>\nProjekti mypy ka b\u00ebr\u00eb nj\u00eb rrug\u00eb t\u00eb gjat\u00eb \u2014 nga prototipet e hershme deri te nj\u00eb sistem me t\u00eb cilin kontrollohen tipet n\u00eb kod prodhimi me v\u00ebllim prej 4 milion\u00eb rreshtash. Gjat\u00eb zhvillimit t\u00eb mypy u standardizuan edhe type hints n\u00eb Python. Sot, rreth tipizimit t\u00eb kodit Python \u00ebsht\u00eb zhvilluar nj\u00eb ekosistem i fuqish\u00ebm. Ajo p\u00ebrfshin mb\u00ebshtetje p\u00ebr biblioteka, mjete ndihm\u00ebse p\u00ebr IDE dhe editor\u00eb, si edhe disa sisteme kontrolli tipesh, secili me avantazhet dhe mang\u00ebsit\u00eb e veta.<\/p>\n<p>Edhe pse kontrolli i tipeve tashm\u00eb perceptohet n\u00eb Dropbox si di\u00e7ka krejt e natyrshme, jam i bindur se ne ende jetojm\u00eb n\u00eb agimin e tipizimit t\u00eb kodit Python. Mendoj se teknologjit\u00eb e kontrollit t\u00eb tipeve do t\u00eb vazhdojn\u00eb t\u00eb zhvillohen dhe t\u00eb p\u00ebrmir\u00ebsohen.<\/p>\n<p>N\u00ebse ende nuk keni p\u00ebrdorur kontrollin e tipeve n\u00eb projektin tuaj Python n\u00eb shkall\u00eb t\u00eb gjer\u00eb, dijeni se tani \u00ebsht\u00eb nj\u00eb moment shum\u00eb i p\u00ebrshtatsh\u00ebm p\u00ebr t\u00eb nisur kalimin drejt tipizimit statik. Kam biseduar me ata q\u00eb e kan\u00eb b\u00ebr\u00eb k\u00ebt\u00eb kalim. Asnj\u00ebri prej tyre nuk \u00ebsht\u00eb penduar. Kontrolli i tipeve e shnd\u00ebrron Python-in n\u00eb nj\u00eb gjuh\u00eb q\u00eb \u00ebsht\u00eb shum\u00eb m\u00eb e p\u00ebrshtatshme se \u00abPython-i i zakonsh\u00ebm\u00bb p\u00ebr zhvillimin e projekteve t\u00eb m\u00ebdha.<\/p>\n<p><b>T\u00eb nderuar lexues!<\/b> A p\u00ebrdorni kontrollin e tipeve n\u00eb projektet tuaja Python?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/bf2bc557ce4481dd87398515bff60e3f.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"Rruga p\u00ebr verifikimin e tipeve t\u00eb 4 milion rreshtave t\u00eb kodit Python. Pjesa 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430. \u2192 \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438: \u043f\u0435\u0440\u0432\u0430\u044f \u0438 \u0432\u0442\u043e\u0440\u0430\u044f \u0414\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0415\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0432\u0430\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 (\u044d\u0442\u043e \u0431\u044b\u043b \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0432\u043e\u043b\u043d\u043e\u0432\u0430\u0432\u0448\u0430\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043e\u043f\u0440\u043e\u0441\u0430\u0445) \u0431\u044b\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0451\u043c\u0430 \u043a\u043e\u0434\u0430 \u0432 Dropbox, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 3 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:25:04+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:25:04+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Rruga drejt kontrollit t\u00eb tipeve p\u00ebr 4 milion\u00eb rreshta kodi Python. Pjesa 3 | ProHoster","description":"Ju paraqesim pjes\u00ebn e tret\u00eb t\u00eb p\u00ebrkthimit t\u00eb materialit p\u00ebr rrug\u00ebn q\u00eb p\u00ebrshkoi Dropbox gjat\u00eb \u0432\u043d\u0435\u0434imit t\u00eb sistemit t\u00eb kontrollit t\u00eb tipeve p\u00ebr kodin Python.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 3 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:25:04+00:00","article:modified_time":"2019-10-31T19:25:04+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38649","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 22:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:05:23","updated":"2026-08-11 12:50:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}