Seite 1 von 2
Würfel
Verfasst: Montag 1. Juni 2009, 19:13
von Clockworx
Ich möchte mit python einen "Würfel" erstellen. Das stelle ich mir so vor:
Man hat ein Fenster mit einem button, auf dem "würfeln" steht. wenn man darauf drückt, soll eine zufällige Zahl zwischen 1-6 erscheinen. Dies kann man dann beliebig viel wiederholen.
Ich habe wenig Vorkenntnisse und wäre sehr erfreut, wenn mir jemand Tipps geben könnte(z.B. nützliche funktionen)
vielen Dank im voraus
Verfasst: Montag 1. Juni 2009, 19:29
von BlackJack
@Clockworx: Als erstes solltest Du das Tutorial in der Python-Dokumentation durcharbeiten. Dann sind die Module `Tkinter` für die grafische Oberfläche und `random` für die Zufallszahl interessant.
Verfasst: Montag 1. Juni 2009, 20:00
von problembär
Ist wohl'n bißchen unfair, weil Du's kaum verstehen kannst:
Code: Alles auswählen
#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-
import Tkinter, random
root = Tkinter.Tk()
btn = Tkinter.Button(root,
text = "würfeln",
command = lambda: btn.configure(text = str(random.randrange(6) + 1)))
btn.pack(padx = 30, pady = 30)
root.mainloop()
Gruß
Verfasst: Montag 1. Juni 2009, 20:10
von numerix
@Clockworx:
Vermutlich wäre es das beste, wenn du dich für die nächsten Wochen von der Vorstellung "Ich klicke auf einen Button und dann passiert etwas" zunächst verabschieden würdest und erst einmal die Grundlagen von Python lernen würdest. Das hat nämlich - wie in den meisten Programmiersprachen - mit "Button anklicken" zunächst einmal gar nichts zu tun. Ein Programm soll ja beim "Button anklicken" nicht irgendetwas machen, sondern etwas bestimmtes - und das hat mit dem Klick an sich meist wenig zu tun.
Verfasst: Montag 1. Juni 2009, 20:28
von derdon
@problembär: Wa willst du mit
bewirken? Ist das so etwas wie
? Und warum nicht
?
Verfasst: Montag 1. Juni 2009, 22:38
von numerix
Was hast du gegen randrange()?
Ich benutze randint() nie, weil es noch langsamer ist als randrange().
Außerdem hat randint() den Nachteil, dass bei randint(a,b) ganz entgegen all dem, was in Python sonst üblich ist, b mit enthalten ist. Das ist bei randrange() nicht so. Und schließlich ist randrange() flexibler als randint(), weil z.B. auch so etwas geht: randrange(5,501,5).
Fazit: randint() ist überflüssig, randrange() ist die bessere Wahl.
Verfasst: Montag 1. Juni 2009, 22:43
von derdon
Bei einer Liste, die 6 Objekte enthält, spielt Geschwindigkeit doch keine große Rolle. Das Argument mit der Inkonsistenz kann ich allerdings verstehen. Meine Fragen waren übrigens nicht rhetorisch gemeint. Ich habe also keine Abneigung gegen randrange, sondern war nur verwundert über den Code.
Verfasst: Dienstag 2. Juni 2009, 02:17
von ichbinsisyphos
problembär hat geschrieben:...
Verdammt, ich hab nicht gewusst, dass TKinter so simpel ist. Das beantwortet dann wohl auch die Frage, wieso irgendjemand, bei all den Alternativen, so ein obskures Toolkit benützt.
Verfasst: Dienstag 2. Juni 2009, 03:10
von cofi
PyQt ist genauso simpel - zumindest solche Anwendungen

(Bei GTK + wxWindows ist das bestimmt genauso)
Ich denke der Hauptgrund ist nicht die Einfachheit, sondern die Verfügbarkeit, da Tkinter batteriebetrieben ist

Verfasst: Dienstag 2. Juni 2009, 09:41
von lunar
@Numerix
Es ist doch nett, dass die Bibliothek dir mit "randint()" sogar die ansonsten erforderliche Addition mit eins abnimmt

Außerdem ruft "randint(a, b)" ruft direkt "randrange(a, b+1)" auf. Wenn du das was misst, dann die Verzögerung durch Funktionsaufrufe und die Addition ... und letztlich sieht "randint(1, 6)" einfach besser aus als "randrange(6) + 1".
@problembär
Die Qt4-Version ist nur unwesentlich länger
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from random import randint
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication(sys.argv)
button = QtGui.QPushButton(u'Würfeln')
button.connect(button, QtCore.SIGNAL('clicked()'),
lambda: button.setText(unicode(randint(1,6))))
button.show()
app.exec_()
Verfasst: Dienstag 2. Juni 2009, 10:08
von numerix
lunar hat geschrieben:@Numerix
Es ist doch nett, dass die Bibliothek dir mit "randint()" sogar die ansonsten erforderliche Addition mit eins abnimmt

Außerdem ruft "randint(a, b)" ruft direkt "randrange(a, b+1)" auf. Wenn du das was misst, dann die Verzögerung durch Funktionsaufrufe und die Addition ... und letztlich sieht "randint(1, 6)" einfach besser aus als "randrange(6) + 1".
Wieso denn 1 addieren?
randrange(1,7) leistet das gleiche wie randint(1,6), außer, dass ich mir bei randint() merken muss, dass bei randint(a,b) das b - anders als bei range/xrange, slicing etc. mit drin ist. Eine potentielle Fehlerquelle! randint() braucht kein Mensch.
Verfasst: Dienstag 2. Juni 2009, 10:50
von BlackJack
@numerix: Du hast doch 1 addiert. Sonst würde da nicht 7 stehen. Bei `randrange()` muss man sich im Gegenzug merken, dass die Obergrenze nicht enthalten ist. Wenn ich keinen zufälligen Index generieren möchte, sondern eine Zahl von 1 bis 6 inklusive, finde ich `randint()` deutlicher und direkter.
Verfasst: Dienstag 2. Juni 2009, 10:56
von sma
Verfasst: Dienstag 2. Juni 2009, 11:16
von numerix
BlackJack hat geschrieben:@numerix: Du hast doch 1 addiert. Sonst würde da nicht 7 stehen. Bei `randrange()` muss man sich im Gegenzug merken, dass die Obergrenze nicht enthalten ist. Wenn ich keinen zufälligen Index generieren möchte, sondern eine Zahl von 1 bis 6 inklusive, finde ich `randint()` deutlicher und direkter.
Kann ich überhaupt nicht nachvollziehen.
Nun kennst du Python weit besser als ich, aber soweit ich sehe, gilt außer bei randint(a,b) bei der Angabe von Bereichen IMMER, dass der zweite Wert exklusiv ist und ich halte es für überaus sinnvoll, das so etwas konsistent durchgehalten wird, weil das sonst eine potentielle Fehlerquelle ist. Darum ist das davon abweichende Verhalten von randint() für mich inkonsistent. Da randint() außerdem langsamer und weniger flexibel ist (keine Schrittweite möglich), sehe ich nicht, warum ich randint() an irgendeiner Stelle randrange() vorziehen sollte.
Verfasst: Dienstag 2. Juni 2009, 11:39
von lunar
numerix hat geschrieben:Nun kennst du Python weit besser als ich, aber soweit ich sehe, gilt außer bei randint(a,b) bei der Angabe von Bereichen IMMER, dass der zweite Wert exklusiv ist und ich halte es für überaus sinnvoll, das so etwas konsistent durchgehalten wird, weil das sonst eine potentielle Fehlerquelle ist.
Das gilt nur für Slicing und alle "*range()"-Funktionen. Eine allgemeine Konvention besteht da nicht, und Fehlerquelle ist auch nur dann, wenn man nicht in die Doku schaut.
Da randint() außerdem langsamer [...] ist.
Mich würde interessieren, wie du darauf kommst ...
Verfasst: Dienstag 2. Juni 2009, 11:44
von wuf
..... Hier noch als weitere Ergänzung die wxPython-Variante:
Code: Alles auswählen
import wx
from random import randint
app = wx.App()
app_win = wx.Frame(None, size=(100,100))
button = wx.Button(app_win, label=str(1))
app_win.Bind(wx.EVT_BUTTON,
lambda event: button.SetLabel(str(randint(1,6))), button)
app_win.Show()
app.MainLoop()
Gruss wuf

Verfasst: Dienstag 2. Juni 2009, 11:51
von numerix
lunar hat geschrieben:Da randint() außerdem langsamer [...] ist.
Mich würde interessieren, wie du darauf kommst ...
Weil es auf meinem System so ist - mag woanders anders sein:
Code: Alles auswählen
from time import time
from random import randint, randrange, random
def test():
t0 = time()
for k in xrange(10**6):
n = randint(1,6)
print time()-t0
t0 = time()
for k in xrange(10**6):
n = randrange(1,7)
print time()-t0
t0 = time()
for k in xrange(10**6):
n = int(random()*6)+1
print time()-t0
test()
Python 2.5:
Python 2.6:
Python 3.0 (syntaktisch angepasst):
Jython 2.2
Code: Alles auswählen
17.42199993133545
14.800999879837036
9.039999961853027
Jython 2.5rc
Verfasst: Dienstag 2. Juni 2009, 12:10
von HerrHagen
Mich würde interessieren, wie du darauf kommst ...
Ein Blick in die Quellen zeigt warum:
Code: Alles auswählen
def randint(self, a, b):
"""Return random integer in range [a, b], including both end points.
"""
return self.randrange(a, b+1)
Ich finde randint trotzdem schöner. Die Verbindung dieser Funktion zu range und den slice-Operationen sehe ich einfach nicht. Es ist eine ganz normale Funktion die halt genau das bietet was benötigt wird. Wenns zeitkritisch wird, taugen die beiden Funktionen eh nichts. Dann würde ich gleich ein ganzes Feld von Zufallsvariaben mit numpy erzeugen.
MFG HerrHagen
Verfasst: Dienstag 2. Juni 2009, 12:54
von lunar
Ich kenne die Quellen von "randint()", daher habe ich ja auch nachgefragt. "randint()" selbst ist nicht langsam, was Numerix da gemessen hat, sind einzig die Kosten eines Funktionsaufrufs in Python und einer Addition in Python. Mit diesem Argument könnte man gleich auf Funktionen verzichten ...
Verfasst: Dienstag 2. Juni 2009, 13:07
von numerix
lunar hat geschrieben:Ich kenne die Quellen von "randint()", daher habe ich ja auch nachgefragt. "randint()" selbst ist nicht langsam, was Numerix da gemessen hat, sind einzig die Kosten eines Funktionsaufrufs in Python und einer Addition in Python. Mit diesem Argument könnte man gleich auf Funktionen verzichten ...
Diese Argumentation kann ich nicht nachvollziehen.
Fakt ist doch:
- randint() ist langsamer als randrange() - ob nun durch einen Funktionsaufruf und/oder eine Addition, spielt doch keine Rolle
- randrange() ist leistungsfähiger durch die optionale Schrittweite
- randrange() fügt sich durch den ausgeschlossenen Wert für die obere Intervallgrenze besser in das bestehende Konzept von range/slicing
- randrange() ist nicht komplizierter einzusetzen zu verstehen o.ä. als randint()
Was bleibt also als Argument für randint(), außer, dass man sich daran gewöhnt hat und es nach meinem Eindruck häufiger in Quelltexten auftaucht als randrange()?
Vor allem: Wieso wird so ein Wind gegen randrange() gemacht? Was ist denn schlecht an randrange()? Oder liegt es einfach daran, dass es einigen weniger vertraut ist als randint() und darum nicht gut gelitten ist?