2

Cuando agrego a un candidato en la opcion 1 y luego voy a listado de los candidatos me lo muestra, pero si agrego otro candidato, se sobre escribe el anterior, pero siguen habiendo 2 candidatos pero con los datos del ultimo candidato. ¡AYUDA!

import os
candidatos = []

# Clase para agregar un candidato
class agregarCandidato:
    cedula = ""
    partido = ""

# Funcion para salir del programa
def salir():
    os.system("exit")

# Funcion para limpiar la consola
def limpiar():
    os.system("cls")

# Este es el menu de nuestro programa
def menu():
    limpiar()
    print("**************************")
    print("*Bienvenido a la Agenda*")
    print("**************************")
    print("1)-Agregar Candidato.")
    print("2)-Listado de Candidatos.")
    print("3)-Eliminar Candidato.")
    print()
    opcion = input("Eliga una opcion: ")
    # Agregar candidato
    if opcion == "1":
        limpiar()
        candidato = agregarCandidato()
        agregarCandidato.cedula = input("Coloca tu cedula: ")
        agregarCandidato.partido = input("Coloca tu partido: ")
        candidatos.append(candidato)
        print("Candidato agregado correctamente!")
        print()
        input("Presione ENTER para continuar")
        menu()

    # Listado de candidatos
    elif opcion == "2":
        print("Lista de candidatos")
        print("Cedula       Partido")
        for candidato in candidatos:
            print(f"{candidato.cedula}      {candidato.partido}")
        input("Presione ENTER para continuar")

        menu()

    # Eliminar candidato
    elif opcion == "3":
        limpiar()
        print("Selecione el Candidato a eliminar")
        posicion = 0
        for candidato in candidatos:
            print(f"{posicion}->{candidato.cedula}")
            posicion = posicion + 1
        elim = int(input("Digite el numero del Candidato a eliminar: "))
        candidatos.pop(elim)
        print("Candidato eliminado correctamente!")
        input("Presione ENTER para continuar")
        menu()

     # Salir de la app
    elif opcion == "5":
        limpiar()
        print("Vuelva pronto!")
        salir()
    # Validar opcion
    else:
        limpiar()
        print("Eliga una opcion valida")
        input("Presione ENTER para continuar")
        menu()

menu()  

Cuando eligo la opcion 1 y digito los datos todo bien y cuando reviso el listado con la opcion 2 el listado aparace asi:

Listado:

Cedula       Partido
987654321      plh

Entonces cuando vuelvo a agregar otro candidato, ejemplo:

Agregando candidato

Cedula : 123456789
partido: prd

Y vuelvo a revisar el listado con la opcion 2, me muestra esto:

Listado:

Cedula       Partido
123545487     prd
123545487     prd

FJSevilla
  • 55,603
  • 7
  • 35
  • 58
  • Hola, perdona pero en si ¿qué es lo que quieres hacer? Si nos pudieras dar más detalles de lo que quisieras lograr y tu salida esperada, seguro podríamos ayudarte. Te recomiendo leer [Como preguntar](https://es.stackoverflow.com/help/how-to-ask) – Ricardo J. Martínez Suástegui Feb 06 '20 at 16:07

1 Answers1

2

Tu error se debe a que usas atributos de clase y no de instancia para definir los atributos de cada candidato.

Los atributos de clase se comparten entre todas las instancias de la clase, por lo que cuando modificas dichos atributos al agregar el segundo candidato la instancia del primero se ve también afectada.

La solución es simplemente usar atributos de instancia para cedula y partido, que es lo que realmente son ya que cada candidato tiene los suyos (pertenecen a cada instancia).

Te aconsejo mirarte estas dos preguntas para comprender mejor la diferencia:

Es cierto que en tu caso podrías dejar la clase como la tienes y asignar a través de la instancia mediante:

 candidato = agregarCandidato()
 candidato.cedula = input("Coloca tu cedula: ")
 candidato.partido = input("Coloca tu partido: ")

pero esto es una "trampa" dado que lo que haces es crear dos nuevos atributos de instancia "al vuelo" que solapan los de clase que defines en la misma (pero que siguen existiendo). Además, si en vez de cadenas fueran objetos mutables esto no funcionaría si no hay una nueva asignación de por medio. En mi respuesta a la primera pregunta enlazada arriba se explica esto con más detalle.

Por otro lado, te aconsejo cambiar el nombre de la clase por Candidato, es más legible que usar agregarCandidato, que parece el nombre de una función/método más que el nombre de una clase.

En definitiva, tu clase podría quedar como:

class Candidato:
    def __init__(self, cedula="", partido=""):
        self.cedula = cedula
        self.partido = partido

y luego simplemente haces:

cedula = input("Coloca tu cedula: ")
partido = input("Coloca tu partido: ")
candidato = Candidato(cedula, partido) # instanciamos la clase
candidatos.append(candidato)

o también:

candidato = Candidato() # instanciamos la clase
candidato.cedula = input("Coloca tu cedula: ")
candidato.partido = input("Coloca tu partido: ")
candidatos.append(candidato)

Una observación más simplemente (no es un error), cuando requieras enumerar un iterable puedes recurrir a enumerate() en vez de usar una variable externa que actue de contador que es menos eficiente, en vez de:

posicion = 0
for candidato in candidatos:
    print(f"{posicion}->{candidato.cedula}")
    posicion = posicion + 1

puedes hacer:

for posicion, candidato in enumerate(candidatos):
    print(f"{posicion}->{candidato.cedula}")

El código completo quedaría:

import os


candidatos = []

# Clase para agregar un candidato
class Candidato:
    def __init__(self, cedula="", partido=""):
        self.cedula = cedula
        self.partido = partido

# Funcion para salir del programa
def salir():
    os.system("exit")

# Funcion para limpiar la consola
def limpiar():
    os.system("cls")

# Este es el menu de nuestro programa
def menu():
    limpiar()
    print("**************************")
    print("*Bienvenido a la Agenda*")
    print("**************************")
    print("1)-Agregar Candidato.")
    print("2)-Listado de Candidatos.")
    print("3)-Eliminar Candidato.")
    print()
    opcion = input("Eliga una opcion: ")
    # Agregar candidato
    if opcion == "1":
        limpiar()

        cedula = input("Coloca tu cedula: ")
        partido = input("Coloca tu partido: ")
        candidato = Candidato(cedula, partido)
        candidatos.append(candidato)
        print("Candidato agregado correctamente!")
        print()
        input("Presione ENTER para continuar")
        menu()

    # Listado de candidatos
    elif opcion == "2":
        print("Lista de candidatos")
        print("Cedula       Partido")
        for candidato in candidatos:
            print(f"{candidato.cedula}      {candidato.partido}")
        input("Presione ENTER para continuar")

        menu()

    # Eliminar candidato
    elif opcion == "3":
        limpiar()
        print("Selecione el Candidato a eliminar")
        for posicion, candidato in enumerate(candidatos):
            print(f"{posicion}->{candidato.cedula}")
        elim = int(input("Digite el numero del Candidato a eliminar: "))
        candidatos.pop(elim)
        print("Candidato eliminado correctamente!")
        input("Presione ENTER para continuar")
        menu()

     # Salir de la app
    elif opcion == "5":
        limpiar()
        print("Vuelva pronto!")
        salir()
    # Validar opcion
    else:
        limpiar()
        print("Eliga una opcion valida")
        input("Presione ENTER para continuar")
        menu()

menu()
FJSevilla
  • 55,603
  • 7
  • 35
  • 58