abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 14:55 | Zajímavý článek

Nová čísla časopisů od nakladatelství Raspberry Pi: MagPi 81 (pdf), HackSpace 18 (pdf), Hello World 8 (pdf) a Wireframe 11 (pdf) a 12 (pdf).

Ladislav Hagara | Komentářů: 0
dnes 01:22 | Nová verze

Po více než 4 měsících vývoje od vydání verze 15 byla vydána nová stabilní verze 16 open source systému Nextcloud (Wikipedie), forku ownCloudu, umožňujícího provoz vlastního cloudového úložiště. Přehled novinek i s náhledy v příspěvku na blogu. Pro vyzkoušení Nextcloudu je k dispozici demo (aktuálně verze 15).

Ladislav Hagara | Komentářů: 0
dnes 01:00 | Nová verze

Node.js Foundation, oficiální projekt konsorcia Linux Foundation, oznámila vydání verze 12.0.0 (Current) otevřeného multiplatformního prostředí pro vývoj a běh síťových aplikací napsaných v JavaScriptu Node.js (Wikipedie). Přehled novinek v článku na Medium. Verze 12 se v říjnu stane novou aktivní LTS verzí. Podpora je plánována do dubna 2022.

Ladislav Hagara | Komentářů: 1
dnes 00:44 | Nová verze

Byla vydána verze 11.10 open source alternativy GitHubu, tj. softwarového nástroje s webovým rozhraním umožňujícího spolupráci na zdrojových kódech, GitLab (Wikipedie). Představení nových vlastností i s náhledy v příspěvku na blogu.

Ladislav Hagara | Komentářů: 0
dnes 00:11 | IT novinky

OpenAI, nezisková organizace pro výzkum umělé inteligence (AI), představila projekt MuseNet. Jedná se o hlubokou neuronovou síť, která dokáže generovat čtyřminutové hudební skladby s 10 různými nástroji a kombinovat styly od country přes Mozarta až po Beatles.

Ladislav Hagara | Komentářů: 5
včera 16:00 | Pozvánky

Spolek OpenAlt zve příznivce otevřených řešení a přístupu na 163. brněnský sraz, který proběhne v pátek 26. dubna od 18:00 v indické restauraci Everest na adrese Veveří 61.

Ladislav Hagara | Komentářů: 5
včera 15:33 | IT novinky

Všem dívkám v ICT vše nejlepší k dnešnímu Mezinárodnímu dni dívek v ICT (Wikipedie, Girls in ICT Day, YouTube).

Ladislav Hagara | Komentářů: 8
včera 12:22 | Nová verze

Byla vydána verze 1.12 systému pro správu a verzování zdrojových kódů Apache Subversion (Wikipedie). Přehled novinek v poznámkách k vydání.

Ladislav Hagara | Komentářů: 11
včera 12:11 | Zajímavý článek

Mozilla zveřejnila každoroční Internet Health Report, který popisuje aktuální společenská témata související s využíváním Internetu. Tentokrát se dotýkají mj. etiky algoritmů strojového učení, cílené reklamy a „chytrých měst“.

Fluttershy, yay! | Komentářů: 2
včera 08:44 | Nová verze

Webová aplikace pro správu repozitářů v gitu Gitea vyšla v nové verzi 1.8.0. Nově poskytuje OAuth 2.0, umožňuje archivaci repozitářů, skrývání organizací jako interních či soukromých, zamykání konverzací a mnoho dílčích změn.

Fluttershy, yay! | Komentářů: 6
Používáte headset pro virtuální realitu?
 (1%)
 (3%)
 (2%)
 (18%)
 (1%)
 (75%)
Celkem 241 hlasů
 Komentářů: 12, poslední 18.4. 01:19
Rozcestník

Prohození řádků v Pythonu a Perlu

2.2. 13:38 | Přečteno: 1349× | Programování | poslední úprava: 2.2. 18:05

Skript načítá ze standardního vstupu a vypisuje na standardní výstup. Argumenty na příkazové řádce jsou ve tvaru 0-5 1-4 2-3 a udávají čísla řádků, které se mají prohodit.

Python

import re, sys

lines = []

for line in sys.stdin:
    lines.append(line.rstrip())        

p = re.compile('(\d+)-(\d+)')
for arg in sys.argv[1:]:
    m = p.match(arg)
    if m:    
        a, b = int(m.group(1)), int(m.group(2))
        lines[a], lines[b] = lines[b], lines[a] 

for line in lines: print(line)
Skript spustíme v terminálu příkazem

python3 swaplines.py 0-5 1-4 2-3 < old > new

První cyklus for načítá řádky a ukládá je do listu (pole). Druhý cyklus for používá slice sys.argv[1:], jelikož sys.argv[0] obsahuje název samotného skriptu (swaplines.py) a ten nepotřebujeme. Jednotlivé argumenty porovnáváme s regulérním výrazem (\d+)-(\d+). Závorky značí části řetězce, jejichž hodnoty vrací metoda group. V případě, že by byl argument na příkazové řádce 0-5, group(1) vrací řetězec 0, group(2) vrací řetězec 5 a group(0) vrací řetězec 0-5. Abychom mohli tyto hodnoty použít jako indexy, musíme je z řetězců převést na číselný typ pomocí funkce int(). Poté již stačí použít několikanásobné přiřazení k prohození prvků.

lines[a], lines[b] = lines[b], lines[a]

Perl

@lines = ();

while (<STDIN>) {
    push(@lines, $_);
}
foreach (@ARGV) {
    if ($_ =~ /(\d+)-(\d+)/) {    
        ($lines[$1], $lines[$2]) = ($lines[$2], $lines[$1]);
    }
}
foreach (@lines) { print $_; }
Toto je v principu ten samý skript, pouze se liší v několika detailech. V Perlu $ARGV[0] není název skriptu, ten bychom našli v $0, ale $ARGV[0] obsahuje první argument na příkazové řádce (takže třeba 0-5). Proměnné $1, $2 atd. zpřístupňují závorkované podřetězce v regexu a na rozdíl od Pythonu je můžeme použít jako indexy, aniž bychom je museli převádět na int. Perl totiž převody proměnných dělá za nás. Proměnná $_ ve smyčce while (<STDIN>) symbolizuje řádek načtený ze vstupu a v cyklu foreach symbolizuje prvek pole, v některých případech lze $_ vynechat. Perl navíc umožňuje vynechat i závorky u funkcí ze standardní knihovny.

Výpis řádků můžeme napsat i delší formou:

foreach $line (@lines) { print($line); }

Nebo naopak je možné samotný skript ještě více zkrátit vynecháním $_ a použitím jednořádkového if a while.
@l = ();
push(@l, $_) while <STDIN>;
foreach (@ARGV) {
    ($l[$1], $l[$2]) = ($l[$2], $l[$1]) if /(\d+)-(\d+)/;    
}
foreach (@l) { print; }
Nicméně tento styl je už celkem špatně čitelný.

Perl se teprve učím, ale řekl bych, že na krátké skripty je to velice efektivní nástroj.

Aktualizace: V diskuzi jsou poznámky, jak skripty napsat ještě lépe.        

Hodnocení: 67 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

xkucf03 avatar 2.2. 16:13 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu

Jedna připomínka k algoritmu: pro malé soubory to funguje, ale pokud bych chtěl prohodit např. první dva řádky (nebo první a desátý) v souboru, který má milion řádků, tak musím načíst celý soubor do paměti (tam se nemusí vejít – nebo i když se vejde, tak mi to zbytečně požere moc paměti, která se dala využít jinak).

Přitom by to bylo řešitelné – načítat řádky postupně (nedávat je všechny do pole) a postupně posílat na výstup. Jen by sis předem musel udělat plán, co musíš načíst předem – např. načíst deset řádků, prohodit, vypsat, a pak už plynule vypisovat zbytek souboru. Tzn. stačí, aby se ti do paměti vešlo prvních deset řádků.

Záleží, k čemu je ten nástroj určený – pokud soubory budou dostatečně malé a RAMka dostatečně velká, tak bych to nechal, jak to je (tzn. dát přednost jednoduchosti, čitelnosti). Ale jestli je důvodem implementace studium, tak si to schválně zkus napsat tak, aby to zvládlo zpracovat třeba i ten soubor s milionem řádků a minimální paměťovou náročností (samozřejmě za předpokladu, že se nemá prohazovat třeba první a poslední řádek).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes
2.2. 16:51 Bherzet | skóre: 11 | blog: Bherzetův blog
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Pro n-m musíš načíst do paměti m - n + 1 řádků. Navrhnout optimální algoritmus pro co nejvíce různých případů může být zajímavá úloha. Prvně by to asi chtělo zanalyzovat, jaké řádky se budou prohazovat (resp. jaká je mezi nimi vzdálenost) a podle toho zvolit vhodnou strategii. Pak je jednou z možností sestavit si index začátků řádků (bonusová úloha: s konstantní spotřebou RAM i pro nekonečně velké soubory; samozřejmě za cenu výkonu) a seekovat se na ně. Při streamovém zpracování by bylo nutné si nejprve vytvořit dočasný soubor.
Jendа avatar 2.2. 23:18 Jendа | skóre: 75 | blog: Výlevníček | JO70FB
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Aniž bych četl kontext, přijde mi, že tohle je úplně ukázková úloha na memory-mapped soubory (v Pythonu například numpy.memmap, i když osobně jsem tohle vždycky používal jenom z C, a pokud to byl Python program, tak se to dělalo v modulu připojeném přes CFFI).
I was just trying to exit Vim and all of this happened!
2.2. 23:30 Bherzet | skóre: 11 | blog: Bherzetův blog
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Jo, mmap je (vhodnější) alternativa k fseek, ale potřebuješ pořád ten index, jinak bys musel řádky hledat sekvenčně.
Bystroushaak avatar 2.2. 23:42 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Aniž bych četl kontext, přijde mi, že tohle je úplně ukázková úloha na memory-mapped soubory (v Pythonu například numpy.memmap, i když osobně jsem tohle vždycky používal jenom z C, a pokud to byl Python program, tak se to dělalo v modulu připojeném přes CFFI).
Tohle mě taky napadlo, ale můžeš v tom potom prohazovat ty řádky? Pokud budou různě dlouhé? Četl jsem tu něco v Jaderných novinkách o tom že linux by měl podporovat ty díry v souborech, ale nemám tušení jak to funguje v praxi.
Bystroushaak avatar 2.2. 23:43 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Jinak OP prohazuje ve skutečnosti řádky v streamech, ne v souborech.
3.2. 00:37 Bherzet | skóre: 11 | blog: Bherzetův blog
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Při streamovém zpracování by bylo nutné si nejprve vytvořit dočasný soubor.
xkucf03 avatar 3.2. 00:43 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše namapovaný soubor vs. proudové zpracování

Což je podobné, jako když si to načteš do RAM – ta se může odswapovat na disk a namapovaný soubor zase může být v paměti…

Tahle úloha IMHO nemá univerzální řešení a člověk si musí vybrat jednu ze dvou možností – buď proudové zpracování a možnost transformovat dynamicky generovaná data, která nikdy v žádném souboru nebyla (takže není co mapovat) nebo pracovat na vstupu se soubory a mít k nim náhodný přístup a moci si přečíst co potřebuji, skákat na různá místa… a na výstupu může být klidně zase proud, takže tam můžu vypisovat průběžně (pokud nechci upravovat ten soubor na místě).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes
3.2. 01:18 Bherzet | skóre: 11 | blog: Bherzetův blog
Rozbalit Rozbalit vše Re: namapovaný soubor vs. proudové zpracování
Což je podobné, jako když si to načteš do RAM – ta se může odswapovat na disk a namapovaný soubor zase může být v paměti…
Ne, není. Když odhlédnu od toho, že 100 GB mi systém naalokovat nedovolí a swap si kvůli tomu zvětšovat (resp. zavádět, protože nemám žádný) nebudu, tak swapování prostě z principu nemůže být tak efektivní jako odkládání do souboru. (Napřed vyžereš všechnu RAM a až dojde, tak se to začně kopírovat na disk, přičemž nevím, jak si kernel ty odswapované stránky organizuje, ale nižší režii to nemůže mít ani náhodou. Mezitím trpí všechny okolní procesy, pokud jsi to tedy nespustil se správnou prioritou a nevím čím…)
Tahle úloha IMHO nemá univerzální řešení a člověk si musí vybrat jednu ze dvou možností – buď proudové zpracování a možnost transformovat dynamicky generovaná data, která nikdy v žádném souboru nebyla (takže není co mapovat) nebo pracovat na vstupu se soubory a mít k nim náhodný přístup a moci si přečíst co potřebuji, skákat na různá místa
Tahle úloha je hlavně k ničemu. Vzešla sice z dotazu v poradně, ale neumím si představit, jak a kde by její řešení bylo obecně uplatnitelné. Jako cvičení to ale může být docela pěkné. Přišlo by mi smysluplnější zkusit to napsat efektivněji než psát složitější Hello, world! ve dvou jazycích. Odtud můj návrh.

Jinak to univerzální řešení v podstatě má: Implementuješ obě dílčí řešení, které jsi popsal (a případně další), a umožníš problémy převádět z jednoho druhu na jiný tam, kde je to výhodné.
Jendа avatar 3.2. 01:07 Jendа | skóre: 75 | blog: Výlevníček | JO70FB
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Ano, pokud budou různě dlouhé, budeš muset posunout všechno mezi nimi. Na mmapování se mi líbí že se „samo“ vyřeší co se musí načíst a zapsat a co už není potřeba, když se to nevejde do paměti tak se stránky samy uvolní a při příštím přístupu zase načtou atd. O konkrétním použití nic nevíme, tak jsem to jenom zmínil jako zajímavou možnost.
I was just trying to exit Vim and all of this happened!
7.2. 09:33 oryctolagus | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
+1, koneckonců, tohle je AFAIK hlavní důvod, proč ag je o tolik rychlejší než grep -R et al.
7.2. 09:45 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Co je ag?
Lidstvo má již jen 12 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte výzvu na proplanetu.cz!
7.2. 12:06 oryctolagus | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
The Silver Seacher [1, 2]

Používám to poslední dobou často, ta rychlost je celkem impresivní...
7.2. 13:56 mimi.vx | skóre: 37 | blog: Mimi.VX | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
8.2. 07:54 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
mmapování taky „samo“ řeší obsluhu chyb. Dostanete SIGSEGV.
3.2. 01:22 Bherzet | skóre: 11 | blog: Bherzetův blog
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Počítal jsem s výstupem na stdout, ne in-place řazením.
Bystroushaak avatar 2.2. 17:22 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Jedna připomínka k algoritmu: pro malé soubory to funguje, ale pokud bych chtěl prohodit např. první dva řádky (nebo první a desátý) v souboru, který má milion řádků, tak musím načíst celý soubor do paměti (tam se nemusí vejít – nebo i když se vejde, tak mi to zbytečně požere moc paměti, která se dala využít jinak).
On navíc nezpracovává soubory, ale scelé streamy. A to mu padne už na
for line in sys.stdin:
    lines.append(line.rstrip())
Což mimochodem kromě toho že načítá neuvěřitelně debilním způsobem celý standardní vstup do pole navíc uřezává bílé znaky z konce řádků, což nechápu proč a pokud bude na konci mezera, nebo tabulátor, tak jí to celou sežere.

Když už ale načítat celý standardní vstup, tak spíš takhle:
lines = sys.stdin.read().splitlines()
pokud tedy nechce používat .readlines(), že na konci jsou znaky nových řádků (což vůbec nechápu proč jako vadí).

Pak taky to parsování čísel regexpama, to mi fakt připomíná ten vtip, že regexpy jsou jako buldozer, dobrý sluha, ale zlý pán. A tady jezdí buldozerem po něčem, co by šlo řešit podstatně čitelněji:
p = re.compile('(\d+)-(\d+)')
for arg in sys.argv[1:]:
    m = p.match(arg)
    if m:    
        a, b = int(m.group(1)), int(m.group(2))
což jde nahradit pomocí:
for arg in parse_args(sys.argv[1:]):
  tokens = arg.split("-")
  a, b = int(tokens[0]), int(tokens[1])
což teda asi automaticky nepřeskakuje špatně matchlé řádky, ale pokud to tam chceš, dá se před to dát podmínka if not all(token.isdigit() for token in tokens) and tokens != 2:, ale mluvit tady o ošetřování chyb moc nemá smysl.

Co má pak za smysl
for line in lines: print(line)
mi uchází. Snaží se autor snad ušetřit budget za nové řádky, nebo co? Tohle rozhodně není čitelnější.

Hah, a teď mi došlo, proč odřezával ty bílé znaky z konce - asi neví, jak vypsat na standardní výstup, protože print() tam přidává svoje \n. Řešení je jednoduché; použít sys.stdout.write(), které má mimochodem i sys.stdout.writelines();
>>> data = sys.stdin.readlines()
asd
bs
>>> data
['asd\n', 'bs\n']
>>> sys.stdout.writelines(data)
asd
bs
>>>
Bystroushaak avatar 2.2. 17:24 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
if not all(token.isdigit() for token in tokens) and tokens != 2:
Chtěl jsem napsat:
if not all(token.isdigit() for token in tokens) or tokens != 2:
  continue
Případně to obalit try:except: blokem.
5.2. 15:52 extremni lama | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Chtěl jsem napsat:

if not all(token.isdigit() for token in tokens) or tokens != 2:
continue

Případně to obalit try:except: blokem.
super, jen ten regex je 10x prehlednejsi :-)
The enemy of my enemy is still my enemy.
Bystroushaak avatar 5.2. 16:33 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Osobně jsem silně proti používání regexu na takhle triviální věci, kde doslova chceš rozpůlit string pomlčkou a převést to na čísla. Obecně mixování programovacího jazyka s úplně jiným, ať už je to tenhle patternmatching brainfuck nebo databázový cobol uznávám jen pokud je k tomu důvod.

Pokud ti v tomhle případě přijde kompilování regexpu, matchování a pak vytahování grup přehlednější, tak se asi neshodneme no.
xkucf03 avatar 5.2. 17:04 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Obecně mixování programovacího jazyka s úplně jiným

Třeba v Perlu je to přirozená součást jazyka.

ať už je to tenhle patternmatching brainfuck

Výhodou regulárních výrazů je to, že jsou (až na drobné odlišnosti) společné pro všechna prostředí a všichni jim rozumí, takže koukneš a vidíš, co to dělá – zatímco ty příkazy nebo konstrukce konkrétního jazyka nemusíš znát z hlavy, pokud s ním běžně neděláš. Totéž SQL – to taky většina lidí zná a zorientuje se v tom, i když to uvidí uvnitř neznámého kódu. Z tohoto pohledu to přispívá čitelnosti.

Argumentem proti regulárním výrazům je výkon – řadu operací jde bez nich udělat efektivněji. Nicméně neuchyloval bych se k předčasné optimalizaci a nezbavoval se regulárních výrazů tam, kde to nepřinese žádný relevantní rozdíl ve výkonu.

Chápu tu snahu používat nativní prostředky jazyka, ale ono když proženeš text nějakou funkcí, která ti vyplivne pole řetězců a z nich si pak taháš hodnoty, tak to není jednodušší oproti regulárnímu výrazu, ze kterého si pak taháš skupiny.

nebo databázový cobol uznávám jen pokud je k tomu důvod

Předpokládám, že myslíš SQL. Ten důvod tam většinou je a dost zásadní – SQL se provádí v databázi, která má k těm datům nejblíž tzn. není potřeba je tahat do aplikace a zpracovávat třeba v tom Pythonu.

Částečně to řeší různá ORM a knihovny typu jOOQ nebo jinq, kde nemusíš psát SQL, používáš nativní prostředky svého jazyka – a to SQL se ti vygeneruje na pozadí samo.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes
Bystroushaak avatar 5.2. 18:21 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Výhodou regulárních výrazů je to, že jsou (až na drobné odlišnosti) společné pro všechna prostředí a všichni jim rozumí, takže koukneš a vidíš, co to dělá – zatímco ty příkazy nebo konstrukce konkrétního jazyka nemusíš znát z hlavy, pokud s ním běžně neděláš. Totéž SQL – to taky většina lidí zná a zorientuje se v tom, i když to uvidí uvnitř neznámého kódu. Z tohoto pohledu to přispívá čitelnosti.
Jak jsem psal, pokud je k tomu důvod, tak se použití regulárních výrazů nevyhýbám. Rozdělení dvou čísel pomlčkou mi ale jako důvod nepřijde. Kdybys třeba měl string, kde může být větší počet těch párů oddělených něčím jiným, tak ok, ale tady dostaneš doslova "1-2" už z argv.
ale ono když proženeš text nějakou funkcí, která ti vyplivne pole řetězců a z nich si pak taháš hodnoty, tak to není jednodušší oproti regulárnímu výrazu, ze kterého si pak taháš skupiny.
Tak to není pravda, že. Je to doslova jednodušší kód na míň řádků, je pochopitelnější co se tam děje a navíc to má větší výkon. Ta if podmínka je jen další validace, která se dá udělat navíc i podstatně jednodušeji a jinak.
Předpokládám, že myslíš SQL. Ten důvod tam většinou je a dost zásadní – SQL se provádí v databázi, která má k těm datům nejblíž tzn. není potřeba je tahat do aplikace a zpracovávat třeba v tom Pythonu.
Opět bych se řídil tím, jestli je k tomu důvod, nebo ne. Když jsem dělal v uložto, tak jsem taky optimalizoval dotazy a byly tam napsané ručně v kódu, protože ORM to prostě neutáhlo a ten důvod byl jasný. Nebo když píšu něco malého nad SQLite, tak to většinou taky spíchnu jen jako string, ale pokud se tomu jde v běžném kódu vyhnout, tak si myslím že je lepší se tomu vyhnout, už jen z toho důvodu, že ORM je víc portabilní a je možné přejít napřiklad z mysql na postgre relativně bezbolestně.
Částečně to řeší různá ORM a knihovny typu jOOQ nebo jinq, kde nemusíš psát SQL, používáš nativní prostředky svého jazyka – a to SQL se ti vygeneruje na pozadí samo.
Používal jsem PonyORM.
6.2. 15:48 extremni lama | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Takze prvne k rychlosti... Kterou stejne nema smysl moc resit. Za prve tech argumentu nebude milion, a za druhe je to python takze to stejne bude pomale ;-) Ale kdyz uz o tom mluvis:

a.py:

import re

p = re.compile('(\d+)-(\d+)')
for i in range(1000000):
    m = p.match("123-456")
    if m:
        print "a =", m.group(1), ", b =", m.group(2)

$ time python a.py > /dev/null

real    0m4.021s
user    0m3.727s
sys     0m0.263s

b.py:

for i in range(1000000):
    tokens = "123-456".split("-")
    if not all(token.isdigit() for token in tokens) or len(tokens) != 2: continue
    print "a =", tokens[0], ", b =", tokens[1]

$ time python b.py > /dev/null

real    0m4.035s
user    0m3.728s
sys     0m0.296s

Takze regex je nepatrne rychlejsi, ale v podstate totez az na chybu mereni ;-)

A ted k citelnosti.

Pokud ti v tomhle případě přijde kompilování regexpu, matchování a pak vytahování grup přehlednější, tak se asi neshodneme no.

Takze misto kompilovani regexu si ho zkompilujeme rucne a pro jistotu spatne. I tva druha verze je spatne... chybi ti tam len ;-)

Co me musi probehnout hlavou kdyz se podivam na kod s regexem:
- mam regex "cislo-cislo"
- zkompiluju
- provedu match
- vezmu prvni cislo, druhe cislo

Je to naprosto primocare, jasne a pochopitelne.

Co me probehne hlavou kdyz se podivam na tvuj kod:
- za prve tam nikde neni co vlastne parsuju. Ano, mohl bych si tam pridat komentar parsuju format "cislo-cislo", ale potom tam muzu rovnou dat ten regex.
- takze mam retezec
- rozdelim ho podle pomlcky
- vznikle pole projedu cyklem a kazdy prvek mapuju na true/false podle toho jestli je to cislo
- vysledne pole znovu projedu cyklem a zkontroluju ze mam vsude true
- zkontroluju ze pole ma prave 2 prvky
- vezmu prvni prvek z pole a druhy prvek z pole

Samozrejme dokazu z toho poskladat co to jako celek dela, ale nerikej ze nevidis jaka je to prasarna...

Dokazu si predstavit tenhle kod ktery by se mohl v citelnosti priblizit tomu regexu:
tokens = arg.split("-")
if len(tokens) == 2 and tokens[0].isdigit() and tokens[1].isdigit():
    # match

Regex je porad citelnejsi, ale tohle uz aspon vypada prijatelne. Ale to co jsi napsal... To jako myslis vazne?

Jestli ses chtel pochlubit ze umis pouzivat "for" a "all" tak ok, aje pro reseni tohohle konkretniho problemu je to strasliva prasarna :-)
The enemy of my enemy is still my enemy.
Bystroushaak avatar 6.2. 17:14 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
- vznikle pole projedu cyklem a kazdy prvek mapuju na true/false podle toho jestli je to cislo

- vysledne pole znovu projedu cyklem a zkontroluju ze mam vsude true

- zkontroluju ze pole ma prave 2 prvky
Tyhle 3 kroky tam mit vubec nemusis, pokud to obalis try:except: blokem co udela continue pri chybe:
for arg in sys.argv[1:]:
  try:
    tokens = arg.split("-")
    a, b = int(tokens[0]), int(tokens[1])
  except:
    continue
6.2. 17:59 extremni lama | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
tohle vypada lepe, ale zase tam chybi test jestli ty cisla jsou prave 2
The enemy of my enemy is still my enemy.
6.2. 18:05 JS1 | skóre: 2 | blog: intuition_pump
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Ma to smysl, se o tom prit? Ja bych to taky nejspis napsal jednim regexpem (v praxi by asi zalezelo na tom, jestli uz jsem regexpy pouzil - asi bych se nenamahal kvuli tomu znovu cist k nim dokumentaci), ale Bystroushaakuv kod mi nevadi.

A ze nekontroluje vsechny chyby - no pokud je to jen skriptik na nejake rychle zpracovani tak v tom nevidim problem.

Prijde mi, ze obecne programatori se prilis mlati po hlavach ohledne zbytecnosti, treba jak vypada kod, misto aby resili skutecne zajimave problemy treba s architekturou nebo UX.
Lidstvo má již jen 12 let, aby odvrátilo nejhorší důsledky klimatické katastrofy. Podpořte výzvu na proplanetu.cz!
6.2. 18:15 extremni lama | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Tak u tohohle konkretniho skriptiku je uplne jedno jak se to udela :-)

Slo mi o to ze kdyz nekdo prijde s tezi "regexy jsou buldozer, nabastlit si vlastni parser bude podstatne citelnejsi" tak se hodi veci uvest na pravou miru...

cituji Bystroushaaka :-)
Pak taky to parsování čísel regexpama, to mi fakt připomíná ten vtip, že regexpy jsou jako buldozer, dobrý sluha, ale zlý pán. A tady jezdí buldozerem po něčem, co by šlo řešit podstatně čitelněji
The enemy of my enemy is still my enemy.
Bystroushaak avatar 6.2. 21:54 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Slo mi o to ze kdyz nekdo prijde s tezi "regexy jsou buldozer, nabastlit si vlastni parser bude podstatne citelnejsi" tak se hodi veci uvest na pravou miru...
Vlastní parser bude skoro vždycky podstatně čitelnější, dokud nemusíš dělat stavový automat. To se ani nebavím o věcech, jako parsování emailové adresy, kde to bnf v čitelnosti vyhraje na celé čáře.
Bystroushaak avatar 6.2. 21:52 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
tohle vypada lepe, ale zase tam chybi test jestli ty cisla jsou prave 2
A je to zapotřebí? Pokud jich bude víc jak dvě, tak použije první dvě. Což teda jestli se nepletu, tak i ten regexp.
Bystroushaak avatar 6.2. 17:23 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Jestli ses chtel pochlubit ze umis pouzivat "for" a "all" tak ok, aje pro reseni tohohle konkretniho problemu je to strasliva prasarna :-)
A muzes nejak zduvodnit proc je to prasarna? Pokud umis cist python, tak je to krasne ciste vyjadreni skoro na urovni matematiky: pro kazdy prvek plati, ze je cislem.

Uznavam, ze v tomhle konkretnim pripade asi dava smysl to tam vypsat explicitne, ale pokud by tam byly uz treba tri prvky, tak by mi to prislo vyslovene blbe.
6.2. 18:00 extremni lama | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Prasarna je to proto ze je to slozitejsi nez by to melo byt. I kdzy jsi zvykly na ten zapis tak porad za tim musis videt jak se ty tokeny propaguji pres nekolik urovni...

Dalsi vec je ze se snazis vymyslet algoritmus ktery za tebe muze snadno udelat regex engine. A jak sam vidis tak tam opakovane delas chyby. I to je dukaz komplexity...
The enemy of my enemy is still my enemy.
Bystroushaak avatar 6.2. 21:59 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Prasarna je to proto ze je to slozitejsi nez by to melo byt. I kdzy jsi zvykly na ten zapis tak porad za tim musis videt jak se ty tokeny propaguji pres nekolik urovni...
Nevím, jakmile se tohle naučíš používat, spolu s generátory a iterátory, tak je to prostě přirozené. Uznávám, že pro někoho kdo to běžně nepoužívá je to nepřirozené, ale to je i regexp.
Dalsi vec je ze se snazis vymyslet algoritmus ktery za tebe muze snadno udelat regex engine. A jak sam vidis tak tam opakovane delas chyby. I to je dukaz komplexity...
Chyby dělám hlavně protože jsem to psal z hlavy jen do inputu tady na abclinuxu. Upřímně kdybych měl psát regexp, tak to asi dopadne mnohem hůř. Ale jinak jak jsem psal, nebráním se regexpu, pokud k tomu existuje důvod. Ten důvod u mě je například že bys musel splitnout string víc než jednou, či provádět nějaké machinace a ověřování. Specificky když chceš parsovat skupiny čísel a znaků, které jdou za sebou v nějakém pořadí a můžou se nějak opakovat, pak je regexp skutečně asi nejlepší řešení. Nadruhou stranu, jakmile ti do toho vleze třeba tak triviální věc, jako URL, tak od regexpů ruce pryč a chce to přejít na něco jiného.
2.2. 17:38 sad
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Dobře, díky za poznámky, tvoje řešení je lepší. Python ještě moc dobře neznám, takže jsem zvyklý načítat řádky v cyklech.
Hah, a teď mi došlo, proč odřezával ty bílé znaky z konce - asi neví, jak vypsat na standardní výstup, protože print() tam přidává svoje \n.
Přesně tak :-) O těch funkcích jsem vážně nevěděl. Tak dík.
Bystroushaak avatar 2.2. 18:13 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Příloha:
Ok. Jinak načítat parametry je obecně lepší pomocí argparse (to generuje i nápovědu a mám na to zastaralý builder). V tomhle případě to nemá úplně smysl, ale jen abys o tom věděl. Tělo toho co to dělá by mělo být ve funkci volané z if __name__ == '__main__':. To je z toho důvodu, aby se to dalo importovat a volat samostatně. Kdybych importoval ten tvůj kód, tak se hned spustí a celé to padne.

Taky si pořid linter (pep8, pylint a pyflakes, sonarlint najednou!), všechno jsou to zdarma pluginy použitelné v editorech, kde ti budou podtrhávat a radit. Taky si zapni zobrazování bílých znaků v editoru, máš tam na konci řádků různé divné mezery (viz příloha) a v pythonu se bez toho moc nedá dělat. To umí všechny, i vim/emacs (ty lintery vim/emacs umí taky).

Importy nepiš na jeden řádek, hezky je rozepiš na víc. To má výhodu že je to jednak čitelnější, když jich tam máš víc, ale taky se dají jednotlivě zakomentovávat a vyhazovat pomocí klávesových zkratek pro mazání celého řádku, místo abys musel jít někam doprostřed řádku a mazat tam jedno slovo. A na začátek přidej shebang (#! /usr/bin/env python3) aby to bylo spustitelné.

No a taky je dobré rozdělit funkcionalitu od sebe a nedělat z toho špagety, kde na jednom místě parsuješ argumenty a zároveň provádíš hlavní algoritmus tvého kódu. Kdybych to měl po tobě v práci zrefactorovat (code review jsi teď dostal), tak by to vypadalo takhle:
#! /usr/bin/env python3
import sys


def _parse_argv(args):
    for arg in args:
        tokens = arg.split('-')

        if len(tokens) != 2 or not all(token.isdigit() for token in tokens):
            continue

        yield [int(token) for token in tokens]


def switch_lines(lines, line_pairs):
    for a, b in line_pairs:
        lines[a], lines[b] = lines[b], lines[a]


def main(line_pairs):
    lines = sys.stdin.readlines()

    switch_lines(lines, line_pairs)

    sys.stdout.writelines(lines)


if __name__ == '__main__':
    main(_parse_argv(sys.argv[1:]))

Argumenty se parsují zvlášť, funkcionalita je zvlášť a hlavní část kódu ve funkci main je taky zvlášť. Z kódu je teď modul použitelný i v jiných programech.

Samozřejmě tohle je pořád bez toho o čem psal xkucf03, tedy toho prediktivního prohazování řádek na zároveň plánu a cacheování, jen čistě očividný refactoring toho co jsi napsal.

Zkus se zamyslet nad všemi body co jsem ti napsal a klidně se zeptej, pokud ti je něco nejasného. Cílem nebylo na tebe zamachrovat, ale udělat code review, tedy ukázat ti jak to dělat objektivně lépe.
2.2. 19:10 sad
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Tak tys mě vážně dobře zrefactoroval :-) Kolik jsem dlužen?

Ale tohle je určitě lepší kód, a kdybych psal něco většího, tak budu postupovat podobně.

Těch prázdných znaků jsem si ani nevšiml, já totiž v Pythonu odsazuji tabem a poté převádím taby na čtyři mezery, aby ten kód vypadal na abíčku stejně jako u mě, já vím, že bych mohl nastavit v IDE tab na mezery, ale zase tolik v Pythonu neprogramuju.

Na druhou stranu mi ten tvůj skript přijde na tak krátký prográmek docela roztahaný, já rád počítám řádky... A s tvými radami budu schopen ten skript v Pythonu ještě o několik řádek zkrátit, takže Python je efektivnější, než jsem myslel.
Bystroushaak avatar 2.2. 19:21 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
A s tvými radami budu schopen ten skript v Pythonu ještě o několik řádek zkrátit, takže Python je efektivnější, než jsem myslel.
To je jedno z kouzel pythonu. Já i po 11 letech programování pořád objevuji jak dělat věci víc efektivněji. Třeba nedávno jsem si konečně dočetl i ty zbylé funkce (kromě contextmanager dekorátoru) v contextlibu a byl jsem docela překvapen.
xkucf03 avatar 2.2. 21:01 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
načítat parametry je obecně lepší pomocí argparse (to generuje i nápovědu a mám na to zastaralý builder).

Tohle zrovna řeším, byť v jiném jazyce. Ale nakonec to dělám ručně (cyklus přes argv)… Jde o to, že na vstupu je nějaký plochý seznam textových řetězců (argv) a na výstupu objekt resp. nějaká stromová struktura. Je to vlastně podobná úloha jako parsování nějakého jazyka – na vstupu máš text resp. posloupnost tokenů a na výstupu je AST.

Dokáží tohle ty nástroje, nebo dělají spíš jen nějaké jednoduché mapování na slovník nebo objekt obsahující pár seznamů?

Jde mi o to, že ty CLI parametry můžou vypadat nějak takhle:

--dělej-něco mojeÚloha1
    --dělej-to-takhle xxx yyy
    --použij-při-tom tohle
    --dávej-při-tom-pozor-na-xyz
--dělej-něco-úplně-jiného 666 444
--dělej-něco mojeÚloha2
    --dělej-to-takhle abc def
    --přejmenuj-to-na zzz
--tady-máš-nějaký-globální-parametr jehoNázev jehoHodnota
--tady-máš-nějaký-globální-parametr jinýParametr jinýHodnota
--debug
--kontext kkk

Přičemž v argv je to nasypané v ploché struktuře, jeden token po druhém, ale já z toho potřebuji postavit nějaký strom, jehož struktura je výše naznačená tím odsazením. U těch „úloh“ by se při parsování mělo zachovat pořadí. U globálních parametrů a voleb jako --debug na pořadí nezáleží.

Přijde mi, že podobné knihovny mají přínos v případě, že chci třeba -abc interpretovat stejně jako -a -b -c nebo -ac -b. Nebo --dlouhý-název jako -d. Nebo třeba --xxx=zzz jako --xxx zzz. S tím mi to asi pomůže, ale co v těch případech, kdy je tam nějaký kontext, záleží na pořadí parametrů a má se z toho vyrobit stromová struktura?

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes
Bystroushaak avatar 2.2. 23:14 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Argparse tohle obecně podle mého názoru bez většího hackování (dají se nastavovat validační a transformační funkce) nedovede. Kdybych to musel řešit, bych si na to asi napsal formální gramatiku a parser.
xkucf03 avatar 3.2. 00:19 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu

Od jaké složitosti bys do toho šel? Ten můj kód kolem toho má nějakých čtyřicet řádků. To mi přijde snesitelnější napsat to ručně (a později to číst) než se dělat s gramatikou. Byť s nějakým PEG parserem by to bylo dost jednoduché, ale zase to znamená zatahovat do programu závislost na nějaké knihovně. A stejně to moc kódu neušetří, protože i ten parser musíš napojit na nějaké akce (které třeba zkonstruují ten objekt).

Možná by bylo zajímavé nějaké deklarativní mapování mezi CLI parametry a objekty – něco jako je JPA (ORM) nebo JAXB… ale psát se mi s moc zrovna nechce.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes
Bystroushaak avatar 3.2. 00:32 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Od jaké složitosti bys do toho šel?
Nevím, jestli je složitost ta správná metrika. U mě by záleželo jak moc bych to chtěl, s tím že jsem většinou ochotný redefinovat jak moc něco chci, když vidím že to jednoduše nejde. Tzn. je možné, že bych prostě změnil požadavky na něco jiného.

Taky bych to porovnával metrikou užitek/námaha. Tohle má očividně docela velkou námahu, ale vůbec nejsem schopný posoudit užitek.

Další věc, kterou je třeba zohlednit je podívat se po netu jestli už něco takového neexistuje. V pythonu je skoro vždycky případ, že ano, takže bych to zkusil založit na tom, či to forknout. V nedávné době jsem řešil například vytahování spec file z src RPM balíčků a ukázalo se, že pythonní rpmfile sice existuje, ale padá na RPM balíčcích, takže jsem nakonec použil a přebalil její neoficiální fork. To celé se mi pořád vyplatilo víc než volat externě příkaz rpm.

Stejně tak bych se asi podíval, jestli neexistuje něco co třeba aspoň částečně řeší tvůj problém. Pokud ne, zvážil bych vytvoření opensource verze, kde bych tím třeba v budoucnosti pomohl někomu jinému. Kdybych to řešil, tak určitě PEG.
xkucf03 avatar 3.2. 01:18 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Nevím, jestli je složitost ta správná metrika.

Od složitosti se odvíjí pracnost prvotní implementace a taky pracnost následné údržby. Další věc je, že když k tomu přijde někdo jiný, tak FOR cyklus a IF/SWITCH bude chápat určitě, ale co když nebude zkušený ohledně gramatik a různých nástrojů/knihoven pro práci s nimi?

Tím nechci říct, že by se to mělo přizpůsobovat těm méně schopným/zkušeným, ale chce to najít nějakou rozumnou míru. Taky už jsem viděl software, který byl navržený „sofistikovaně“ někým „geniálním“, ale postupně to šlo všechno do háje, protože do rozvoje se moc neinvestovalo, takže hodně věcí bylo už přežitých, z původního pěkného návrhu zbyla spíš už jen ta složitost a to vedlo k prodražení vývoje (i triviální úpravy zabraly dost času), v důsledku toho si zákazníci objednávali méně úprav, což vedlo k tomu, že vývojáři se věnovali jiným projektům a jejich znalost tohoto produktu se vytrácela. Když se jednou za čas objevil nějaký požadavek na implementaci něčeho nového, tak trvalo dlouho, než se do toho někdo zase dostal a vzpomněl si jak to funguje (nebo to spíš znovu objevil, protože s tím softwarem nikdy nedělal), takže to zase bylo drahé, což zákazníky demotivovalo požadovat v budoucnu další změny… je to začarovaný kruh – kdyby se dělaly změny často, tak budou mít vývojáři větší praxi a s tím sofistikovaným řešením se lépe sžijí, takže budou efektivnější a implementace změn bude levnější, takže zákazníci si jich budou moci dovolit víc. Pokud se tahle spirála rozjede tím špatným směrem, tak to odrovná i původně dobrý software. To už tedy hodně odbíhám od tématu, ale ono je dost rozdíl, dělat software, na kterém pracuje na plno několik vývojářů a dělat software, ve kterém se má jednou za půl roku udělat nějaká menší změna. A když si zvolíš technologie a postupy pro ten první scénář, tak to v tom druhém nemusí vůbec dobře fungovat.

Pak jsou tedy ještě jiná kritéria jako správnost/spolehlivost a výkon, ale ta složitost mi tady přijde nejzásadnější. Správnost ověříš testy a měla by být zaručena vždy. A na výkonu tady až tak nesejde, protože CLI parametry se parsují jen jednou (a pokud jsou složité, tak asi i program bude dělat něco celkem složitého a jeho běh bude řádově delší než doba parsování parametrů).

Tohle má očividně docela velkou námahu, ale vůbec nejsem schopný posoudit užitek. … Stejně tak bych se asi podíval, jestli neexistuje něco co třeba aspoň částečně řeší tvůj problém. Pokud ne, zvážil bych vytvoření opensource verze, kde bych tím třeba v budoucnosti pomohl někomu jinému. Kdybych to řešil, tak určitě PEG.

Ta jiná řešení ale taky nemají nulovou pracnost. Asi bych si to měl zkusit reimplementovat pomocí PEG parseru, abych to mohl porovnat, ale jen tak od boku mi přijde, že by to jednodušší nebylo, protože ten kód jsem měl napsaný za chvilku a moc to nebolelo. Ono asi i to hledání existujících řešení by zabralo víc času.

Příklad, kde jsem to použil minule: CLIParser.h. Ta současná úloha je jen o málo složitější a implementace zabrala méně času než tahle diskuse… Tu první verzi jsem nějak namastil s tím, že uvidím jak to půjde a při druhém nebo třetím použití to nějak zobecním a učešu. Nechtělo se mi vymýšlet nějakou abstrakci nebo sofistikované řešení předem – ve chvíli, kdy ještě přesně nevím, co od toho budu chtít a jak s tím budu pracovat.

Vlastně si mi tenhle způsob docela líbí – nejdřív nastřelit první verzi a pak ji postupně opracovávat. Ale jde to aplikovat v případě, kdy se můžeš vrátit zpět a předělat to. Což jde typicky u vlastních projektů. Zatímco když vyvíjíš pro někoho jiného, kdo to platí nebo dokonce řídí vývoj, tak tam je tendence už do toho nesahat, jakmile to nějak funguje (jednak ze strachu, aby se to nerozbilo, a jednak kvůli snižování nákladů, protože za krásný kód nikdo platit nechce).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes
Bystroushaak avatar 3.2. 01:33 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu

Tím nechci říct, že by se to mělo přizpůsobovat těm méně schopným/zkušeným, ale chce to najít nějakou rozumnou míru. Taky už jsem viděl software, který byl navržený „sofistikovaně“ někým „geniálním“, ale postupně to šlo všechno do háje, protože do rozvoje se moc neinvestovalo, takže hodně věcí bylo už přežitých, z původního pěkného návrhu zbyla spíš už jen ta složitost a to vedlo k prodražení vývoje (i triviální úpravy zabraly dost času), v důsledku toho si zákazníci objednávali méně úprav, což vedlo k tomu, že vývojáři se věnovali jiným projektům a jejich znalost tohoto produktu se vytrácela. Když se jednou za čas objevil nějaký požadavek na implementaci něčeho nového, tak trvalo dlouho, než se do toho někdo zase dostal a vzpomněl si jak to funguje (nebo to spíš znovu objevil, protože s tím softwarem nikdy nedělal), takže to zase bylo drahé, což zákazníky demotivovalo požadovat v budoucnu další změny… je to začarovaný kruh – kdyby se dělaly změny často, tak budou mít vývojáři větší praxi a s tím sofistikovaným řešením se lépe sžijí, takže budou efektivnější a implementace změn bude levnější, takže zákazníci si jich budou moci dovolit víc. Pokud se tahle spirála rozjede tím špatným směrem, tak to odrovná i původně dobrý software. To už tedy hodně odbíhám od tématu, ale ono je dost rozdíl, dělat software, na kterém pracuje na plno několik vývojářů a dělat software, ve kterém se má jednou za půl roku udělat nějaká menší změna. A když si zvolíš technologie a postupy pro ten první scénář, tak to v tom druhém nemusí vůbec dobře fungovat.

Ok, s tím souhlasím.
Ta jiná řešení ale taky nemají nulovou pracnost. Asi bych si to měl zkusit reimplementovat pomocí PEG parseru, abych to mohl porovnat, ale jen tak od boku mi přijde, že by to jednodušší nebylo, protože ten kód jsem měl napsaný za chvilku a moc to nebolelo. Ono asi i to hledání existujících řešení by zabralo víc času.
Pokud to už někdo vyřešil, tak to může mít třeba jen 20% pracnost.
Vlastně si mi tenhle způsob docela líbí – nejdřív nastřelit první verzi a pak ji postupně opracovávat. Ale jde to aplikovat v případě, kdy se můžeš vrátit zpět a předělat to. Což jde typicky u vlastních projektů. Zatímco když vyvíjíš pro někoho jiného, kdo to platí nebo dokonce řídí vývoj, tak tam je tendence už do toho nesahat, jakmile to nějak funguje (jednak ze strachu, aby se to nerozbilo, a jednak kvůli snižování nákladů, protože za krásný kód nikdo platit nechce).
Co se mě týče, tak já pracoval vždycky v hodně agilních týmech, kde se bralo jako samozřejmost, že software není produkt, ale proces. Samozřejmě je to dané volbou mojí práce (backend), ale obecně myslím že to je asi nejpraktičtější způsob jak dosáhnout toho co chceš a kontinuálně to zlepšovat.
2.2. 18:01 Bherzet | skóre: 11 | blog: Bherzetův blog
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
asi neví, jak vypsat na standardní výstup, protože print() tam přidává svoje \n. Řešení je jednoduché; použít sys.stdout.write(), které má mimochodem i sys.stdout.writelines()
Nebo nastavit volitelný argument end funkce print na prázdný řetězec.
wamba avatar 2.2. 18:55 wamba | skóre: 38 | blog: wamba
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Řádky do pole můžeš vložit přímo namísto
@l = ();
push(@l, $_) while <STDIN>;
jednoduše
my @l = <STDIN>;
Nasledující
($l[$1], $l[$2]) = ($l[$2], $l[$1])
lze upravit na
 @l[$1,$2] = @l[$2,$1]
Konečně pole můžeš přímo vytisknout
print @l
This would have been so hard to fix when you don't know that there is in fact an easy fix.
2.2. 19:18 sad
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
WOW! Tak tohle jsem přesně potřeboval! Dík!

Tohle už je prakticky one-liner, ne?

@l[$1,$2] = @l[$2,$1] jsem viděl ve funkci, takže jsem myslel, že to lze dělat jen s referencí.

A je tohle pořád Perl5?

2.2. 20:12 kolcon | skóre: 15 | blog: kolcon
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu

... a na zacatek use strict; use warnings;

3.2. 09:50 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Perl5 je stále aktuální „verze“. Od roku 1994 napořád. Řezy existovali už v Perlu 5.6.0, ale co se s nimi dalo dělat a nad jakými strukturami se dalo dělat se časem rozšiřovalo. Hodně změn přišlo až s Perlem 5.20.0. Bohužel perldata/Slices je na historická data skoupý.
3.2. 00:35 VM
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu
Krom toho že na to je příkaz "tac", tak se to dá v Perlu udělat výrazně jednodušeji:

perl -e 'print reverse <>' soubor...

Funguje to tak že operátor <> v seznamovém kontextu načte všechno do seznamu, reverse to otočí, a print to vypíše...
xkucf03 avatar 3.2. 01:26 xkucf03 | skóre: 47 | blog: xkucf03
Rozbalit Rozbalit vše Re: Prohození řádků v Pythonu a Perlu

Asi by si to chtělo přečíst víc než jen nadpis :-)

Ten program nemá obracet pořadí všech řádků, ale prohazovat libovolné dvojice řádků, které byly zadány jako parametry příkazu.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-Výuka.cz, Relational pipes

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.