Domanda Piccolo script python

ItsReal

Utente Electrum
30 Dicembre 2014
114
30
9
104
Salve a tutti, ho provato a fare un programmino che simula una transazione in una macchinetta del caffè.
Sono alle prime armi e vorrei capire come migliorare questo script, magari avere la possibilità di non uscire dal programma ogni volta che finisco un' istruzione e quindi che continuasse all'infinito ogni qualvolta si inserisca denaro, come se fosse una macchinetta nella realtà.
Ho anche un'infarinatura sulla programmazione ad oggetti, la quale trovo un po' complicata da capire e vorrei sapere se questo programmino posso riscriverlo in un modo "totalmente" diverso.
Vi lascio lo script qui sotto, intanto vi ringrazio :D

Python:
# simulare una macchinetta del caffè

bevande = {
    "Caffe": 0.40,
    "Cioccolata": 0.60,
    "Caffe macchiato": 0.45,
    "Te": 0.30,
}

credito_inserito = 0
credito_rimanente = 0

for nome, prezzo in bevande.items():
    print(f"Prodotto: {nome}, Prezzo: {prezzo}")
print('-' * 50)

selezione_prodotto = input("Inserisci il nome del prodotto: ")
if selezione_prodotto in bevande.keys():
    print(f"Hai selezionato {selezione_prodotto.upper()}")
else:
    print("Valore non corretto!")
    exit()

credito_inserito = float(input("Inserisci denaro: "))
print(f"Denaro disponibile: {credito_inserito}")
print('-' * 50)

if credito_inserito >= bevande[selezione_prodotto]:
    print("Erogazione in corso ...")
    credito_rimanente = credito_inserito - bevande[selezione_prodotto]
    print("Bevanda pronta!")
    print('-' * 50)
    print(f"Denaro rimanente: {credito_rimanente}")

elif credito_inserito < bevande[selezione_prodotto]:
    print("Non hai abbastanza credito")
    print(f"{selezione_prodotto} costa {bevande[selezione_prodotto]} euro")
 
Ciao,
innanzitutto, per la tua prima richiesta, cioè come puoi fare a far andare il programma all'infinito, puoi semplicemente mettere tutto il codice dentro a una funzione, e chiamare la funzione da dentro a un ciclo `while`.

Inoltre, è buona pratica mettere il codice dentro una "guardia", cosi se il tuo codice viene importato come module, non viene eseguito.

Quindi, supponendo che la tua nuova funzione si chiami macchinetta, avremo qualcosa del genere:

Python:
# Leggi https://stackoverflow.com/q/419163/2586392 per più informazioni su questo costrutto
if __name__ == "__main__":
    while True:
       macchinetta()

Se vogliamo fare qualcosa di carino, possiamo fare che si ricordi del credito tra un'esecuzione e l'altra (supponiamo non dia resto!).

Puoi creare una classe, giusto per esercitarsi con la programmazione a oggetti, e gli diamo un paio di funzioni per aggiungere e togliere denaro. Aggiungiamo anche un'eccezione se non ci sono abbastanza soldi.

Il codice diventa allora qualcosa tipo:
Python:
class Cassa(object):
    def __init__(self):
        self.credito = 0

    def aggiungi(self, amount):
        self.credito += amount

    def rimuovi(self, amount):
        if amount >= self.credito:
            raise ValueError("Non hai abbastanza credito!")
        
        self.credito -= amount

def macchinetta(cassa: Cassa):
    bevande = {
        "Caffe": 0.40,
        "Cioccolata": 0.60,
        "Caffe macchiato": 0.45,
        "Te": 0.30,
    }

    for nome, prezzo in bevande.items():
        print(f"Prodotto: {nome}, Prezzo: {prezzo}")

    print('-' * 50)

    selezione_prodotto = input("Inserisci il nome del prodotto: ")

    if selezione_prodotto in bevande.keys():
        print(f"Hai selezionato {selezione_prodotto.upper()}")
    else:
        print("Valore non corretto!")
        return

    credito_inserito = float(input("Inserisci denaro: "))
    cassa.aggiungi(credito_inserito)
    print(f"Denaro disponibile: {cassa.credito}")
    print('-' * 50)

    try:
        cassa.rimuovi(bevande[selezione_prodotto])
        print("Erogazione in corso ...")
        print("Bevanda pronta!")
        print('-' * 50)
        print(f"Denaro rimanente: {cassa.credito}")
    except ValueError as err:
        print(err)
        print(f"{selezione_prodotto} costa {bevande[selezione_prodotto]} euro")

    print("\n")

# Leggi https://stackoverflow.com/q/419163/2586392 per più informazioni su questo costrutto
if __name__ == "__main__": 
    cassa = Cassa()
    while True:
        macchinetta(cassa)

Se vuoi esercitarti un altro po', puoi:
  • Creare una classe "Inventario", che conti quante cose ci sono ancora nella macchinetta, e man mano diminuisce
  • Avere un selettore che ti faccia scegliere quanto zucchero
  • Aggiungere la possibilità di avere le "chiavette", dove puoi caricare credito
  • Poter far ricaricare l'inventario
  • A fine giornata, stampare quanti soldi sono stati collezionati, e quante bevande sono state erogate
  • Salvare il tutto in un file, che funga da database, cosicché l'inventario rimanga anche tra esecuzioni diverse del programma
Spero di averti dato qualche idea utile ;-)
 
Ciao,
innanzitutto, per la tua prima richiesta, cioè come puoi fare a far andare il programma all'infinito, puoi semplicemente mettere tutto il codice dentro a una funzione, e chiamare la funzione da dentro a un ciclo `while`.

Inoltre, è buona pratica mettere il codice dentro una "guardia", cosi se il tuo codice viene importato come module, non viene eseguito.

Quindi, supponendo che la tua nuova funzione si chiami macchinetta, avremo qualcosa del genere:

Python:
# Leggi https://stackoverflow.com/q/419163/2586392 per più informazioni su questo costrutto
if __name__ == "__main__":
    while True:
       macchinetta()

Se vogliamo fare qualcosa di carino, possiamo fare che si ricordi del credito tra un'esecuzione e l'altra (supponiamo non dia resto!).

Puoi creare una classe, giusto per esercitarsi con la programmazione a oggetti, e gli diamo un paio di funzioni per aggiungere e togliere denaro. Aggiungiamo anche un'eccezione se non ci sono abbastanza soldi.

Il codice diventa allora qualcosa tipo:
Python:
class Cassa(object):
    def __init__(self):
        self.credito = 0

    def aggiungi(self, amount):
        self.credito += amount

    def rimuovi(self, amount):
        if amount >= self.credito:
            raise ValueError("Non hai abbastanza credito!")
       
        self.credito -= amount

def macchinetta(cassa: Cassa):
    bevande = {
        "Caffe": 0.40,
        "Cioccolata": 0.60,
        "Caffe macchiato": 0.45,
        "Te": 0.30,
    }

    for nome, prezzo in bevande.items():
        print(f"Prodotto: {nome}, Prezzo: {prezzo}")

    print('-' * 50)

    selezione_prodotto = input("Inserisci il nome del prodotto: ")

    if selezione_prodotto in bevande.keys():
        print(f"Hai selezionato {selezione_prodotto.upper()}")
    else:
        print("Valore non corretto!")
        return

    credito_inserito = float(input("Inserisci denaro: "))
    cassa.aggiungi(credito_inserito)
    print(f"Denaro disponibile: {cassa.credito}")
    print('-' * 50)

    try:
        cassa.rimuovi(bevande[selezione_prodotto])
        print("Erogazione in corso ...")
        print("Bevanda pronta!")
        print('-' * 50)
        print(f"Denaro rimanente: {cassa.credito}")
    except ValueError as err:
        print(err)
        print(f"{selezione_prodotto} costa {bevande[selezione_prodotto]} euro")

    print("\n")

# Leggi https://stackoverflow.com/q/419163/2586392 per più informazioni su questo costrutto
if __name__ == "__main__":
    cassa = Cassa()
    while True:
        macchinetta(cassa)

Se vuoi esercitarti un altro po', puoi:
  • Creare una classe "Inventario", che conti quante cose ci sono ancora nella macchinetta, e man mano diminuisce
  • Avere un selettore che ti faccia scegliere quanto zucchero
  • Aggiungere la possibilità di avere le "chiavette", dove puoi caricare credito
  • Poter far ricaricare l'inventario
  • A fine giornata, stampare quanti soldi sono stati collezionati, e quante bevande sono state erogate
  • Salvare il tutto in un file, che funga da database, cosicché l'inventario rimanga anche tra esecuzioni diverse del programma
Spero di averti dato qualche idea utile ;-)
Grazie, ora provo e ti aggiorno.
L' unica cosa che sono in dubbio è quando vai a scrvere: cassa: Cassa come parametri della funzione
Python:
def macchinetta(cassa: Cassa):
 
L' unica cosa che sono in dubbio è quando vai a scrvere: cassa: Cassa come parametri della funzione
Hai ragione, scusami, non l'ho spiegato.

Questo viene usato da Python come "tipo" dell'argomento. In questo modo il tuo IDE / editor sa il tipo, e quindi può suggerirti cose utili, come autocompletare i nomi dei metodi che chiami: https://docs.python.org/3/library/typing.html
 
Hai ragione, scusami, non l'ho spiegato.

Questo viene usato da Python come "tipo" dell'argomento. In questo modo il tuo IDE / editor sa il tipo, e quindi può suggerirti cose utili, come autocompletare i nomi dei metodi che chiami: https://docs.python.org/3/library/typing.html
Ciao caro, sto cercando di migliorare il codice ed implementare qualcosina.
Ho provato a fare un qualcosa tipo:

Python:
class Cassa(object):
    def __init__(self):
        self.credito = 0    # credito all'interno del distributore

    def aggiungi_credito(self, user_amount):
        self.credito += user_amount

    def eroga_prodotto(self, product_amount):
        if product_amount > self.credito:
            raise ValueError("Non hai abbastanza credito")
        self.credito -= product_amount

    def dai_resto(self, user_amount, product_amount):
        if user_amount > product_amount:
            resto = user_amount - product_amount
            print("Erogazione resto: € {}".format('%.2f' % resto))

class Inventario(object):
    def __init__(self):
        self.prodotti = {
            "Oreo": 2.00,
            "Patatine": 1.30,
            "Kinder bueno": 1.50,
            "Kinder pinguin": 2.00,
            "Acqua naturale": 1.00,
            "Acqua frizzante": 1.00,
            "Croccantelle": 1.20,
            "Yogurt": 2.00,
            "Smarties": 1.40,
            }

        self.quantita = {}
        for product, quantity in self.prodotti.items():
            self.quantita[product] = 0

    def aggiungi_prodotto(self, product_name, quantity):
            self.quantita[product_name] += int(quantity)

    def rimuovi_prodotto(self, product_name, quantity):
            self.quantita[product_name] -= int(quantity)


def avvio(cassa: Cassa, inventario: Inventario):
    print('-' * 50)
    print("Prodotti disponibili:")

    for prodotto, prezzo in inventario.prodotti.items():
        print(f"{prodotto}: € {prezzo}")

    print('-' * 50)


    scelta = input('> ')
    if scelta in inventario.prodotti.keys() and inventario.quantita[scelta] != 0:
        print(inventario.quantita)
        print('-' * 50)
        print(f"Hai selezionato: {scelta.capitalize()}")
        print(f"Prezzo: € {inventario.prodotti[scelta]}")
        print('-' * 50)

    if scelta == '0000':   # codice speciale per amministratore
        aggiunta = input("Seleziona il prodotto da aggiungere: ")
        quantita = input("Quantita: ")
        inventario.aggiungi_prodotto(aggiunta, quantita)
        for product, quantity in inventario.quantita.items():
            print(f"Prodotto: {product}, Quantità: {quantity}")
        return

    elif inventario.quantita[scelta] == 0:
        print("Prodotto esaurito")
        return

    try:
        soldi = float(input("Inserisci denaro > "))

    except ValueError:
        print("Valore non valido")
        return


    cassa.aggiungi_credito(soldi)

    try:
        cassa.eroga_prodotto(inventario.prodotti[scelta])
        print("Erogazione in corso...")
        print("Prego ritirare prodotto")
        cassa.dai_resto(soldi, inventario.prodotti[scelta])

    except ValueError as err:
        print(err)


while True:
    cassa = Cassa()
    inventario = Inventario()
    avvio(cassa, inventario)

Ho dei problemi che non riesco a risolvere:
1. Vorrei che quando l'utente digitasse il nome del prodotto il programma lo valuti anche se la stringa dovesse essere di caratteri maiuscoli o minuscoli
Ho provato con .lower() ma poi non me lo rileva all'interno del dict

2. Non trovo il modo per far si che il dict Inventario prenda gli stessi elementi del dicr Prodotti così da avere un dic per Prodotto: Prezzo e Prodotto: Quantità anche aggiungendo altri elementi

3. Come faccio a salvare il valore della quantità ogni volta che si esegue il While?
 
1. Vorrei che quando l'utente digitasse il nome del prodotto il programma lo valuti anche se la stringa dovesse essere di caratteri maiuscoli o minuscoli
Ho provato con .lower() ma poi non me lo rileva all'interno del dict
Giusta idea! Devi semplicemente mettere tutto in lower case quando crei il dizionario, cosicché poi con lower() sull'input utente compara con parole già in lowercase

2. Non trovo il modo per far si che il dict Inventario prenda gli stessi elementi del dicr Prodotti così da avere un dic per Prodotto: Prezzo e Prodotto: Quantità anche aggiungendo altri elementi
Ti consiglio di usare un solo dizionario, che abbia dizionari come elementi. Esempio:

Python:
prodotti = {
    "acqua": {"prezzo": 0.5, "amount": 12},
    "the": {"prezzo": 1, "amount": 18}
}

3. Come faccio a salvare il valore della quantità ogni volta che si esegue il While?
Non ho capito, cosa intendi?
 
Per forza, reinizializzi le classi ad ogni ciclo.

Invece di

Python:
while True:
    cassa = Cassa()
    inventario = Inventario()
    avvio(cassa, inventario)

fai

Python:
cassa = Cassa()
inventario = Inventario()

while True:
    avvio(cassa, inventario)
 
  • Mi piace
Reazioni: ItsReal