3 | ||
Editor: mol
Time: 2013/08/28 14:39:20 GMT+2 |
||
Note: |
changed: - <img src="py25.png" align=right> Na počátku byl v konferenci py.cz nevinný dotaz: Jak se udělá v pythonu mřížka s devíti čarami svisle a devíti čarami vodorovně? Někdo se dožadoval upřesnění, někdo od ruky vysmahnul textové řešení. Pár odpovědí:: # Napr. takto :-) # _ _ _ _ _ _ _ _ # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| Ale teraz vazne. Z Vasej otazky nie je sasne, na co presne potrebujete tu mriezku. V samotnom Pythone vytvorite mriezku pravdepodobne tazko. Ak potrebujete mriezku nakreslit do obrazku, skuste pouzit komponentu PIL alebo balik graphics z frameworku Reportlab. Nebo:: Já vám dám mřížku. Budete na to potřebovat specielně licencovanou knihovnu od Microsoftu. Další možnost je toto: x=y=20 print ' ' + '_' * (2*x-1) + ('\n|' + '_|' * x) * y EULA: Tento zdrojový kód je možné použít a šířit pouze v případě jeho plného grokování. Hezký den. Pak se, po čase, objevil následující příspěvek, který rozpoutal tu pravou diskuzi:: from Tkinter import * import random KROK=30 # velikost jednoho ctverecku OKRAJ=20 # velikost okraje DELKA=10 # pocet poli BARVA={0:'white',1:'red', 2:'lightgreen'} # barvicky (free bonus) def ctverec(x,y,vypln): "Vytiskne ctverecek v souradnicich x,y a s vyplni" x=x*KROK+OKRAJ y=y*KROK+OKRAJ canvas.create_rectangle(x,y,x+KROK,y+KROK,fill=BARVA[vypln]) def sachovnice(): "Vymalovani sachovnice bunek" for y in range(DELKA): for x in range(DELKA): bakterie=(random.randint(0,2)) ctverec(x,y, bakterie) # inicializace Tkinter root=Tk() root.title("Sachovnice") frame=Frame(root) frame.pack() canvas=Canvas(frame, bg='white', height=DELKA*KROK+2*OKRAJ, width=DELKA*KROK+2*OKRAJ) canvas.pack() # vykresleni sachovnice sachovnice() root.mainloop() Jen pár reakcí: - Jo, jo -- Pavel je zatim vitez ;-) Jeste nejaky pohyb by to chtelo ;-) - Dovolil jsem si drobnou úpravu. Protože se jako klíče slovníku BARVA používala čísla 0 až 2, může se to změnit na jednodušší strukturu -- seznam. Drobnou úpravou se pak dá zajistit, že se použijí všechny barvy, kterými seznam naplním (doplněna žlutá). Místo range(DELKA) je lepší používat xrange(DELKA). Osobně považuji takové příklady za vynikající prostředek k diskusi. Vždycky se na tom dá najít nějaký chlup (je jich tam ještě hodně) a vždycky se na tom dá dozvědět něco nového (i když to sleduji jen pasivně). Navrhuji došolichat ten příklad do vzorové podoby (i co se týká stylu), vytvořit z toho nějaký dokument (HTML) a zařadit to do nějakých školiček včetně zpracované podoby nastávající diskuse. A taky navrhuji, předělat to do ryze české podoby, včetně českých komentářů a textů. Zvýrazní se tím nové problémy, které se v reálných českých aplikacích musí řešit:: from Tkinter import * import random KROK=30 # velikost jednoho ctverecku OKRAJ=20 # velikost okraje DELKA=10 # pocet poli BARVA=['white', 'red', 'lightgreen', 'yellow'] # barvicky (free bonus) def ctverec(x,y,vypln): "Vytiskne ctverecek v souradnicich x,y a s vyplni" x=x*KROK+OKRAJ y=y*KROK+OKRAJ canvas.create_rectangle(x,y,x+KROK,y+KROK,fill=BARVA[vypln]) def sachovnice(): "Vymalovani sachovnice bunek" for y in xrange(DELKA): for x in xrange(DELKA): bakterie=(random.randint(0,len(BARVA)-1)) ctverec(x,y, bakterie) # inicializace Tkinter root=Tk() root.title("Sachovnice") frame=Frame(root) frame.pack() canvas=Canvas(frame, bg='white', height=DELKA*KROK+2*OKRAJ, width=DELKA*KROK+2*OKRAJ) canvas.pack() # vykresleni sachovnice sachovnice() root.mainloop() range a xrange No a pak vznikla válka mezi range a xrange. Zastánci range měli v rukávu jen to, že se to doteď dělalo tak, tak proč nějaké novinky. Xrange-isti zase výhled do budoucna. Padaly poznámky na rychlost, efektivitu, atd. Jeden příspěvek za všechny:: >>Místo range(DELKA) je lepší používat xrange(DELKA). > >> >> co se tyká budoucnosti moc ne .... >> xrange je na seznamu to be removed >> http://www.python.org/peps/pep-3000.html >> tak ze pod budoucími verzemi pythonu nepouzitelne Dovolím si důrazně nesouhlasit. Stejný dokument říká, že range() má vracet iterátor. Jinými slovy to znamená, že se staré range() má zcela zrušit a xrange() se má přejmenovat na range(). Uvedený dokument je navíc věnován "hypotetické budoucí verzi Pythonu" a slouží spíš pro diskusi a ověřování nápadů při dalším vývoji. Hlavním důvodem pro můj důrazný nesouhlas je rozdíl ve funčnosti (efektivnosti) range() a xrange(). Jméno není tak důležité. Přejmenování funkce se dá v Pythonu dosáhnout velmi snadno: >>>>>> range <built-in function range> >>>>>> xrange <type 'xrange'> >>>>>> range = xrange >>>>>> range <type 'xrange'> >>>>>> Tím už nyní dosáhnu toho, že se zahodí odkaz na zabudovanou funkci range() a pod tímto jménem se podstrčí xrange(). Funguje to ale jenom v daném (lokálním) prostoru jmen. Aby budoucí verze Pythonu neznemožnila používání starších programů, které používají xrange(), může provést něco takového (trochu chytřeji): def xrange(): # print 'Varovani...' return range() To znamená, že všude, kde budu používat (v té době již nepodporovanou) funkci xrange(), bude potichu nahrazena použitím nové range(). Jakmile to bude aktuální, dá se najevo změna trochu hlasitěji (naznačeno zakomentovaným printem). Také se probrala otázka češtiny v programech a její užitečnost, bublinová nápověda, Style guide, a další. Vcelku široký záběr. Pak ještě byl script ještě upraven a také převeden na pygame platformu:: Přidal jsem funkci sachovniceKlik - překreslení sachovnice. A přidal i výpis souřadnice myši, aby případný zájemce viděl podstatu věci. A přejmenování ctverec --> bunka. Ženský rod láká více pozornosti ;-) a je to méně otřepané. [Tkinter] :: # -*- coding: cp1250 -*- from Tkinter import * import random KROK = 30 # velikost jedné buňky OKRAJ = 20 # velikost okraje DELKA = 10 # počet polí POZADI = 'white' # barva pozadí BARVA = ['white', 'orangered', 'lightgreen', 'yellow'] # barvičky def bunka(souradnice, barva): u"""Vytiskne buňku na plátno v souřadnicích (x, y) zadanou barvou.""" x=souradnice[0] y=souradnice[1] # výpočet pixelových souřadnic rohů buňky levy = x*KROK + OKRAJ pravy = levy + KROK horni = y*KROK + OKRAJ dolni = horni + KROK platno.create_rectangle(levy, horni, pravy, dolni, fill=barva) def sachovnice(): u"""Vymalování šachovnice na plátno s náhodnou barvou v buňce.""" for y in xrange(DELKA): for x in xrange(DELKA): bakterie = random.randint(0,len(BARVA)-1) bunka((x, y), BARVA[bakterie]) def sachovniceKlik(udalost): u"""Pomocná funkce při volání z kliku myši.""" print u"Souřadnice myši: (%i, %i)" % (udalost.x, udalost.y) sachovnice() # Inicializace Tkinter. root = Tk() root.title(u"Šachovnice") root.bind('<Button-1>', sachovniceKlik) frame = Frame(root) frame.pack() # Vytvoření mého plátna, na které se bude kreslit platno = Canvas(frame, bg=POZADI, height=DELKA*KROK+2*OKRAJ, width=DELKA*KROK+2*OKRAJ) platno.pack() # Vykreslení šachovnice na moje plátno sachovnice() # Spuštění uživatelského rozhraní root.mainloop() Pygame :: # -*- coding: cp1250 -*- import pygame, random from pygame.locals import * KROK = 30 # velikost jedné buňky OKRAJ = 20 # velikost okraje DELKA = 10 # počet polí POZADI = 'white' # barva pozadí BARVA = ['white', 'orangered', 'lightgreen', 'yellow'] # barvičky def bunka(souradnice, barva): u"""Vytiskne buňku na plátno v souřadnicích (x, y) zadanou barvou.""" x=souradnice[0] y=souradnice[1] # výpočet souřadnic poziceX = x*KROK + OKRAJ poziceY = y*KROK + OKRAJ sirka = KROK + 1 vyska = KROK + 1 umisteni = pygame.Rect(poziceX, poziceY, sirka, vyska) # Vybarvení plochy buňky pygame.draw.rect(platno, barva, umisteni) # Vybarvení černého rámečku kolem buňky pygame.draw.rect(platno, pygame.color.Color('black'), umisteni, 1) def sachovnice(): u"""Vymalování šachovnice na plátno s náhodnou barvou v buňkách.""" for y in xrange(DELKA): for x in xrange(DELKA): bakterie = random.randint(0,len(BARVA)-1) bunka((x, y), pygame.color.Color(BARVA[bakterie])) # Inicializace pygame sirkaPlochy = DELKA*KROK+2*OKRAJ vyskaPlochy = DELKA*KROK+2*OKRAJ platno = pygame.display.set_mode((sirkaPlochy, vyskaPlochy)) platno.fill(pygame.color.Color(POZADI)) hodiny=pygame.time.Clock() # Vykreslení šachovnice na plátno sachovnice() pygame.display.flip() # Čekání na události opakovat=1 while opakovat: for udalost in pygame.event.get(): if udalost.type == pygame.QUIT: # Končíme opakovat=0 if udalost.type == MOUSEBUTTONDOWN: # Překreslíme šachovnici print u"Souřadnice myši: ", udalost.pos sachovnice() pygame.display.flip() pygame.quit() # úklid [PyQt_PySide] :: # -*- coding: utf-8 -*- # # Nevim, co je presne zadani, ale tohle je taky mrizka 9x9... from qt import * from qttable import QTable import sys # velikost bunky "mrizky" SIZE = 30 class MainForm(QMainWindow): def __init__(self,parent = None,name = None,fl = 0): # inicializace okna QMainWindow.__init__(self,parent,name,fl) self.setCaption('Qt Mrizka - at uz je to cokoli...') self.setCentralWidget(QWidget(self,"qt_central_widget")) mainFromLayout = QGridLayout(self.centralWidget(),1,1,11,6,"mainFromLayout") # samotna "mrizka" self.mrizka = QTable(self.centralWidget(),"mrizka") self.mrizka.setLineWidth(1) self.mrizka.setNumRows(9) self.mrizka.setNumCols(9) # zmena velikosti bunek, to uz je jen jako bonus... for i in range(self.mrizka.numRows()): self.mrizka.setRowHeight(i, SIZE) for j in range(self.mrizka.numCols()): self.mrizka.setColumnWidth(j, SIZE) # zarovnani v oknu mainFromLayout.addWidget(self.mrizka,0,0) if __name__ == '__main__': app = QApplication(sys.argv) app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()')) mw = MainForm() mw.show() app.setMainWidget(mw) app.exec_loop() [Tkinter] - jako tlačítka :: from Tkinter import * hlavni= Tk() pocetBunek=9 velikost=4 for i in range(pocetBunek*pocetBunek): radek=i/pocetBunek # vypocet cisla radky sloupec=i%pocetBunek # vypocet cisla sloupce tlacitko=Button(hlavni, text=str(i+1), width=velikost*2, height=velikost) tlacitko.grid(row=radek, column=sloupec) hlavni.mainloop()
Na počátku byl v konferenci py.cz nevinný dotaz:
Někdo se dožadoval upřesnění, někdo od ruky vysmahnul textové řešení. Pár odpovědí:
# Napr. takto :-) # _ _ _ _ _ _ _ _ # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| # |_|_|_|_|_|_|_|_| Ale teraz vazne. Z Vasej otazky nie je sasne, na co presne potrebujete tu mriezku. V samotnom Pythone vytvorite mriezku pravdepodobne tazko. Ak potrebujete mriezku nakreslit do obrazku, skuste pouzit komponentu PIL alebo balik graphics z frameworku Reportlab.
Nebo:
Já vám dám mřížku. Budete na to potřebovat specielně licencovanou knihovnu od Microsoftu. Další možnost je toto: x=y=20 print ' ' + '_' * (2*x-1) + ('\n|' + '_|' * x) * y EULA: Tento zdrojový kód je možné použít a šířit pouze v případě jeho plného grokování. Hezký den.
který rozpoutal tu pravou diskuzi:
from Tkinter import * import random KROK=30 # velikost jednoho ctverecku OKRAJ=20 # velikost okraje DELKA=10 # pocet poli BARVA={0:'white',1:'red', 2:'lightgreen'} # barvicky (free bonus) def ctverec(x,y,vypln): "Vytiskne ctverecek v souradnicich x,y a s vyplni" x=x*KROK+OKRAJ y=y*KROK+OKRAJ canvas.create_rectangle(x,y,x+KROK,y+KROK,fill=BARVA[vypln]) def sachovnice(): "Vymalovani sachovnice bunek" for y in range(DELKA): for x in range(DELKA): bakterie=(random.randint(0,2)) ctverec(x,y, bakterie) # inicializace Tkinter root=Tk() root.title("Sachovnice") frame=Frame(root) frame.pack() canvas=Canvas(frame, bg='white', height=DELKA*KROK+2*OKRAJ, width=DELKA*KROK+2*OKRAJ) canvas.pack() # vykresleni sachovnice sachovnice() root.mainloop()
from Tkinter import * import random KROK=30 # velikost jednoho ctverecku OKRAJ=20 # velikost okraje DELKA=10 # pocet poli BARVA=['white', 'red', 'lightgreen', 'yellow'] # barvicky (free bonus) def ctverec(x,y,vypln): "Vytiskne ctverecek v souradnicich x,y a s vyplni" x=x*KROK+OKRAJ y=y*KROK+OKRAJ canvas.create_rectangle(x,y,x+KROK,y+KROK,fill=BARVA[vypln]) def sachovnice(): "Vymalovani sachovnice bunek" for y in xrange(DELKA): for x in xrange(DELKA): bakterie=(random.randint(0,len(BARVA)-1)) ctverec(x,y, bakterie) # inicializace Tkinter root=Tk() root.title("Sachovnice") frame=Frame(root) frame.pack() canvas=Canvas(frame, bg='white', height=DELKA*KROK+2*OKRAJ, width=DELKA*KROK+2*OKRAJ) canvas.pack() # vykresleni sachovnice sachovnice() root.mainloop()
No a pak vznikla válka mezi range a xrange. Zastánci range měli v rukávu jen to, že se to doteď dělalo tak, tak proč nějaké novinky. Xrange-isti zase výhled do budoucna. Padaly poznámky na rychlost, efektivitu, atd. Jeden příspěvek za všechny:
>>Místo range(DELKA) je lepší používat xrange(DELKA). > >> >> co se tyká budoucnosti moc ne .... >> xrange je na seznamu to be removed >> http://www.python.org/peps/pep-3000.html >> tak ze pod budoucími verzemi pythonu nepouzitelne Dovolím si důrazně nesouhlasit. Stejný dokument říká, že range() má vracet iterátor. Jinými slovy to znamená, že se staré range() má zcela zrušit a xrange() se má přejmenovat na range(). Uvedený dokument je navíc věnován "hypotetické budoucí verzi Pythonu" a slouží spíš pro diskusi a ověřování nápadů při dalším vývoji. Hlavním důvodem pro můj důrazný nesouhlas je rozdíl ve funčnosti (efektivnosti) range() a xrange(). Jméno není tak důležité. Přejmenování funkce se dá v Pythonu dosáhnout velmi snadno: >>>>>> range <built-in function range> >>>>>> xrange <type 'xrange'> >>>>>> range = xrange >>>>>> range <type 'xrange'> >>>>>> Tím už nyní dosáhnu toho, že se zahodí odkaz na zabudovanou funkci range() a pod tímto jménem se podstrčí xrange(). Funguje to ale jenom v daném (lokálním) prostoru jmen. Aby budoucí verze Pythonu neznemožnila používání starších programů, které používají xrange(), může provést něco takového (trochu chytřeji): def xrange(): # print 'Varovani...' return range() To znamená, že všude, kde budu používat (v té době již nepodporovanou) funkci xrange(), bude potichu nahrazena použitím nové range(). Jakmile to bude aktuální, dá se najevo změna trochu hlasitěji (naznačeno zakomentovaným printem).
Také se probrala otázka češtiny v programech a její užitečnost, bublinová nápověda, Style guide, a další. Vcelku široký záběr.
byl script ještě upraven a také převeden na pygame platformu:
Přidal jsem funkci sachovniceKlik - překreslení sachovnice. A přidal i výpis souřadnice myši, aby případný zájemce viděl podstatu věci. A přejmenování ctverec --> bunka. Ženský rod láká více pozornosti ;-) a je to méně otřepané.
# -*- coding: cp1250 -*- from Tkinter import * import random KROK = 30 # velikost jedné buňky OKRAJ = 20 # velikost okraje DELKA = 10 # počet polí POZADI = 'white' # barva pozadí BARVA = ['white', 'orangered', 'lightgreen', 'yellow'] # barvičky def bunka(souradnice, barva): u"""Vytiskne buňku na plátno v souřadnicích (x, y) zadanou barvou.""" x=souradnice[0] y=souradnice[1] # výpočet pixelových souřadnic rohů buňky levy = x*KROK + OKRAJ pravy = levy + KROK horni = y*KROK + OKRAJ dolni = horni + KROK platno.create_rectangle(levy, horni, pravy, dolni, fill=barva) def sachovnice(): u"""Vymalování šachovnice na plátno s náhodnou barvou v buňce.""" for y in xrange(DELKA): for x in xrange(DELKA): bakterie = random.randint(0,len(BARVA)-1) bunka((x, y), BARVA[bakterie]) def sachovniceKlik(udalost): u"""Pomocná funkce při volání z kliku myši.""" print u"Souřadnice myši: (%i, %i)" % (udalost.x, udalost.y) sachovnice() # Inicializace Tkinter. root = Tk() root.title(u"Šachovnice") root.bind('<Button-1>', sachovniceKlik) frame = Frame(root) frame.pack() # Vytvoření mého plátna, na které se bude kreslit platno = Canvas(frame, bg=POZADI, height=DELKA*KROK+2*OKRAJ, width=DELKA*KROK+2*OKRAJ) platno.pack() # Vykreslení šachovnice na moje plátno sachovnice() # Spuštění uživatelského rozhraní root.mainloop()
# -*- coding: cp1250 -*- import pygame, random from pygame.locals import * KROK = 30 # velikost jedné buňky OKRAJ = 20 # velikost okraje DELKA = 10 # počet polí POZADI = 'white' # barva pozadí BARVA = ['white', 'orangered', 'lightgreen', 'yellow'] # barvičky def bunka(souradnice, barva): u"""Vytiskne buňku na plátno v souřadnicích (x, y) zadanou barvou.""" x=souradnice[0] y=souradnice[1] # výpočet souřadnic poziceX = x*KROK + OKRAJ poziceY = y*KROK + OKRAJ sirka = KROK + 1 vyska = KROK + 1 umisteni = pygame.Rect(poziceX, poziceY, sirka, vyska) # Vybarvení plochy buňky pygame.draw.rect(platno, barva, umisteni) # Vybarvení černého rámečku kolem buňky pygame.draw.rect(platno, pygame.color.Color('black'), umisteni, 1) def sachovnice(): u"""Vymalování šachovnice na plátno s náhodnou barvou v buňkách.""" for y in xrange(DELKA): for x in xrange(DELKA): bakterie = random.randint(0,len(BARVA)-1) bunka((x, y), pygame.color.Color(BARVA[bakterie])) # Inicializace pygame sirkaPlochy = DELKA*KROK+2*OKRAJ vyskaPlochy = DELKA*KROK+2*OKRAJ platno = pygame.display.set_mode((sirkaPlochy, vyskaPlochy)) platno.fill(pygame.color.Color(POZADI)) hodiny=pygame.time.Clock() # Vykreslení šachovnice na plátno sachovnice() pygame.display.flip() # Čekání na události opakovat=1 while opakovat: for udalost in pygame.event.get(): if udalost.type == pygame.QUIT: # Končíme opakovat=0 if udalost.type == MOUSEBUTTONDOWN: # Překreslíme šachovnici print u"Souřadnice myši: ", udalost.pos sachovnice() pygame.display.flip() pygame.quit() # úklid
# -*- coding: utf-8 -*- # # Nevim, co je presne zadani, ale tohle je taky mrizka 9x9... from qt import * from qttable import QTable import sys # velikost bunky "mrizky" SIZE = 30 class MainForm(QMainWindow): def __init__(self,parent = None,name = None,fl = 0): # inicializace okna QMainWindow.__init__(self,parent,name,fl) self.setCaption('Qt Mrizka - at uz je to cokoli...') self.setCentralWidget(QWidget(self,"qt_central_widget")) mainFromLayout = QGridLayout(self.centralWidget(),1,1,11,6,"mainFromLayout") # samotna "mrizka" self.mrizka = QTable(self.centralWidget(),"mrizka") self.mrizka.setLineWidth(1) self.mrizka.setNumRows(9) self.mrizka.setNumCols(9) # zmena velikosti bunek, to uz je jen jako bonus... for i in range(self.mrizka.numRows()): self.mrizka.setRowHeight(i, SIZE) for j in range(self.mrizka.numCols()): self.mrizka.setColumnWidth(j, SIZE) # zarovnani v oknu mainFromLayout.addWidget(self.mrizka,0,0) if __name__ == '__main__': app = QApplication(sys.argv) app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()')) mw = MainForm() mw.show() app.setMainWidget(mw) app.exec_loop()
from Tkinter import * hlavni= Tk() pocetBunek=9 velikost=4 for i in range(pocetBunek*pocetBunek): radek=i/pocetBunek # vypocet cisla radky sloupec=i%pocetBunek # vypocet cisla sloupce tlacitko=Button(hlavni, text=str(i+1), width=velikost*2, height=velikost) tlacitko.grid(row=radek, column=sloupec) hlavni.mainloop()