Zahlen generieren

Fragen zu Tkinter.
Antworten
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Hallo Leute!

Ich steig gerade ein ins Programmiern mit Phyton. Zuvor hab ich C# und Java programmiert. Nun hab ich folgendes Problem:

Ich will ein Label erstellen und daneben einen Button. Wenn ich auf den Button klicke, soll im Label eine Zahlenfolge erscheinen mit 8 Stellen. Die Zahlen sollen von 00000000 bis 99999999 reichen. Das Problem dabei ist, dass aber in jeder Zahlenfolge mindestes 3 verschiedene Ziffern vorkommen und nicht immer die selben. (Also nicht 11111111 oder 77777777).
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hallo und willkommen.

Ich hoffe ich liege damit richtig.

Code: Alles auswählen

from Tkinter import *
import random 

zahl = random.randrange(0, 99999999)

fenster=Tk()
label=Label(fenster, width=25, height=3, text='zahlenfolge')
label.pack()
def zahlen():
    label.configure(text=zahl)

button=Button(fenster, text='zufall ?', command=zahlen)
button.pack()
fenster.mainloop()
ein Klasse kann mann daraus natürlcih auch machen fals du das dan möchtest.

Ich hoffe das es keine Hausaufgabe ist.
Gruss
pyStyler
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Danke!

Kann ich diese Zahlenfolge auch in eine Datei schreiben, wo dann immer überprüft werden kann ob sie schon vergeben ist?

Ne war keine Aufgabe, ich geh nicht mehr zur Schule :D
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Tom01 hat geschrieben:Das Problem dabei ist, dass aber in jeder Zahlenfolge mindestes 3 verschiedene Ziffern vorkommen und nicht immer die selben. (Also nicht 11111111 oder 77777777).
Wieviele verschiedene Ziffern in einer Zahl vorkommen, kannst du mit Sets (Mengen) pruefen:

Code: Alles auswählen

>>> print len(sets.Set(str(1111111)))
1
>>> print len(sets.Set(str(111222212121212)))
2
In eine Datei schreiben:

Code: Alles auswählen

datei = open("bla.txt", "a")
datei.write(str(123123123) + "\n"))
datei.write(str(99999999) + "\n"))
datei.close()
Wobei es bei deinam Anliegen wahrscheinlich sinnvoller waere, die Werte in einer Liste zu speichern und dann via pickle erst bei Beenden des Programms in eine Datei zu schreiben.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

hi Tom01,

vielleicht schaffst du das auch ohne meine Hilfe. :D
Gerold hat einen sehr schoenen Tut geschrieben wie mann Daten lesen und schreiben kann.

http://www.python-forum.de/topic-6157.html

versuch es bitte, sonst melde Dich noch einmal Spaeter.

Gruss
pyStyler

edit: :oops: da war jemand schneller.
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Code: Alles auswählen

def code():
    fenster.label2.config(text=zahl)

def speichern():
    daten = file('C:\Python25\wert.txt','a+')
    eingabe = write(code)
    daten.write(eingabe)
    daten.close
Das ist ein Auszug des Programms. Warum hängt es sich aufn wenn ich auf den Button Speichern klicke?

Code: Alles auswählen

fenster.buttonSpeichern = Button(text = "Speichern", 
       command = speichern)
fenster.buttonSpeichern.pack(side = RIGHT, padx = 20)
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Code: Alles auswählen

def code(): # 1
    fenster.label2.config(text=zahl) 

def speichern(): 
    daten = file('C:\Python25\wert.txt','a+') 
    eingabe = write(code) 
    daten.write(eingabe) 
    daten.close 
damit willst du deine Funktion #1 speichern. Wobei ich jetzt nicht wüsste was 'a+' ist.
Das geht natürlich nicht.

Code: Alles auswählen

def code(): # 1
    fenster.label2.config(text=zahl) 
Diese Funtion kannst du nur als reine ausgabe verwänden. Intern musst du dafür sorgen, dass die zufällig generierte Zahl in der Textdatei gespeichert wird.

bin im moment unterzeitdruck sorry für so ne grobe Antwort
BlackJack

Die schon verwendeten Zahlen könnte man mit `shelve` in eine Datenbank speichern. So lassen sie sich sehr einfach überprüfen, da sich so ein `shelve` nahezu wie ein Dictionary verhält.

Hier mal eine "komplette" Lösung die alles bisher gesagte zusammenfasst:

Code: Alles auswählen

import random
import shelve
import Tkinter as tk

def random_number_string():
    result = ''
    used = shelve.open('used_numbers')
    while not len(set(result)) >= 3 and result not in used:
        result = '%08d' % random.randint(0, 99999999)
    used[result] = None
    used.close()
    return result

def generate_number():
    number_label.configure(text=random_number_string())

root = tk.Tk()
button = tk.Button(root, text='Generate', command=generate_number)
button.pack()
number_label = tk.Label(root, text='-' * 8)
number_label.pack()

root.mainloop()
Natürlich wird das ziemlich ineffizient, wenn man wirklich viele Nummern braucht, weil es umso langsamer wird, je mehr Nummern bereichts "verbraucht" sind. In dem Fall ist es besser alle brauchbaren Nummern zu erzeugen, die Liste zu "mischen" (`random.shuffle`) und diese dann zu speichern. Dann muss man sich nur noch merken welche Nummer zuletzt "gezogen" wurde.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

morgen,
da Black Jack vor gelegt hat, hier mal mein versuch.Trotz so Spaet sind mir doch noch ein paar Spielerein gelungen.

Code: Alles auswählen

#!/usr/bin/python
from Tkinter import *
from random import randrange
import pickle
class Zahlen:
    def __init__(self, pfadname):
        self.pfad = pfadname
        try:
            datei=file(self.pfad, 'r')
            self.zS = pickle.load(datei)
            datei.close()
        except:
            self.zS = []
            
        self.fenster = Tk()
        self.fenster.geometry('340x280+250+250')
        self.frame = Frame(self.fenster, relief=GROOVE, bd=2)
        self.frame.pack(pady=30)
        self.label1=Label(self.fenster, text='___________')
        self.label2=Label(self.frame, text='Zufalls Zahl',
                          width=25, height=2, font=('Courier', 14, 'bold'))
        zahl_text='''zufallszahl ausgeben\n&speichern\n''' 
        self.button=Button(self.frame, text=zahl_text, command=self.zZahl)
        self.label1.pack(side=BOTTOM)
        self.label2.pack(pady=20)
        self.button.pack()
        self.fenster.mainloop()

    def neueZahl(self, zahl):
        self.zS += [zahl]
        self.speichern()

    def zZahl(self):
        zahl = 99999999
        self.zufallsZahl = randrange(zahl)
        self.label2.configure(text=self.zufallsZahl)
        self.label2.after(500, self.zm)

    def zm(self):
        if self.zufallsZahl not in self.zS:
            self.neueZahl(self.zufallsZahl)
            self.label2.after(10, self.show)
        else:
            text='Zahl schon vorhanden'
            return
        
    def speichern(self):
        datei=file(self.pfad, 'w')
        pickle.dump( (self.zS), datei )
        datei.close()

    def show(self):
        self.label1.configure(text=self.zufallsZahl)
        self.label2.configure(text='Zahl gespeichert')
        
if __name__=='__main__':
    pfd='zufallszahlen.txt'
    Zahlen(pfd)


gute nacht noch zusammen.

edit:
Achtung das oben gepostete Quellcode ist noch sehr buggy kurz gesagt es tut überhautp nicht das was es tun soll.
werde es spaeter berichtigen wenn ich es schaffe.
War gestern doch schon zu Spaet für meine Gehirnzellen. :D

edit die 2: 16:26 Uhr
nun läuft alles prima.

Gruss
pyStyler
Zuletzt geändert von pyStyler am Dienstag 18. Juli 2006, 15:29, insgesamt 2-mal geändert.
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Hier hab ich jetzt mal meinen jetztigen Status:

Code: Alles auswählen

from Tkinter import *
import time
import random
import shelve

zahl = random.randrange(0, 99999999)


###########################
def firmenname():
	fenster.label.config(text='Hier steht der Firmenname')

def code():
    fenster.label2.config(text=zahl)

def datum():
    fenster.label3.config(text=time.asctime())

def speichern():
    try:
        datei = file('C:\Python25\werte.txt', 'a+')
        for i in s:
            datei.write(str(i)+'\n')
        datei.close()
    except:
        print 'Speichern nicht moeglich'


############################
    
fenster=Tk()
fenster.label= Label(fenster,text='Firma')
fenster.label2= Label(fenster,text='Code')
fenster.label3= Label(fenster,text='Datum')
fenster.label.pack(side=LEFT, padx = 20, pady = 20, fill = BOTH)
fenster.label2.pack(side=LEFT, padx = 20, pady = 20, fill = BOTH)
fenster.label3.pack(side=LEFT, padx = 20, pady = 20, fill = BOTH)

##

fenster.buttonFirma=Button(master=fenster,
		      text='Firma',
		      command=firmenname)
fenster.buttonFirma.pack(side=BOTTOM, padx = 20, pady = 20, fill = BOTH)
##

fenster.buttonCode=Button(master=fenster,
		      text='Code',
		      command=code)
fenster.buttonCode.pack(side=BOTTOM, padx = 20, pady = 20, fill = BOTH)
##

fenster.buttonDatum=Button(master=fenster,
		      text='Datum',
		      command=datum)
fenster.buttonDatum.pack(side=BOTTOM, padx = 20, pady = 20, fill = BOTH)
##

fenster.buttonSpeichern = Button(text = "Speichern", 
       command = speichern)
fenster.buttonSpeichern.pack(side = BOTTOM, padx = 20, pady = 20, fill = BOTH)
##

fenster.buttonExit = Button(text = "Exit", 
          command = fenster.destroy)
fenster.buttonExit.pack(side = BOTTOM, padx = 20, pady = 20, fill = BOTH)
##


fenster.mainloop()
Ich kann aber nicht speichern...
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hallo Tom01

Code: Alles auswählen

def speichern():
    try:
        datei = file('C:\Python25\werte.txt', 'a+')
        for i in s:
            datei.write(str(i)+'\n')
        datei.close()
    except:
        print 'Speichern nicht moeglich'
damit kannst du nichts speichern! Also ich meine damit kannst du schon was speichern aber da du keine werte für s hast,
wird nichts gespeicht sondern immer 'Speichern nicht möglich' ausgegeben.
BlackJack

Tom01 hat geschrieben:Hier hab ich jetzt mal meinen jetztigen Status:

Code: Alles auswählen

def speichern():
    try:
        datei = file('C:\Python25\werte.txt', 'a+')
        for i in s:
            datei.write(str(i)+'\n')
        datei.close()
    except:
        print 'Speichern nicht moeglich'
Ein schönes Beispiel dafür warum ein "nacktes" ``except`` ohne eine konkrete Ausnahme keine gute Idee ist. Wenn Du da ein ``except IOError:`` draus machst, dann wirst Du feststellen, das beim Versuch zu speichern ein `NameError` kommt, da der Name `s` nirgends definiert ist.

Und Du solltest entweder die rückwärtsgerichteten Schrägstriche verdoppeln oder eine "Raw" Zeichenkette für den Pfad verwenden. Sonst bekommst Du irgendwann einmal Probleme wenn Du gültige Escape-Sequenzen in einem Dateinamen hast, wie zum Beispiel '\a' oder '\n'.
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Ich hab hier mal was verändert. Könnte es so gehn:

Code: Alles auswählen

###########################
def firmenname():
	fenster.label.config(text='Hier steht der Firmenname')

def code():
    fenster.label2.config(text=zahl)

def datum():
    fenster.label3.config(text=time.asctime())

def speichern():
    try:
        datei = file('werte.txt', 'w+')
        for i in code:
            datei.write(str(i)+'\n')
        datei.close()
    except:
        print 'Speichern nicht moeglich'


############################
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Tom01 hat geschrieben:Ich hab hier mal was verändert. Könnte es so gehn:

Code: Alles auswählen

###########################
def firmenname():
	fenster.label.config(text='Hier steht der Firmenname')

def code():
    fenster.label2.config(text=zahl)

def datum():
    fenster.label3.config(text=time.asctime())

def speichern():
    try:
        datei = file('werte.txt', 'w+')
        for i in code:
            datei.write(str(i)+'\n')
        datei.close()
    except:
        print 'Speichern nicht moeglich'


############################
damit willst Du immer noch die Funktion def code speichern und nicht irgend einen Wert.

Code: Alles auswählen

zahl=100
def speichern( xyz ): #xyz ist nur ne Variable 
	datei=file('werte.txt', 'w')
	datei.write(str(zahl)+'\n') #ein wert Zahl 100 wird gespeichert	datei.close()
vielleicht ist es so besser zu verstehen wie Werte gespeichert werden.

Wobei ich sagen muss, so wohl meine als auch deine Funktion Speichern alle Werte als String.
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Wenn ich in der Klammer wo du xyz hast was reinschreibe, kommt immer das:

TypeError: speichern() takes exactly 1 argument (0 given)
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

upss sorry hat einen fehler im Code

Code: Alles auswählen

zahl=100 
def speichern( xyz ): #xyz ist nur ne Variable 
    datei=file('werte.txt', 'w') 
    datei.write(str(xyz)+'\n') #ein wert Zahl 100 wird gespeichert    datei.close() 
so alles wieder ok!

versuch mal erst unter IDLE zu testen

Code: Alles auswählen

>>> meinWert = 100
>>> def speichern( xyz ):
	datei=file('werte.txt', 'w')
	datei.write(str(xyz)+'\n')
	datei.close()

	
>>> speichern(meinWert) #Funktion def speichern wird aufgerufen....
>>> 
Tom01
User
Beiträge: 10
Registriert: Montag 17. Juli 2006, 13:44

Jetzt möchte ich, wenn auf speichern geklickt wird, der Wert in eine Datei gespeichert wird (funktioniert auch schon) und wenn uaf Drucken geklickt wird, soll der Code, der Firmenname und das Datum nebeneinander in eine Datei geschrieben werden.
Mein Versuch funktioniert leider nicht:

jetzt kommt immer das als Ergebnis:
Firmenname: <function firmenname at 0x00BB6BF0>
Datum: <function datum at 0x00BB6C70>
Code: 17153627

Code: Alles auswählen

from Tkinter import *
import time
import random
import shelve

zahl = random.randrange(0, 99999999)

###########################

def firmenname():
	fenster.label.config(text='Hier steht der Firmenname')

def code():
    fenster.label2.config(text=zahl)

def datum():
    fenster.label3.config(text=time.asctime())

def speichern(xyz):
    try:
        datei = file('werte.txt', 'a+')
        datei.write(str(xyz)+'\n')
        datei.close()
    except IOError:
        print 'Speichern nicht moeglich'

def drucken(firma, datum, code):
    try:
        ausdruck = file('ausdruck.txt', 'a+')
        ausdruck.write("Firmenname: " + str(firma)+'\n')
        ausdruck.write("Datum: " + str(datum)+'\n')
        ausdruck.write("Code: " + str(code)+'\n')
        ausdruck.close()
    except IOError:
        print 'Speichern nicht moeglich'

############################
    
fenster=Tk()
fenster.label= Label(fenster,text='Firma', font=('Comic Sans MS',16),fg='blue', width = 20)
fenster.label2= Label(fenster,text='Code', font=('Comic Sans MS',16),fg='blue', width = 10)
fenster.label3= Label(fenster,text='Datum', font=('Comic Sans MS',16),fg='blue', width = 20)
fenster.label.pack(side=LEFT, padx = 20, pady = 20, fill = BOTH, expand=0)
fenster.label2.pack(side=LEFT, padx = 20, pady = 20, fill = BOTH, expand=0)
fenster.label3.pack(side=LEFT, padx = 20, pady = 20, fill = BOTH, expand=0)

##

fenster.buttonFirma=Button(master=fenster,
		      text='Firma',
		      command=firmenname, bg='yellow')
fenster.buttonFirma.pack(side=BOTTOM, padx = 20, pady = 20, fill = BOTH)
##

fenster.buttonCode=Button(master=fenster,
		      text='Code',
		      command=code, bg='yellow')
fenster.buttonCode.pack(side=BOTTOM, padx = 20, pady = 20, fill = BOTH, expand=0)
##

fenster.buttonDatum=Button(master=fenster,
		      text='Datum',
		      command=datum, bg='yellow')
fenster.buttonDatum.pack(side=BOTTOM, padx = 20, pady = 20, fill = BOTH, expand=0)
##

fenster.buttonExit = Button(text = "Exit", 
          command = fenster.destroy)
fenster.buttonExit.pack(side = BOTTOM, padx = 20, pady = 20, fill = BOTH, expand=0)
##

fenster.buttonSpeichern = Button(text = "Speichern", 
       command = speichern(zahl))
fenster.buttonSpeichern.pack(side = BOTTOM, padx = 20, pady = 20, fill = BOTH, expand=0)
##

fenster.buttonDrucken = Button(text = "Drucken",
          command = drucken(firmenname, datum, zahl))
fenster.buttonDrucken.pack(side = BOTTOM, padx = 20, pady = 20, fill = BOTH, expand=0)
##



fenster.mainloop()

BlackJack

Vielleicht solltest Du das mit der GUI erst einmal weglassen und Dich mit den Grundlagen vertraut machen. Du versuchst schon wieder Funktionen in Zeichenketten umzuwandeln.

Ausserdem werden einige Funktionen, die Du an Buttons als `command` binden willst, bei Dir ausgeführt und der Rückgabewert an `command` gebunden.

Schreib doch erst einmal ein kleines Skript mit den Funktionen, also Zufallszahl generieren, in Datei schreiben und Drucken und eine kleine Testfunktion und schreib dann dazu den GUI Teil wenn alles läuft.

Und versuch globale Variablen bei den Funktionen zu vermeiden. Wenn etwas von "aussen" kommt, dann sollte es als Argument übergeben werden und Ergebnisse sollten möglichst nur als Rückgabewert nach aussen dringen.
Antworten