how do i fix this function with dictionary to add and print added people? - python

currently im trying to solve a problem in the code i wrote, for some reason whenever i call imprimir() it only shows the last added person while it should show all the persons added.
libro = {}
def agregar(rut, nombre, edad):
estudiante = {}
estudiante['rut'] = rut
estudiante['nombre'] = nombre
estudiante['edad'] = edad
libro['rut'] = estudiante
def imprimir():
for rut in libro:
estudiante = libro[rut]
print(estudiante['rut'], estudiante['nombre'], estudiante['edad'])
def main():
contador = 0
while contador < 2:
rut = input("rut: ")
nombre = input("nombre: ")
edad = input("Edad: ")
contador = contador + 1
agregar(rut, nombre, edad)
imprimir()
main()
I had the code limited to only 2 people to be added. so if for the first person i write, rut = 1, nombre = 1 and edad = 1, and for the second, rut = 2, nombre = 2 and edad = 2. While using main(), it should print:
1 1 1
2 2 2
but instead it just prints 2 2 2 with 1 1 1 not found, my guess is that somehow the added person are not added but instead rewritten, but i cant find why, if i includo imprimir() inside the while in the main() it prints each person as soon as i finish adding one, but the idea its that the program should print all the added people once i finish adding them.

The problem is your adding the items with the same key so the dict just overrides the last value with each entry you add...
libro = {}
def agregar(rut, nombre, edad):
estudiante = {}
estudiante['rut'] = rut
estudiante['nombre'] = nombre
estudiante['edad'] = edad
# this would override the previous entry since it's always the same key
libro['rut'] = estudiante
# use a key that is unique and all entries will be preserved
libro[rut] = estudiante
# or for some truly unique keys
libro[str(uuid.uuid4())] = estudiante

Related

How to override lists?

I have a question. I'm programming the gallows game. Everything's fine, but I'm stuck with something. The user selects a letter, which will be displayed on the screen and in the corresponding box. But every time the user selects a letter, the, Those I used to choose are gone.
You can see:
import pyfiglet
import random
import os
def start():
print(pyfiglet.figlet_format("BIENVENIDO AL JUEGO DEL AHORCADO"))
print("""
¡ A D I V I N A L A P A L A B R A !
""")
def game():
with open("./archivos/data.txt", "r", encoding="utf-8") as f:
palabras = list(f)
palabra = random.choice(palabras)
palabra = palabra.replace("\n", "")
letras = [i for i in palabra]
guiones = []
for i in letras:
guiones.append("_")
print(" ".join(guiones))
print("")
guiones = []
while guiones != letras:
letra = input("Elige una letra: ")
for i in palabra:
if i == letra:
guiones.append(letra)
else:
guiones.append("_")
print(" ".join(guiones))
guiones.clear()
def run():
start()
game()
if __name__ == "__main__":
run()
Since You are working with lists (which are mutable), You can flip the "_" to the guessed letter and not touch the rest of guiones. To do so, one solution is to use an index to access the list at the given position, like in the code snippet below :
# guiones = [] do NOT clear guiones!
while guiones != letras:
letra = input("Elige una letra: ")
for i in range(len(palabra)):
if palabra[i] == letra:
guiones[i] =letra
print(" ".join(guiones))

How to condition a variable by calling the value?

I have a doubt. Previously I made my first Python program with everything I learned, it was about the system of a vending machine, but one of the main problems was that it was too redundant when conditioning and ended up lengthening the code. So they explained to me that I should define the functions and return in case they are not fulfilled.
But my question is, how can I call the value of a variable, specifically a number, by conditioning it?
Example:
# -*- coding: utf-8 -*-
def select_ware(wares):
print(' '.join(wares))
while True:
selected = input("Elige un código: ")
if selected in wares:
print(f'El precio es de: {wares[selected]}\n')
break
else:
print("El código no existe, introduce un código válido")
return selected
def pay_ware(wares, selected):
money_needed = wares[selected]
money_paid = 0
while money_paid < money_needed:
while True:
try:
money_current = float(input("Introduce tu moneda: "))
break
except ValueError:
print('Please enter a number.')
money_paid += money_current
print(f'Paid ${money_paid}/${money_needed}')
if money_paid>{select_ware}: #This is the part where I want to substitute the value to call the variable.
print(f'Su cambio es ${money_paid-money_needed}')
return money_paid, money_needed
def main():
wares = {'A1': 6, 'A2': 7.5, 'A3': 8, 'A4': 10, 'A5': 11}
selected_ware = select_ware(wares)
pay_ware(wares, selected_ware)
if __name__ == "__main__":
main()
The question is this:
if money_paid>{select_ware}: #This is the part where I want to substitute the value to call the variable.
print(f'Su cambio es ${money_paid-money_needed}')
How can I implement it to avoid making long conditions for each value, that is, for the value of 'A1': 6, 'A2': 7.5, 'A3': 8, 'A4': 10, 'A5': 11?
Thanks for reading. Regards.
You are almost done! Just modify {select where} by money needed. You can also modify the Try Exception statement in order to avoid stop your program until the money current is a float number:
def pay_ware(wares, selected):
money_needed = wares[selected]
money_paid = 0
valid_money_current = False # para chequear que el pago sea con monedas
while money_paid < money_needed:
while not valid_money_current:
money_current = float(input("Introduce tu dinero: "))
if type(money_current) is float:
valid_money_current = True # el pago es valido
else:
print('Please enter a number.')
money_paid += money_current
print(f'Paid ${money_paid}/${money_needed}')
if money_paid > money_needed: #This is the part where I want to substitute the value to call the variable.
print(f'Su cambio es ${money_paid-money_needed}')
return money_paid, money_needed

Creating a subject and grading system in Python

I am trying to create a gradingsystem for a UNI project.
we are told to have 3 global lists:
Emner = ["INFO100","INFO104","INFO110","INFO150","INFO125"]
FagKoder = [["Informasjonsvitenskap","INF"],["Kognitiv vitenskap","KVT"]
Karakterer=[["INFO100","C"],["INFO104","B"],["INFO110","E"]]
With these lists we are suppost to create a way to view the subjects(Emner), with grades from Karakterer, but we should also be able to view subjects without grades. It should be displayed like this:
We should also be able to add new subjects in (Emner) and add new Grades in (Karakterer). All of this should be displayed as in the picture above.
I have been trying all different kind of ways of doing this, but i keep returning to one of two problems. Either im not able to print a subject without a grade, or if i add a new subject(Emne), and want to add a grade(Karakter) i am not able to place it to the right Subject, as it just saves at the first one without a grade.
hope anyone can help me with this, going crazy here!
Code i have so far:
def emneliste():
global Emner
global Karakterer
emne,kar = zip(*Karakterer)
ans = [list(filter(None, i)) for i in itertools.zip_longest(Emner,kar)]
def LeggTilEmne():
global Karakterer
global Emner
nyttEmne = input("Skriv ny emnekode (4Bokstaver + 3 tall): ")
if nyttEmne not in Emner:
while re.match('^[A-Å]{3,4}[0-9]{3}$',nyttEmne):
Emner.append(nyttEmne)
print(nyttEmne + " Er lagt til!")
start()
print("Feil format")
LeggTilEmne()
else:
print("Dette Emnet er allerede i listen din")
start()
def SettKarakter():
global Karakterer
global Emner
VelgEmne = input("Hvilke emne? ")
Emne,Karakter = zip(*Karakterer)
if str(VelgEmne) not in str(Emner):
print("Dette faget er ikke i din liste")
feil = input("om du heller ønsket å opprette fag trykk 2, ellers trykk enter ")
if feil == str(2):
LeggTilEmne()
else:
start()
else:
if str(VelgEmne) in str(Karakterer):
index = Karakterer.index([VelgEmne,"C"])
Karakterer.pop(index)
SettKar = input("Karakter? ")
Emner.append([VelgEmne,SettKar])
print("Karakter " + SettKar + " Er Lagt til i " + VelgEmne)
start()
else:
SettKar = input("Karakter? ")
if str(VelgEmne) in str(Emner):
index = Emner.index(VelgEmne)
print(index)
Emner.pop(index)
Emner.insert(index,[VelgEmne,SettKar])
print("Karakter " + SettKar + " Er Lagt til i " + VelgEmne)
start()
else:
print("Virker Ikke")
start()
You can make Karakterer a dict instead so that you can iterate through the subjects in Emner and efficiently look up if a subject is in Karakterer with the in operator:
Karakterer = dict(Karakterer)
for subject in Emner:
print(*([subject] + ([Karakterer[subject]] if subject in Karakterer else [])))
This outputs:
INFO100 C
INFO104 B
INFO110 E
INFO150
INFO125
Here's an updated GradeHandler class demo. I tried to allow for updating grades, removing subjects, etc.:
__name__ = 'DEMO'
class GradeHandler(object):
EMNER = ["INFO100","INFO104","INFO110","INFO150","INFO125"]
FAGKODER= [["Informasjonsvitenskap","INF"],["Kognitiv vitenskap","KVT"]]
KARAKTERER = [["INFO100","C"],["INFO104","B"],["INFO110","E"]]
def __init__(self):
self.Emner = self.EMNER
self.FagKoder = self.FAGKODER
self.Karakterer = self.KARAKTERER
self.__create_grade_dict()
def remove_subject(self, subject_name):
"""
Remove a subject ot the classes class list variable.
"""
try:
self.Emner = [i for i in self.EMNER if i != subject_name]
self.__create_grade_dict()
except ValueError:
pass
def add_subject(self, subject_name):
"""
Append a subject ot the classes class list variable.
"""
if not subject_name in Emner:
self.Emner.append(subject_name)
self.__create_grade_dict()
def __create_grade_dict(self, grade_dict=None):
"""
Split grades matrix into separate parts; Create and set a dictionary of values.
"""
if grade_dict is None:
self.grade_dict = dict()
sub, grade = zip(*self.Karakterer)
karakterer_dict = {k:v for k, v in list(zip(sub, grade))}
for i in self.Emner:
if i in karakterer_dict.keys():
self.grade_dict[i] = karakterer_dict[i]
else:
self.grade_dict[i] = ''
def update_grade(self, subject_name, grade='A'):
"""
Update a grade in the grade dictionary.
Will also add a subject if not alrady in the dictionary.
"""
try:
self.grade_dict[subject_name] = grade
except (KeyError, ValueError):
pass
def print_grades(self, subject_name=None):
"""
Print dictionary results.
"""
if subject_name is None:
for k, v in self.grade_dict.items():
print('{} {}'.format(k, v))
else:
if subject_name in self.grade_dict.keys():
print('{} {}'.format(subject_name, self.grade_dict[subject_name]))
if __name__ == 'DEMO':
### Create an instance of the GradeHandler and print initial grades.
gh = GradeHandler()
gh.print_grades()
### Append a class
gh.add_subject('GE0124')
gh.print_grades()
### Add grade
gh.update_grade('GE0124', 'B+')
gh.print_grades()
### Update grades
gh.update_grade('GE0124', 'A-')
gh.print_grades()
### Remove subject (will also remove grade.
gh.remove_subject('GE0124')
gh.print_grades()

How can I modify this code so it doesn't go back to the beginning of the function, but a little bit after the beginning?

I'm working on a school project and I have a problem. I have to write code for apothecary where clients can buy medicine. So, I need to make restrictions, which one doesn't go with others and etc. Here is the code:
def prodajLek():
lekovi = Fajl1.UcitavanjeLekova()
lekoviRed = []
brojacZaForPetlju = 1
n = 0
cena = 0
kolicina = []
korpa = []
rednibrojevilekova = []
ukupnacena = 0
print(" Fabricki naziv Genericki naziv Serijski broj Kolicina Cena \n")
for i in lekovi:
x = i.strip().split("|")
lekoviRed.append(x)
if lekoviRed[n][5] == "False":
print(brojacZaForPetlju,"\t {:10} \t {:10} \t\t\t {:3} \t\t\t {:4} \t\t {:5}".format(x[0],x[1],x[2],x[3],x[4]))
brojacZaForPetlju = brojacZaForPetlju + 1
n = n + 1
print("\n\n\n\n")
rednibrleka = input("Izaberite redni broj leka koji zelite da prodate:\n>>\t")
rednibrleka = int(rednibrleka)
rednibrleka = rednibrleka - 1
rednibrojevilekova.append(rednibrleka)
kolicinaZahteva = input("Koju kolicinu zelite da prodate?\n>>\t")
kolicinaZahteva = int(kolicinaZahteva)
if kolicinaZahteva > int(lekoviRed[rednibrleka][3]):
print("Nema toliko na lageru!\n")
Fajl1.LekarMenu()
kolicina.append(kolicinaZahteva)
cena = int(lekoviRed[rednibrleka][4])
korpa.append(cena)
print("Da li zelite da kupite jos lekova?\n1.Da\n2.Ne\n")
nastavakKupovine = input(">>")
if nastavakKupovine == "1":
prodajLek()
elif nastavakKupovine == "2":
Fajl1.LekarMenu()
So, when I get to the nastavakKupovine input, when I press 1, I need to continue shopping and store my row numbers, my price and quantity in arrays rednibrojlekova = [] , korpa = [] and kolicina = []. But I have a problem, because I dont know how to continue this without reseting these arrays to empty.
The standard idiom for what you want to do is a while True loop. Rather than show how to change your (rather long) function, here's a very simple one which hopefully shows the principle in a straightforward way:
def ask():
answers = []
while True:
response = input("What do you have to say? ")
answers.append(response)
check = input("Type 'q' to quit, anything else to repeat: ")
if check == "q":
break
else:
continue
return answers
For this simple function, the else: continue part isn't necessary, because the loop will continue anyway, but I've included it so you can see how to use it.
Here's an example of the function in action:
>>> ask()
What do you have to say? Something
Type 'q' to quit, anything else to repeat:
What do you have to say? Another thing
Type 'q' to quit, anything else to repeat:
What do you have to say? Ok, done
Type 'q' to quit, anything else to repeat: q
['Something', 'Another thing', 'Ok, done']
>>>
You can find out more about while, break and continue by reading the More Control Flow Tools chapter of the official Python tutorial.

Keys and Dictionaries

it seems that my code isn't working well, everytime i run it it seems that the key value of agenda is replaced by the next one I enter instead of adding it as a new one. Please help my find why is this happening and how to i fix it. Thanks!
def contactos():
q=int(raw_input("Desea agregar un contacto (1=si, 0=no): "))
while q==1:
a=raw_input("ingrese nombre contacto, telefono, mail (delimitados por espacio)")
d=a.split()
agenda={}
agenda[d[0]]= "nombre", d[0], "telefono: ", d[1], "mail :", d[2]
q=int(raw_input("Desea agregar otro contacto (1=si, 0=no): "))
print agenda.keys()
return agenda
You are resetting agenda to an empty dictionary each time through the loop. Initialize it once before the loop.
def contactos():
agenda = {}
q=int(raw_input("Desea agregar un contacto (1=si, 0=no): "))
while q==1:
a=raw_input("ingrese nombre contacto, telefono, mail (delimitados por espacio)")
d=a.split()
agenda[d[0]]= "nombre", d[0], "telefono: ", d[1], "mail :", d[2]
q=int(raw_input("Desea agregar otro contacto (1=si, 0=no): "))
print agenda.keys()
Do note Cyber's answer, as well, if you want to add multiple phone numbers and addresses for the same name.
Instead of assigning, which will overwrite the value
agenda[d[0]]= "nombre", d[0], "telefono: ", d[1], "mail :", d[2]
You would have to append
agenda[d[0]].append(["nombre", d[0], "telefono: ", d[1], "mail :", d[2]])
you should/could use class instead
https://docs.python.org/2/reference/datamodel.html
here is a very simple example
class contact:
def __init__(self, name="", phone="", mail=""):
self.phone = phone
self.name = name
self.mail = mail
a = contact("A name")
print a.name
a.mail = "test#gmail.com"
print a.mail

Categories