label=gtk.Label() label.set_markup("Popisek:")Kde práci s fontem jednoduše zajišťuje PangoML, což je jednodušší, HTML podobný, jazyk. Co se týče GTK ve windows, tak je pravda, že jeho defaultní vzhled je větší, než je tam obvyklé (hůře vidící lidé ocení). Zřejmě si ale přehlédl, že součástí GTK pro windows je prográmek (v adresáři bin, jmenuje se gtkthemeselector.exe) pro přepínání témat (vzhledů. skinů) a že kromě defaultního vzhledu jsou jeho součástí další vzhledy, třeba redmond95 nebo wimp, které by ti mohli vyhovovat. Což je mimochodem další z výhod GTK. TCL/TK má při programování své místo, to nepopírám, už jen kvůli údržbě již napsaného kódu. Můj příspěvek jen chtěl upozornit nezkušené zájemce o programování, že TCL je veterán, o kterém můžeme psát s nadšenou nostalgií, ale přeci tu jen už jsou vhodnější a modernější programovací jazyky. Zkušení programátoři přínos TCL zajisté dovedou posoudit sami. Určitě se najdou tací, které TCL osloví a něco jim přinese, ale přiznejme si, bude jich pravděpodobně výrazná menšina. Co se týče Vi, to je skutečně zastaralé a nelze nikomu doporučit. Vim zastaralý rozhodně není, vyvíjí se a jiné editory v některých ohledech překonává. Přesto, a nebo právě proto, bych souhlasil, že Vim není vhodný pro amatéry, na to je příliš komplikovaný a vlastnosti které nabízí amatéři nedokáží využít a ocenit. Nicméně, zastaralost bych neodvíjel od času vzniku, ale od toho, jaká ta věc je. I teď v roce 2005 může vzniknout nový jazyk, který bude používat zastaralé koncepty a může tak klidně být považován za zastaralý a překonaný. A TCL/TK podle mě takové je, přestože bylo ve své době inovativní a řada modernějších jazyků se jím nepochybně nechala inspirovat.
PYTHON/GTK: def printStatus(button, checks): for check in checks: if check.get_active(): stat = "je zatržen." else: stat = "není zatžen." print check.get_label(), stat TCL/TK: proc tisk {seznam} { foreach i $seznam { set var [$i cget -variable] global $var set f [expr $$var] if {$f==1} {set answer je} {set answer není} puts "[$i cget -text] $answer zatržen" } }Snad už je jasné, proč si myslím, že: Nelíbí se mi ... ani po stránce použitelnosti z pohledu programátora. Jestli to dokážete, zkuste se na ty dvě ukázky podívat očima začátečníka (na které jsem se obracel). Co mu asi přijde srozumitelnější a intuitivnější? To co je nutné v TCL/TK opravdu nelze považovat za elegantnost samu, jak jste napsal, právě naopak. Zjišťovat stav tlačítka pomocí tří příkazů, globální proměnné a ještě vyhodnocováním výrazu, to je úplně mimo. V moderním toolkitu něco takového musí být dostupné jako snadno čitelná stavová proměnná toho tlačítka.
checks = [] checks.append( gtk.CheckButton( label="První" ) ) checks.append( gtk.CheckButton( label="Druhý" ) ) checks.append( gtk.CheckButton( label="Třetí" ) ) checks.append( gtk.CheckButton( label="Čtvrtý" ) ) checks.append( gtk.CheckButton( label="Pátý" ) )na
checks = ["První","Druhý","Třetí","Čtvrtý","Pátý"] for popisek in checks: checks.append( gtk.CheckButton( label=popisek ) )No neni ten Python krasnej?
#!/usr/bin/wish foreach desc {První Druhý Třetí Čtvrtý Pátý} { lappend seznam [checkbutton .cb[incr i] -text $desc] } button .tisk -text "Tiskni" -command {tisk $seznam} button .konec -text "Konec" -command {exit} pack {*}$seznam .tisk .konec proc tisk {seznam} { foreach i $seznam { puts "[$i cget -text] [lindex {není je} [expr \$::[$i cget -variable]]] zatržen" } }
invalid command name "tisk" invalid command name "tisk" while executing "tisk $seznam" invoked from within ".tisk invoke" ("uplevel" body line 1) invoked from within "uplevel #0 [list $w invoke]" (procedure "tk::ButtonUp" line 22) invoked from within "tk::ButtonUp .tisk" (command bound to event)4) Toto odmítám. Když by začátečník potřeboval pracovat s polem tlačítek, určitě by je vložil do pole, to je vcelku logické. Program neprovádí žádné akce na změnu stavu widgetu, cílem programu je prozkoumat aktuální stav svých widgetů. V každám případě je vidět, že to co je vydáváno za výhodu TCL/TK je Pythonu/GTK vlastní a umí to přehledněji a jednodušeji. Což je to, na co upozorňuji, o nic jiného mi nejde.
To není provokace, to je velmi rozumné.
(if <podmínka> <true-forma> <false-forma>) (cond (<podmínka> <forma> <forma>*) (<podmínka> <forma> <forma>*)*)
A je to. Odděluje se na horizonální úrovni mezerami a na vertikální závorkami a je to. Víc člověk vědět nemusí. Indentace je povinnost pro čitelnost, ale ve slušném editoru je automatická. Co by mohl člověk chtít víc?
Další mnou kdesi výše jmenované jazyky jsou podobně jednoduché. Python jednoduchý není a spousta jiných jazyků je na tom ještě hůř.
AB = [] Ab = [] aB = [] ab = [] for a, b, hodnota in vysledky: if a and b: AB.append(hodnota) elif a and not b: Ab.append(hodnota) elif b and not a: aB.append(hodnota) else: ab.append(hodnota)Jsem zvědavý na řešení v ostatních jazycích které zde zazněly, především Lispu a TCL. Nechť laskavý čtenář naší disputace sám posoudí, co se mu zdá nebo nezdá být přehledné. Čímž bych také tento spor ukončil, protože se zdá být značně subjektivní.
resAB := vysledky select: [ :v | v first & v second ] thenCollect: [ :v | v third ]. resAb := vysledky select: [ :v | v first & v second not ] thenCollect: [ :v | v third ]. resaB := vysledky select: [ :v | v first not & v second ] thenCollect: [ :v | v third ]. resab := vysledky select: [ :v | v first not & v second not ] thenCollect: [ :v | v third ].nebo třeba
select := [:val | vysledky select: [ :v | (v first: 2) = val ] thenCollect: [ :v | v third ] ]. resAB := select value: #(true true). resAb := select value: #(true false). resaB := select value: #(false true). resab := select value: #(false false).nebo imperativněji, blíže Vašemu řešení:
resAB := OrderedCollection new. resAb := OrderedCollection new. resaB := OrderedCollection new. resab := OrderedCollection new. vysledky do: [ :v | (v first & v second) ifTrue: [ resAB add: v third ]. (v first & v second not) ifTrue: [ resAb add: v third ]. (v first not & v second) ifTrue: [ resaB add: v third ]. (v first not & v second not) ifTrue: [ resab add: v third ] ].Příkladů, na kterých se dá ukázat, že právě ten a ten určitý jazyk je nejlepší, se dá vymyslet hodně. Podobně by se dalo třeba zadat naimplementovat tak základní věc, jako singleton (jedináček), nebo nějaký příklad, kde se dá skvěle využít dynamická dědičnost, a Python by proti Selfu vypadal jak malej do školky (což by, mimochodem, nebyl zcela mylný závěr ;-).
AB = [c for a, b, c in vysledky if a and b] Ab = [c for a, b, c in vysledky if a and not b] aB = [c for a, b, c in vysledky if b and not a] ab = [c for a, b, c in vysledky if not a and not b]Hezké, že? Předvede se někdo s TCL prosím?
výsledkyAB := UspořádanáKolekce nová. výsledkyAb:= UspořádanáKolekce nová. výsledkyaB := UspořádanáKolekce nová. výsledkyab := UspořádanáKolekce nová. výsledky zpracuj: [ :výsledek | (výsledek první a: výsledek druhý) kdyžJePravda: [ výsledkyAB přidej: výsledek třetí ]. (výsledek první a: výsledek druhý ne) kdyžJePravda: [ výsledkyAb přidej: výsledek třetí ]. (výsledek první ne a: výsledek druhý) kdyžJePravda: [ výsledkyaB přidej: výsledek třetí ]. (výsledek první ne a: výsledek druhý ne) kdyžJePravda: [ výsledkyab přidej:výsledek třetí ] ].Můžete si to porovnat s předchozím příkladem a vydedukovat, co je ve Smalltalku dáno syntaxí jazyka a co je prachobyčejné volání zpráv, které si můžete modifikovat a dotvářet jak se Vám zlíbí :-)
V TCL například takto (osobně bych to napsal trošku jinak, ale nebylo by to tak čitelné):
set AB {} set Ab {} set aB {} set ab {} set vysledky { { 0 0 prvni} { 0 1 druhy} { 1 0 treti} {1 1 ctvrty}} foreach i $vysledky { set podminka1 [lindex $i 0] set podminka2 [lindex $i 1] set vysledek [lindex $i 2] if [expr $podminka1 & $podminka2] { lappend AB $vysledek } elseif [expr $podminka1 & ! $podminka2] { lappend Ab $vysledek } elseif [expr ! $podminka1 & $podminka2] { lappend aB $vysledek } else { lappend ab $vysledek} } puts $AB puts $Ab puts $aB puts $ab
Podle mě trošičku lepší řešení, kde se pořád neopakuje stejná operace:
set AB {} set Ab {} set aB {} set ab {} set vysledky { { 0 0 prvni} { 0 1 druhy} { 1 0 treti} {1 1 ctvrty}} foreach i $vysledky { set podminka1 [lindex $i 0] set podminka2 [lindex $i 1] set vysledek [lindex $i 2] if [expr $podminka1 & $podminka2] { set seznam AB } elseif [expr $podminka1 & ! $podminka2] { set seznam Ab } elseif [expr ! $podminka1 & $podminka2] { set seznam aB } else { set seznam ab } lappend $seznam $vysledek } puts $AB puts $Ab puts $aB puts $ab
Vážený pane, před uzavírací závorkou nejsou žádné hvězdičky. Najděte si v nějakém slovníku výpočetní techniky slovo „metaznak“.
Hvězdičky jsou na místech, kde se prvek před nimi může vyskytnout alespoň jednou nebo se nemusí vyskytnout vůbec. Alternativa by byla místo <forma> <forma>*
napsat jen <forma>+
, ale zjevně by to byla marná snaha, pokud Vám unikla konvence hvězdičky, asi byste těžko pochopil plus. A já myslel, že tenhle (pravda, mírně neformální, ale celkem běžný) zápis budou znát všichni. Narážím na něj dnes a denně a regulární výrazy se taky snad běžně používají.
Není co chápat na tom, proč jsou jen na druhém řádku. Jako kdybyste říkal, že při čtení syntaxe Cčka (aby se ji naučil) musí člověk předem vědět, proč se kde v Cčku píší jaké závorky a kam který prvek jazyka. Omyl! Zápis syntaxe je tu právě od toho, aby mu řekl, kam má co psát.
Pokud nedokážete pochopit (k této domněnce mne vede zjevná nesouvislost vaší odpovědi a mého příspěvku, nebo přinejmenším souvislost neviditelná pro mne) ani takhle triviální zápis dvou nezávislých syntaktických konstrukcí (příklad formy if
a příklad formy cond
), jsem zvědavý, jak byste se tvářil na BNF zápis, který do toho zamíchá třeba ještě rekurzi.
(let (|ab| |aB| |Ab| |AB|) (loop for (a b c) in results if a if b collect c into |AB| else collect c into |Ab| else if b collect c into |aB| else collect c into |ab| finally (return (values |ab| |aB| |Ab| |AB|))))Ale určitě by to šlo i líp, já jsem začátečník... :-) Tohle je imperativní ekvivalent, zamyslím se nad čistším řešením. Ale tohle by mělo být čitelné i pro nelispera... ;-)
import win32com.client exc=win32com.client.Dispatch("Excel.Application") exc.Visible = 1 exc.Workbooks.Add() exc.Cells(1,1).Value = "Hello"Tohle je funkční ukázka vytvoření XLS souboru kde v buňce A1 je nápis Hello. Díky nastavení Visible = 1 se všechny příkazy zobrazují online. Je to snadné, stačí se "jen" naučit objektový model Excelu, Wordu a dalších COM serverů, jenž lze ve windows nalézt. Takže moje pozornost není zaměřená na další a další jazyky jako Guile. V jazyku mám jasno a teď zkoumám jeho různá využití. U Pythonu je vskutku co objevovat.
x = (a+b) / (c-d) y.attr = zpoužívá:
(setf x (/ (+ a b) (- c d))) (setf (attr y) z)skutečně nemohu považovat za přehledný. Tok programu totiž odporuje přirozenému (či ve škole naučenému, viz matematika, fyzika) myšlení. To nespravíte ani odsazováním a navíc tak máte jak náročné odsazování tak miliony nepřehledných (protože do sebe x krát vnořených) závorek. Vím co to znamená hledat zapomenutou závorku v Céčku, fakt bych to nechtěl dělat v Lispu :-).
"Tok programu totiž odporuje přirozenému (či ve škole naučenému, viz matematika, fyzika) myšlení."
Přirozené? Odkdy je na středověkém algebraickém zápisu něco "přirozeného"? To, že se z nějakého důvodu ujal? (A podotýkám, že vznikl v prostředí mnohem jednodušších jím zapisovaných problémů. Dnes máme trošku jinou dobu.)
"To nespravíte ani odsazováním a navíc tak máte jak náročné odsazování tak miliony nepřehledných (protože do sebe x krát vnořených) závorek. Vím co to znamená hledat zapomenutou závorku v Céčku, fakt bych to nechtěl dělat v Lispu :-). "
Nevím jak Vy, ale za mě všechny tyhle věci dělá editor, a to nejen v Lispu.
BTW, jestli je to opravdu zavedený zápis, vždycky přeci můžu použít:
#I( x = (a+b) / (c-d) ) #I( attr(y) = z )Což se převede na
(SETQ X (/ (+ A B) (- C D))) (SETQ (ATTR Y) Z)
Nevypadá to téměř stejně? :-) Uznávám, že by bylo dobré mírně CL-INFIX
modifikovat, kvůli tomu structu, ale syntaktický převod je ekvivalentní. Zkusím si ho někdy dát za domácí úkol. (Jestli se někdy dostanu domů... :-D) Navíc s objekty by to tak jako tak nefungovalo, CLOS není tak omezený, aby podporoval jen single-dispatch. A když už jsme u té srozumitelnosti jazyků:
„No proper program contains an indication which as an operator-applied occurrence identifies an operator-defining occurrence which as an indication-applied occurrence identifies an indication-defining occurrence different from the one identified by the given indication as an indication-applied occurrence.“
-- ALGOL 68 Report
Ideální pro začátečníky, že? ;-)
try: lists[x].append(y) except: lists[x]=[y]Misto:
lists.setdefault(x, []).append(y)Tj. pomoci vyjimek se zakladaji nove, neexistujici promenne, pritom v Pythonu na to existuje standardni konstrukce a vyjimky jsou v nem pomale. Nevim jestli to uz neni opravene, zkoumal jsem je dobre ped 1 - 2 roky a radu tech testu jsem dovedl optimalizovat pro vyssi vykon.
# encoding: utf-8 import time t1 = time.time() # priprava dat data = open('data.dat') vysledky = [] for line in data: a, b, v = line.split() vysledky.append((int(a)==1, int(b)==1, v)) data.close() t2 = time.time() # test 1 AB1 = [ v for a, b, v in vysledky if a and b] Ab1 = [ v for a, b, v in vysledky if a and not b] aB1 = [ v for a, b, v in vysledky if b and not a] ab1 = [ v for a, b, v in vysledky if not a and not b] t3 = time.time() # test 2 AB2 = []; Ab2 = []; aB2 = []; ab2 = [] for a, b, v in vysledky: if a and b: AB2.append(v) elif a and not b: Ab2.append(v) elif b and not a: aB2.append(v) else: ab2.append(v) t4 = time.time() print 'Příprava dat trvala %f s' % (t2-t1) print 'První test trval %f s' % (t3-t2) print 'Druhý test trval %f s' % (t4-t3)A výsledky jsou zde:
[wraith@frodo pokusy]$ python test.py Příprava dat trvala 6.605488 s První test trval 3.123812 s Druhý test trval 1.611570 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 6.658894 s První test trval 3.189925 s Druhý test trval 1.623393 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 6.636448 s První test trval 3.207551 s Druhý test trval 1.616027 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 6.630546 s První test trval 3.181450 s Druhý test trval 1.624684 s
[wraith@frodo ~]$ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 15 model : 2 model name : Intel(R) Pentium(R) 4 CPU 2.60GHz stepping : 9 cpu MHz : 3121.705 cache size : 512 KB physical id : 0 siblings : 2 fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe cid xtpr bogomips : 6176.76
vysledky.append((int(a)==1, int(b)==1, v))na:
vysledky.append((a=='1', b=='1', v))
[wraith@frodo pokusy]$ python test.py Příprava dat trvala 5.126848 s První test trval 3.094513 s Druhý test trval 1.562948 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 5.163060 s První test trval 3.137445 s Druhý test trval 1.569227 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 5.171682 s První test trval 3.089666 s Druhý test trval 1.550673 s
[wraith@frodo pokusy]$ python test.py Příprava dat trvala 3.537647 s První test trval 0.756269 s Druhý test trval 0.692954 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 3.397884 s První test trval 0.737806 s Druhý test trval 0.693551 s [wraith@frodo pokusy]$ python test.py Příprava dat trvala 3.404836 s První test trval 0.735210 s Druhý test trval 0.698294 s
Já už mu daroval mu ANSI Common Lisp od Grahama. (Je to opravdu velmi dobrý přítel... :-)) Nicméně ve Scheme již cosi udělal, ale nadává na PLT Scheme pro jeho pomalost. Překvapí vás, že v době, kdy už měl nějaký ten software ve Scheme napsaný, jsem mu musel vysvětlit, jak že to je se statickým scopingem a k čemu slouží LET? (To bylo v souvislosti s otázkou "jak udělám funkci, která si mezi dvěma voláními bude něco pamatovat, třeba jako static
proměnné v Cčku" :-)) Možná za to může ten AutoLISP... :-)))
Stejně se domnívám, že nakonec zvládneme on i já (já jsem taky pořád v zácviku :-)) jak Scheme, tak i Common Lisp a pak si budeme moci vybírat podle potřeby. (I když, nevím, uvidíme, jestli já budu dřív umět hrát ha harfu nebo on pracovat s modernějším Lispem. Já věřím tomu druhému, on mě přesvědčuje o tom prvním... ;-))
Příprava dat trvala 15.422000 s První test trval 3.875000 s Druhý test trval 2.000000 s ================== [4]> (load "test.fas") ;; Loading file test.fas ... Real time: 11.421875 sec. Run time: 10.140625 sec. Space: 136005080 Bytes GC: 24, GC time: 3.578125 sec. Bytes permanently allocated: 66792 Bytes currently in use: 33629196 Bytes available until next GC: 8407299 Alokovanych bajtu: 33629196 Real time: 0.703125 sec. Run time: 0.671875 sec. Space: 8000032 Bytes Real time: 0.78125 sec. Run time: 0.734375 sec. Space: 8000032 Bytes AB: 250788 aB: 249885 Ab: 249285 ab: 250042 ;; Loaded file test.fas TSempron 2500+, DDR SDRAM 266 MHz paměti. Tohle jsou Windows 2000, CLISP 2.34 a Python 2.4.1. Zkoušel jsem ještě CMUCL kompilátor v Linuxu, tam to bylo asi 0.6 sekundy, ovšem stroj byl 300 MHz P II. Zkusím CMUCL i na tom Sempronu a hlavně zapnu v kompilátoru nějaké ty optimalizace, tohle je off-the-head kód, který si jen tak funguje, ale asi moc hezký není. Jo a Python spotřeboval asi 90 MB paměti, CLISP asi 40 MB. To se podle mě taky počítá...
(macroexpand '(cond ((= a 1) 12) ((= a 2) 35) ((= a 3) 551) (t 3214)))Výsledek by měl být něco jako
(IF (= A 1) 12 (IF (= A 2) 35 (IF (= A 3) 551 3214)))Což je na LISPu naprosto skvělé, člověk si může spoustu vnitřností prohlédnout takhle jednoduše. :-)
destructuring-bind
:-D Akorát poslední týden na potěšení není čas, pitomé termíny... :-(
real time : 5.520 secs run-gbc time : 4.130 secs child run time : 0.000 secs gbc time : 1.280 secs real time : 13.990 secs run-gbc time : 6.100 secs child run time : 0.000 secs gbc time : 7.790 secs real time : 3.980 secs run-gbc time : 2.350 secs child run time : 0.000 secs gbc time : 1.630 secsJestli to chápu, tak načtení datového souboru 5,5 s, a dva různé testy 13,9 s a 3,9 s. No, jako interpret tedy nic moc. Jestli mi někdo poradí, jak to zkompilovat, budu rád. Také by mě zajímalo, jak to spustit, aniž bych po skončení programu zůstal viset v interaktivní konzoli, za prvé mě to rozčiluje, za druhé pak programy v lispu takto nejde spouštět třeba ze skriptů.
import time, psyco, gc psyco.full() def run(): t1 = time.time() data = [(x[0]=='1', x[2]=='1', x[4:6]) for x in open('data.dat')] t2 = time.time() AB, Ab, aB, ab = [], [], [], [] for a, b, v in data: if a and b: AB.append(v) elif a and not b: Ab.append(v) elif b and not a: aB.append(v) else: ab.append(v) t3 = time.time() print 'Data: %.3f s' % (t2-t1) print 'Test: %.3f s' % (t3-t2) return data, AB, Ab, aB, ab t=time.time() gc.disable() run() gc.enable() print 'Run: %.3f s' % (time.time()-t)A spustil ji ve windows v Pythonu 2.4, výsledky jsou fajn:
F:\proj\test>python test.py Data: 0.453 s Test: 0.187 s Run: 0.859 s F:\proj\test>python test.py Data: 0.453 s Test: 0.188 s Run: 0.844 s F:\proj\test>python test.py Data: 0.454 s Test: 0.187 s Run: 0.860 s
Mimochodem, za takovéhle příspěvky by se asi v newsgroupě objevilo "RTFM". Snad si umíte přečíst dokumentaci, ne? Implementace GC je překvapivě záležitost implementace, ne jazyka, který od toho odstiňuje a dost možná je v jeho specifikaci výslovně zmínka, že tyhle věci se v normě jazyka _neřeší_. Schválně se podívám. Kód, který jsem poslal, je spustitelný v CLISPu a CMUCL, jak jsem psal. Až mi váš kód nebude fungovat v IronPythonu nebo v Jythonu, mám taky začít nadávat?
A pokud se chcete naučit Common LISP nenásilnou formou, zkuste třeba http://www.gigamonkeys.com - ta knížka je výborná. Je to Common LISP, tak, jak je popsaný v HyperSpecu, ne konkrétní implementace - radši to předesílám předem.
„Není tu ale deset různých nekompatibilních implementací Pythonu pro to samé prostředí. Tohle skutečně hodnotu Lispu snižuje.“
Tak tohle jsem nepochopil. Jednak ta nekompatibilita je pouze v nestandardizovaných věcech, což je typicky malá část programu (a už jsem to v mnohla LISPovských kódech viděl, třeba 200-300 kB kódu společného a 5-15 kB kódu pro každou implementaci - de facto hnída), jednak - proč je možnost výběru nevýhodou? Prostě si vyberte jednu implementaci, tu používejte, na ostatní zapomeňte...lo and behold! Máte jednu implementaci. ;-)
BTW, ty tři implementace Pythonu jsou na tom asi stejně jako ty LISPy - každý je dobrý v něčem jiném, pokud jde o interakci se zbytkem světa.
import pygtk pygtk.require('2.0') import gtkAle dnes už to nepoužívám, protože většinou mám prostředí kde mé aplikace poběží pod kontrolou a GTK1 je už mrtvé.
Ale to si pletete implementaci a jazyk. :-)
Použil jsem CLISP a CMUCL, což jsou dvě implementace, které se mi dost líbí (CMUCL je výkonnostně možná nejlepší LISP vůbec), a ten benchmark jsem pustil interaktivně:
CLISP:(compile-file "neco.lisp") (load "neco.fas")nebo CMUCL:
(compile-file "neco.lisp") (load "neco.x86f")
případně to nějak narvat do parametrů příkazového řádku, ale to jsem zatím nepotřeboval. Ostatně v obou implenentacích se dá aplikace zabalit do image tak, že se po spuštění image ve VM spustí rovnou zadaná funkce, u CMUCL se to snad dá udělat i přímo spustitelné.
Vybrat si GCL, to je odvaha, tam jsou věci trošku složitější a zatím s ním nemám zkušenosti.
Jo a samozřejmě je dobré použít správnou cestu k souboru s daty.
-module(trizeni). -export([proved/1]). proved(Vysledky) -> Trid = fun ([ true,true,X ],{ A,B,C,D }) -> { [X | A],B,C,D }; ([ true,false,X ],{ A,B,C,D }) -> { A,[X | B],C,D }; ([ false,true,X ],{ A,B,C,D }) -> { A,B,[X | C],D }; ([ false,false,X ],{ A,B,C,D }) -> { A,B,C,[X | D] } end, lists:foldl(Trid,{[],[],[],[]},Vysledky).Z interaktivního shellu nebo jiného modulu/programu se pak tato funkce zavolá např. takto:
{ AABB,AAB,ABB,AB } = trizeni:proved([true,true,1],[true,false,2],[false,true,3],[false,false,4]]).A poté mohu s proměnnými AABB apod. dále pracovat. Jména byla zvolena jinak vzhledem k tomu, že v Erlangu musí jméno proměnné začínat velkým písmenem.
Franto, nezapomeň koupit: půl chleba litr mléka deset vajíčekČistě teoreticky tam ta dvojtečka taky být nemusí, stačí odsazení, ne? Jenže typografie (obor zabývající se předávání informací písemnou formou co nejsrozumitelnějším způsobem), která se vyvíjí po staletí dospěla k tomuto řešení, bez dvojtečky by to bylo málo přehledné. Takže i kdyby ta dvojtečka tam teoreticky nepotřebovala být, tak tam být musí, aby kód byl přehledný a čitelný, na což se u Pythonu klade důraz.
Python v žádném případě není jednoduchý. Jediné jednoduché jazyky, které znám jsou Lisp, Scheme, FORTH, Smalltalk, Self a případně i TCL, i když ty na začítku seznamu vedou.
Čitelný bloatware je pořád bloatware. Nic proti tomu, že je to snadno naučitelný bloatware (mám Python rád, stejně tak i Ruby), aspoň má výhody oproti megabloatwaru s názvem „C++“, který má z mého pohledu nejhorščí poměr bloat/užitečnost v celé historii programování, ale pořád jím zůstává.
# ---------------------------- # funkce pro vykresleni hlavniho okna proc fncHlavniOkno {} { global PRVNI DRUHY TRETI CTVRTY PATY set PRVNI 1 set DRUHY 1 set TRETI 1 set CTVRTY 0 set PATY 0 # vytvoreni komponent okna frame .c checkbutton .c.prvni -text "Prvni" -variable PRVNI \ -onvalue 1 -offvalue 0 checkbutton .c.druhy -text "Druhy" -variable DRUHY \ -onvalue 1 -offvalue 0 checkbutton .c.treti -text "Treti" -variable TRETI \ -onvalue 1 -offvalue 0 checkbutton .c.ctvrty -text "Ctvrty" -variable CTVRTY \ -onvalue 1 -offvalue 0 checkbutton .c.paty -text "Paty" -variable PATY \ -onvalue 1 -offvalue 0 button .stav -text "Vytiskni stav" -width 15 -command {fncStav} # usporadani komponent okna grid .c -row 0 -column 0 -sticky "W" grid .c.prvni -row 0 -column 0 -sticky "W" grid .c.druhy -row 1 -column 0 -sticky "W" grid .c.treti -row 2 -column 0 -sticky "W" grid .c.ctvrty -row 3 -column 0 -sticky "W" grid .c.paty -row 4 -column 0 -sticky "W" grid .stav -row 1 -column 0 -sticky "W" } # zjisteni a vytisteni stavu checkboxu proc fncStav {} { set ls [winfo children .c] set out [open "file.log" a] foreach ctrl $ls { set outln "[$ctrl cget -text] : " set var [$ctrl cget -variable] global $var if {[expr $$var]} { append outln "vybran" } else { append outln "nevybran" } puts $out $outln } close $out } fncHlavniOkno # ----------------------------Kdyz jej date do souboru a nastavite spustitelne atributy, bude to fungovat. Protoze momentalne nejsem na linuxu ale na win, vyresil jsem vystup do logovaciho souboru (viz. fncStav), po jeji zmene na:
proc fncStav {} { set ls [winfo children .c] foreach ctrl $ls { set outln "[$ctrl cget -text] : " set var [$ctrl cget -variable] global $var if {[expr $$var]} { append outln "vybran" } else { append outln "nevybran" } puts $outln } }by to melo psat do shellu - momentalne nemuzu slouzit s otestovanim :-)
#!/bin/env python # -*- coding: utf-8 -*- checkNames = ['První', 'Druhý', 'Třetí', 'Čtvrtý', 'Pátý'] # TK VARIANTA ############################################################ # import Tkinter as tk # # # obsluha udalostí ------------------------------------------------------# # checks = [] # def printStatus(): # global checks # for name, status in checks: # if status.get(): # print name, "je zatžen." # else: # print name, "není zatržen." # # # vytvoření GUI ---------------------------------------------------------# # root = tk.Tk() # # frame = tk.Frame(root) # frame.pack() # # for name in checkNames: # var = tk.IntVar() # checks.append([name, var]) # widget = tk.Checkbutton(frame, text=name, variable=var) # widget.pack() # # pButton = tk.Button(frame, text="Tiskni výsledky", command=printStatus) # pButton.pack() # # # čekání na událost -----------------------------------------------------# # root.mainloop() # # ####################################################################### # GTK VARIANTA ########################################################### # import gtk # # # obsluha udalostí ------------------------------------------------------# # def printStatus(button, checks): # for check in checks: # if check.get_active(): # print check.get_label(), "je zatržen." # else: # print check.get_label(), "není zatržen." # # # vytvoření GUI ---------------------------------------------------------# # vbox = gtk.VBox() # # checks = [ gtk.CheckButton(label=name) for name in checkNames ] # for check in checks: # vbox.pack_start( check ) # # qButton = gtk.Button( label="Vytiskni stav" ) # qButton.connect( 'clicked', printStatus, checks ) # vbox.pack_start(qButton) # # win = gtk.Window() # win.connect( 'destroy', lambda x: gtk.main_quit() ) # win.add(vbox) # win.show_all() # # # čekání na událost -----------------------------------------------------# # gtk.main() # # #######################################################################
import wx class ChecksDialog(wx.Dialog): ID_BUTTON_PRINT = 5001 def __init__(self, parent, ID, title): wx.Dialog.__init__(self, parent, ID, title) sizer = wx.BoxSizer(wx.VERTICAL) labels = ['first', 'second', 'third', 'fourth', 'fifth'] self.checks = [wx.CheckBox(self, -1, label) for label in labels] for check in self.checks: sizer.Add(check, 0, wx.ALL, 5) button = wx.Button(self, self.ID_BUTTON_PRINT, 'Print') sizer.Add(button, 0, wx.ALL|wx.ALIGN_CENTER, 5) wx.EVT_BUTTON(self, self.ID_BUTTON_PRINT, self.OnButton) self.SetSizerAndFit(sizer) def OnButton(self, event): for check in self.checks: if check.IsChecked(): print check.GetLabel(), ' checked' else: print check.GetLabel(), ' not checked' class ChecksApp(wx.App): def OnInit(self): dlg = ChecksDialog(None, -1, "Checkboxes Demo") dlg.Show(True) self.SetTopWindow(dlg) return True app = ChecksApp(0) app.MainLoop()
#!/usr/bin/python # -*- coding: iso8859-2 import wx class ChecksDialog(wx.Dialog): ID_BUTTON_PRINT = 5001 def __init__(self, parent, ID, title): wx.Dialog.__init__(self, parent, ID, title) sizer = wx.BoxSizer(wx.VERTICAL) labels = ['first', 'second', 'third', 'fourth', 'fifth'] self.checks = [wx.CheckBox(self, -1, label) for label in labels] for check in self.checks: sizer.Add(check, 0, wx.ALL, 5) button = wx.Button(self, self.ID_BUTTON_PRINT, 'Print') sizer.Add(button, 0, wx.ALL|wx.ALIGN_CENTER, 5) wx.EVT_BUTTON(self, self.ID_BUTTON_PRINT, self.OnButton) wx.EVT_CLOSE(self, self.OnQuit) self.SetSizerAndFit(sizer) def OnButton(self, event): for check in self.checks: if check.IsChecked(): print check.GetLabel(), ' checked' else: print check.GetLabel(), ' not checked' def OnQuit(self, event): self.Destroy() class ChecksApp(wx.App): def OnInit(self): dlg = ChecksDialog(None, -1, "Checkboxes Demo") dlg.Show(True) self.SetTopWindow(dlg) return True app = ChecksApp(0) app.MainLoop()