Difference between revisions of "Python Programma tieni punteggio."
(21 intermediate revisions by the same user not shown) | |||
Line 41: | Line 41: | ||
*il modulo cambiapunteggiodi.py, poi gli metterò un controllo per verificare l`esistenza di Giocatore: | *il modulo cambiapunteggiodi.py, poi gli metterò un controllo per verificare l`esistenza di Giocatore: | ||
− | <syntaxhighlight lang="python"> import pickle | + | <syntaxhighlight lang="python"> |
+ | |||
+ | import pickle | ||
f = open(".info.pck","r") | f = open(".info.pck","r") | ||
infotorneo = {} | infotorneo = {} | ||
Line 85: | Line 87: | ||
<syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
+ | #filename:fedelib.pyc | ||
import datetime | import datetime | ||
import pickle | import pickle | ||
Line 152: | Line 155: | ||
return self.datacreazione[ID] | return self.datacreazione[ID] | ||
else: | else: | ||
− | + | return | |
Line 196: | Line 199: | ||
a = {} | a = {} | ||
a = pickle.load(f) | a = pickle.load(f) | ||
− | self. | + | self.datacreazione = a |
f.close() | f.close() | ||
f=open(".cancellati.pck","rb") | f=open(".cancellati.pck","rb") | ||
Line 210: | Line 213: | ||
def IDList(self): #restituisce la lista degli ID usati | def IDList(self): #restituisce la lista degli ID usati | ||
b=list(range(1,self.IDGEN)) | b=list(range(1,self.IDGEN)) | ||
+ | c=self.listacancellati | ||
while self.listacancellati != []: | while self.listacancellati != []: | ||
− | b.remove( | + | b.remove(c.pop()) |
− | |||
return b | return b | ||
+ | </syntaxhighlight> | ||
+ | Modulo reset.py: | ||
+ | <syntaxhighlight lang="python"> | ||
+ | #va utilizzato per resettare tutti i dati perdendo i precedenti. | ||
+ | import fedelib | ||
+ | infotorneo=fedelib.torneoinfo() | ||
+ | infotorneo.savefiles() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Modulo newplayer.py: | ||
+ | <syntaxhighlight lang="python"> | ||
+ | import fedelib | ||
+ | infotorneo = fedelib.torneoinfo() | ||
+ | a = input("New player's name?\n" ) | ||
+ | try: | ||
+ | infotorneo.loadfiles() | ||
+ | except IOError: | ||
+ | infotorneo.savefiles() | ||
+ | infotorneo.create(a) | ||
+ | infotorneo.savefiles() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Modulo printIDtable.py: | ||
+ | <syntaxhighlight lang="python"> | ||
+ | import fedelib | ||
+ | import sorts | ||
+ | fi=open("lista.txt","w") | ||
+ | infotorneo = fedelib.torneoinfo() | ||
+ | infotorneo.loadfiles() | ||
+ | a = [] | ||
+ | a = infotorneo.IDList() #se volessi un sortbyname qua potrei scrivere: a = sorts.sortbyname(infotorneo) | ||
+ | fi.write("NOME\t\tPUNTI\t\tID\t\tDATA\n") | ||
+ | while a != []: | ||
+ | b = a.pop() | ||
+ | fi.write("{0!s}\t\t{1!s}\t\t{2!s}\t\t{3!s}\n".format(str(infotorneo.read(b,"n")),str(infotorneo.read(b,"p")),str(b),str(infotorneo.read(b,"d")))) | ||
+ | fi.close() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Modulo updateplayer.py: | ||
+ | <syntaxhighlight lang="python"> | ||
+ | import fedelib | ||
+ | infotorneo = fedelib.torneoinfo() | ||
+ | infotorneo.loadfiles() | ||
+ | while True: | ||
+ | try: | ||
+ | ID = int(input("What is the ID of the user you want to update?\n", )) | ||
+ | break | ||
+ | except ValueError: | ||
+ | print("ID must be an integer") | ||
+ | if not int(ID) in infotorneo.IDList(): print("unused ID");quit() | ||
+ | else : pass | ||
+ | scelta = 'no' | ||
+ | while scelta != "date" and scelta != "name" and scelta != "score" and scelta != "abort" : | ||
+ | scelta = input("what do you want to change?(specify (date/score/name/abort))\n", ) | ||
+ | if scelta == "abort": quit() | ||
+ | if scelta == "name" : | ||
+ | a = input("write new name for ID: {0!s}\n".format(ID), ) | ||
+ | a=str(a) | ||
+ | infotorneo.update(ID,a) | ||
+ | if scelta == "date" : | ||
+ | while True: | ||
+ | try: | ||
+ | day = int(input("write new date for ID: {0!s}\nDay:\t".format(ID), )) | ||
+ | mth = int(input("\nMonth:\t", )) | ||
+ | yr = int(input("\nYear:\t", )) | ||
+ | break | ||
+ | except ValueError: | ||
+ | print("Day, Month and Year must be integers") | ||
+ | infotorneo.update(ID,tuple((day,mth,yr))) | ||
+ | if scelta == "score" : | ||
+ | while True: | ||
+ | try: | ||
+ | scr = int(input("write new score for ID: {0!s}".format(ID), )) | ||
+ | break | ||
+ | except ValueError: | ||
+ | print("Score must be an integer:\t") | ||
+ | infotorneo.update(ID,scr) | ||
+ | infotorneo.savefiles() | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | deleteplayer.py: | ||
+ | <syntaxhighlight lang="python"> | ||
+ | import fedelib | ||
+ | infotorneo = fedelib.torneoinfo() | ||
+ | infotorneo.loadfiles() | ||
+ | while True: | ||
+ | try: | ||
+ | ID = int(input("what is the ID to delete?", )) | ||
+ | break | ||
+ | except ValueError: | ||
+ | print("ID must be an integer.") | ||
+ | infotorneo.delete(ID) | ||
+ | infotorneo.savefiles() | ||
+ | </syntaxhighlight> | ||
+ | Nel prossimo file.py andrò definendo le varie funzioni di ID sorting che poi verranno importate e usate a seconda delle preferenze dell' utente in printIDtable.py. | ||
+ | Per ora ho fatto solo il sortbyname | ||
+ | <syntaxhighlight lang="python"> | ||
+ | |||
+ | import copy | ||
+ | def sortbyname(tmpcls): | ||
+ | |||
+ | nomi = [] | ||
+ | IDs = tmpcls.IDList() | ||
+ | constIDs = copy.deepcopy(IDs) #senza il deepcopy buggone | ||
+ | while IDs != []:nomi.append(tmpcls.read(IDs.pop(),'n')) | ||
+ | nomi.sort() | ||
+ | sortedIDs = [] | ||
+ | fixedlen = len(constIDs) | ||
+ | while (len(sortedIDs) != fixedlen): | ||
+ | a = nomi.pop() | ||
+ | TmpID = 0 #sapevo che quello 0 sarebbe servito un giorno | ||
+ | while True: | ||
+ | if a == tmpcls.read(TmpID,'n'):sortedIDs.append(TmpID);break | ||
+ | else: | ||
+ | TmpID = TmpID + 1 | ||
+ | while not TmpID in constIDs:TmpID = TmpID + 1 | ||
+ | continue | ||
+ | return sortedIDs | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 23:59, 20 November 2013
Ho voglia di organizzare un torneo di 105, per chi non lo conoscesse e` il gioco che ha ispirato UNO solamente un po' piu complesso. Ma, prima di poterci giocare avevo intenzione di fare un programma in python il cui scopo è quello di tenere il punteggio del torneo e, all`occorrenza, quello di crearmi un file.txt con tutti i nomi dei partecipanti e i relativi punteggi, in ordine decrescente. Ovviamente in qualsiasi momento si dovra poter aggiungere un partecipante, diminuirne o aumentarne il punteggio, eliminarlo dal torneo. Il programma che ho in mente non e specializzato per il centocinque ma è un generico "tieni punteggio metti in ordine decrescente e scrivi file nel formato "NOME GIOCATORE \t\t PUNTEGGIO"" per così dire. Ecco come mi immagino la struttura del programma (ma che probabilmente fara schifo perche non ho mai fatto niente di utile):
- Una directory con dentro dei file.py ciascuno dei quali grazie alla libreria 'pickle' interagisce con un file che sarà appunto info.pck e, ciascuno dei quali ha un compito ben preciso: sorting decrescente, generare il file.txt, aggiungere un partecipante, rimuovere un partecipante, etc...
- Ciascuno di questi file python poi verrà interpellato dall`utente direttamente da console tramite degli script posti in /usr/bin.
Ho deciso di usare questa implementazione cosi che semmai volessi aggiungere qualche nuova feature al programma, non dovro mai modificare né i vecchi script né i file.py ma dovrò semplicemente creare le nuove feature e farle interagire con il file.pck. Prima di andare avanti volevo qualche opinione o consiglio riguardo alla struttura sopra descritta, ed eventualmente migliorie o magari una struttura completamente diversa.
- Fede
Questo esempio ci apre sicuramente spunti di riflessione sulla persistenza: interessante!
Aggiungo qualche idea...
Le operazioni che si ipotizzano sui partecipanti sono le CRUD: necessarie. Per usabilità aggiungerei anche qualche operazioni per elencare o ricercare i partecipanti già inseriti.
Al fine di distinguere partecipanti omonimi si potrebbe pensare di creare un'astrazione specifica di "Partecipante" (verso l'OOP), così da caratterizzarlo ulteriormente (ID?, data iscrizione al torneo?...tutto quello che ci viene in mente...).
Per la parte di (de)serializzazione si utilizza pikle: interessante "guardare" dentro al file serializzato o, eventualmente, provare a creare una nostra libreria di serializzazione: attenzione agli oggetti che, anche indirettamente, hanno riferimenti a se stesso!
am_20131112
- Primo modulo.py, Starter.py:
import pickle
scelta = 'y'
infotorneo = {}
while scelta == 'y':
a = raw_input("Nome Giocatore:" ) #a = input("Nome Giocatore:" )
infotorneo[a] = 0 #Inizialmente nel torneo tutti hanno punteggio 0.
scelta = raw_input("Vuoi inserire altri Giocatori? (y/n)" ) #scelta = input("Vuoi inserire altri Giocatori? (y/n)" )
while (scelta != 'y' and scelta != 'n'):
scelta = raw_input("Specificare y/n" ) #scelta = input("Specificare y/n" )
f = open(".info.pck","w")
pickle.dump(infotorneo, f)
f.close()
- il modulo cambiapunteggiodi.py, poi gli metterò un controllo per verificare l`esistenza di Giocatore:
import pickle
f = open(".info.pck","r")
infotorneo = {}
infotorneo = pickle.load(f)
f.close()
scelta = 'y'
while (scelta == 'y'):
Giocatore = raw_input("Di chi vuoi cambiare il punteggio?" )
NuovoPunteggio = raw_input("Inserire nuovo punteggio." )
infotorneo[Giocatore] = NuovoPunteggio
scelta = raw_input("Vuoi cambiare il punteggio di un altro giocatore?(y/n)" )
while(scelta != 'y' and scelta != 'n'):
scelta = raw_input("Specificare y/n")
f = open(".info.pck","w")
pickle.dump(infotorneo, f)
f.close()
Grazie per l'aiuto ing. Monaldini, cambierò il mio progetto e faro così:
class torneoinfo: #metodi da definire
pass
infotorneo = torneoinfo() #utilizzo ID nei field "key" dei dizionari per reperire le info.
infotorneo.nomegiocatori = {}
infotorneo.datacreazione = {}
infotorneo.punteggigiocatori = {}
#etc...
Con questo modulo che importerò nei vari altri file.py definisco una classe che funzionerà per ID e con il quale potrò poi implementare le varie feature... Un metodo fondamentale che dovrò fare è quello per aggiungere un giocatore e che dovrà essere fatto in modo che metta i dati in questo formato: {ID : 'NOMEGIOCATORE' } {ID : GG:MM:AAAA } {ID : ValorePunteggio }
Ecco la struttura che utilizzero`:
#filename:fedelib.pyc
import datetime
import pickle
class torneoinfo:
def __init__(self):
self.IDGEN = 1
self.nomegiocatori = {}
self.punteggiogiocatori = {}
self.datacreazione = {}
self.nomegiocatori[0] = "NO"
self.listacancellati = []
def create(self, nome):
if self.listacancellati != []:
IDtmp=self.listacancellati.pop()
self.nomegiocatori[IDtmp] = str(nome)
self.punteggiogiocatori[IDtmp] = 0
self.datacreazione[IDtmp] = (int(datetime.date.today().strftime("%d")),int(datetime.date.today().strftime("%m")),int(datetime.date.today().strftime("%Y")))
return
else:pass
self.nomegiocatori[self.IDGEN] = str(nome)
self.punteggiogiocatori[self.IDGEN] = 0
self.datacreazione[self.IDGEN] = (int(datetime.date.today().strftime("%d")),int(datetime.date.today().strftime("%m")),int(datetime.date.today().strftime("%Y")))
self.IDGEN = self.IDGEN + 1
#def update(self, ID = 0, punteggio = 0, nome = "niente", data = (int(datetime.date.today().strftime("%d")),int(datetime.date.today().strftime("%m")),int(datetime.date.today().strftime("%Y")))):
# if (type(ID)!=type(1) or not(ID in range(0,self.IDGEN)) or type(data)!= type(1,2,3)):
# print("Update fallito!")
# return
# self.punteggiogiocatori[ID] = int(punteggio)
# self.datacreazione[ID] = data
# if (nome != "niente"):
# self.nomegiocatori[ID] = str(nome)
def update(self, ID, a = -1):
if not ID in range(1, self.IDGEN) or ID in self.listacancellati: print('update fallito');return
else:pass
if type(a)==type(0):
if a == -1:
print("update fallito")
return
else:
self.punteggiogiocatori[ID] = a
return
if type(a)==type("n"):
self.nomegiocatori[ID] = a
return
if type(a)==type((1,2,3)) and len(a)==3:
self.datacreazione[ID] = a
return
else:
print("update fallito")
def read(self, ID, a = 'z'):
if type(a)==type('a') and ID in range(1, self.IDGEN) and not ID in self.listacancellati:
if a == 'z':
print('read fallito')
return
else: pass
if a=='n':
return self.nomegiocatori[ID]
else: pass
if a=='p':
return self.punteggiogiocatori[ID]
else: pass
if a=='d':
return self.datacreazione[ID]
else:
return
def delete(self, ID):
if not ID in range(1, self.IDGEN) or ID in self.listacancellati: print('delete fallito');return
else:pass
self.listacancellati.append(ID)
del self.nomegiocatori[ID]
del self.punteggiogiocatori[ID]
del self.datacreazione[ID]
def savefiles(self):
f=open(".nomi.pck","wb")
pickle.dump(self.nomegiocatori, f)
f.close()
f=open(".punti.pck","wb")
pickle.dump(self.punteggiogiocatori, f)
f.close()
f=open(".date.pck","wb")
pickle.dump(self.datacreazione, f)
f.close()
f=open(".cancellati.pck","wb")
pickle.dump(self.listacancellati, f)
f.close()
f=open(".IDGEN.pck","wb")
pickle.dump(self.IDGEN, f)
f.close()
def loadfiles(self):
f=open(".nomi.pck","rb")
a = {}
a = pickle.load(f)
self.nomegiocatori = a
f.close()
f=open(".punti.pck","rb")
a = {}
a = pickle.load(f)
self.punteggiogiocatori = a
f.close()
f=open(".date.pck","rb")
a = {}
a = pickle.load(f)
self.datacreazione = a
f.close()
f=open(".cancellati.pck","rb")
a = []
a = pickle.load(f)
self.listacancellati = a
f.close()
f=open(".IDGEN.pck","rb")
a = pickle.load(f)
self.IDGEN = a
f.close()
def IDList(self): #restituisce la lista degli ID usati
b=list(range(1,self.IDGEN))
c=self.listacancellati
while self.listacancellati != []:
b.remove(c.pop())
return b
Modulo reset.py:
#va utilizzato per resettare tutti i dati perdendo i precedenti.
import fedelib
infotorneo=fedelib.torneoinfo()
infotorneo.savefiles()
Modulo newplayer.py:
import fedelib
infotorneo = fedelib.torneoinfo()
a = input("New player's name?\n" )
try:
infotorneo.loadfiles()
except IOError:
infotorneo.savefiles()
infotorneo.create(a)
infotorneo.savefiles()
Modulo printIDtable.py:
import fedelib
import sorts
fi=open("lista.txt","w")
infotorneo = fedelib.torneoinfo()
infotorneo.loadfiles()
a = []
a = infotorneo.IDList() #se volessi un sortbyname qua potrei scrivere: a = sorts.sortbyname(infotorneo)
fi.write("NOME\t\tPUNTI\t\tID\t\tDATA\n")
while a != []:
b = a.pop()
fi.write("{0!s}\t\t{1!s}\t\t{2!s}\t\t{3!s}\n".format(str(infotorneo.read(b,"n")),str(infotorneo.read(b,"p")),str(b),str(infotorneo.read(b,"d"))))
fi.close()
Modulo updateplayer.py:
import fedelib
infotorneo = fedelib.torneoinfo()
infotorneo.loadfiles()
while True:
try:
ID = int(input("What is the ID of the user you want to update?\n", ))
break
except ValueError:
print("ID must be an integer")
if not int(ID) in infotorneo.IDList(): print("unused ID");quit()
else : pass
scelta = 'no'
while scelta != "date" and scelta != "name" and scelta != "score" and scelta != "abort" :
scelta = input("what do you want to change?(specify (date/score/name/abort))\n", )
if scelta == "abort": quit()
if scelta == "name" :
a = input("write new name for ID: {0!s}\n".format(ID), )
a=str(a)
infotorneo.update(ID,a)
if scelta == "date" :
while True:
try:
day = int(input("write new date for ID: {0!s}\nDay:\t".format(ID), ))
mth = int(input("\nMonth:\t", ))
yr = int(input("\nYear:\t", ))
break
except ValueError:
print("Day, Month and Year must be integers")
infotorneo.update(ID,tuple((day,mth,yr)))
if scelta == "score" :
while True:
try:
scr = int(input("write new score for ID: {0!s}".format(ID), ))
break
except ValueError:
print("Score must be an integer:\t")
infotorneo.update(ID,scr)
infotorneo.savefiles()
deleteplayer.py:
import fedelib
infotorneo = fedelib.torneoinfo()
infotorneo.loadfiles()
while True:
try:
ID = int(input("what is the ID to delete?", ))
break
except ValueError:
print("ID must be an integer.")
infotorneo.delete(ID)
infotorneo.savefiles()
Nel prossimo file.py andrò definendo le varie funzioni di ID sorting che poi verranno importate e usate a seconda delle preferenze dell' utente in printIDtable.py. Per ora ho fatto solo il sortbyname
import copy
def sortbyname(tmpcls):
nomi = []
IDs = tmpcls.IDList()
constIDs = copy.deepcopy(IDs) #senza il deepcopy buggone
while IDs != []:nomi.append(tmpcls.read(IDs.pop(),'n'))
nomi.sort()
sortedIDs = []
fixedlen = len(constIDs)
while (len(sortedIDs) != fixedlen):
a = nomi.pop()
TmpID = 0 #sapevo che quello 0 sarebbe servito un giorno
while True:
if a == tmpcls.read(TmpID,'n'):sortedIDs.append(TmpID);break
else:
TmpID = TmpID + 1
while not TmpID in constIDs:TmpID = TmpID + 1
continue
return sortedIDs