
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()