insira a descrição da imagem aqui insira a descrição da imagem aqui
Quando tento excluir uma linha do meu arquivo CSV, ele exclui todo o resto e, em seguida, inverte a linha e separa os caracteres em suas próprias colunas. Não tenho ideia do que está acontecendo. Acima, estão as imagens que mostram o antes e o depois do meu arquivo CSV quando tento excluí-lo. Não tenho ideia do que está acontecendo e é muito estranho. Aqui está meu código e o problema está na linha 95:
import csv
import sys
FILENAME = "guests.csv"
def exit_program():
print("Terminating program.")
sys.exit()
def read_guests():
try:
guests = []
with open(FILENAME, newline="") as file:
reader = csv.reader(file)
for row in reader:
guests.append(row)
return guests
except FileNotFoundError as e:
## print(f"Could not find {FILENAME} file.")
## exit_program()
return guests
except Exception as e:
print(type(e), e)
exit_program()
def write_guests(guests):
try:
with open(FILENAME, "w", newline="") as file:
## raise BlockingIOError("Error raised for testing.")
writer = csv.writer(file)
writer.writerows(guests)
except OSError as e:
print(type(e), e)
exit_program()
except Exception as e:
print(type(e), e)
exit_program()
def list_guests(guests):
number_of_guests = 0
number_of_members = 0
total_fee = 0
for i, guests in enumerate(guests, start=1):
print(f"{i}. Name: {guests[0]} {guests[1]}\n Meal: {guests[2]} \n Guest Type: {guests[3]} \n Amount due: ${guests[4]}")
if guests[3] == "guest":
number_of_guests +=1
if guests[3] == "member":
number_of_members +=1
total_fee += 22
print("Number of members: " +str(number_of_members))
print("Number of guests: " +str(number_of_guests))
print("Total fee paid by all attendees: " +str(total_fee))
print()
def add_guests(guests):
fname = input("First name: ")
lname = input("Last name: ")
while True:
try:
meal = str(input("Meal(chicken, vegetarian, or beef): "))
except ValueError:
print("Please enter a meal. Please try again.")
continue
if meal == "beef" :
break
if meal == "chicken" :
break
if meal == "vegetarian" :
break
else:
print("Please enter a meal:(chicken, vegetarian, or beef)")
while True:
attendee_type = input("Are you a 'member' or 'guest'?")
if attendee_type == "member" :
break
if attendee_type == "guest" :
break
else:
print("Please enter either 'member' or 'guest': ")
fee = 22
guest = [fname, lname, meal, attendee_type, fee]
guests.append(guest)
write_guests(guests)
print(f"{fname} was added.\n")
def delete_guest(guests):
name = input("Enter the guest's first name: ")
for i, guests in enumerate(guests, start=1):
if name == guests[0]:
del guests[i]
write_guests(guests)
print(f"{name} removed from catalog.")
print("")
break
print(f"{name} doesn't exist in the list.")
def menu_report(guests):
number_of_beef = 0
number_of_chicken = 0
number_of_vegetarian = 0
for i, guests in enumerate(guests, start=1):
if guests[2] == "beef":
number_of_beef +=1
if guests[2] == "chicken":
number_of_chicken +=1
if guests[2] == "vegetarian":
number_of_vegetarian +=1
print("Number of Chicken entrees: " +str(number_of_chicken))
print("Number of Beef entrees: " +str(number_of_beef))
print("Number of vegetarian Meals: " +str(number_of_vegetarian))
print()
def display_menu():
print("COMMAND MENU")
print("list - List all guests")
print("add - Add a guest")
print("del - Delete a guest")
print("menu - Report menu items")
print("exit - Exit program")
print()
def main():
print("The Guests List program")
print("")
guests = read_guests()
while True:
display_menu()
command = input("Command: ")
if command.lower() == "list":
list_guests(guests)
elif command.lower() == "add":
add_guests(guests)
elif command.lower() == "del":
delete_guest(guests)
elif command.lower() == "menu":
menu_report(guests)
elif command.lower() == "exit":
break
else:
print("Not a valid command. Please try again.\n")
print("Bye!")
quit()
if __name__ == "__main__":
main()
Isto é para uma tarefa que vence amanhã! arg!
Pensei que ele excluiria a linha, mas, em vez disso, ele salvou apenas essa linha e transformou cada entrada em uma coluna dessa linha em sua própria linha. Cada caractere na linha original agora estava separado em sua própria coluna.
No seu loop for, você está reutilizando o nome da variável guests, o mesmo nome da sua lista de todos os guests.
Isso sobrescreve a lista dentro do loop e causa um comportamento inesperado.
Os convidados dentro do loop referem-se a uma única linha de convidado, não mais à lista completa. Ao tentar deletar guests[i], você está excluindo um índice de uma única linha (ou até mesmo uma string, caso tenha sido corrompida). Como resultado, ao chamar write_guests(guests) posteriormente, ele grava dados inválidos no arquivo, causando o problema de "texto lateral" que você descreveu. Você pode corrigir isso alterando o nome da variável do loop para algo diferente, como "guest".
Aqui está uma versão corrigida usando guest como uma variável de loop nomeada.
evitar sombreamento
Use identificadores singulares e plurais quando apropriado. A expressão usual é
for x in xs:
Você escreveu:
O que você queria escrever era
for i, guest in ...
Ao testar
name
a igualdade, você pretendia se referir aguest[0]
, a primeira coluna de uma linha.Infelizmente, a nova
guests
variável local está ocultando oguests
parâmetro original. Como resultado, esse parâmetro não está mais acessível dentro do corpo do loop.sofrer mutação fora do loop
Recomendo atribuir condicionalmente
match_index = i
dentro do loop e emitirdel guests[match_index]
depois que ofor
loop terminar.Além disso, é uma pena que o programa não verifique se o nome de cada convidado é único.
Se você deseja filtrar por um atributo não exclusivo, como remover convidados que comeram "carne", considere criar uma nova lista filtrada e retorná-la. Isso evita pular linhas que possam corresponder.
normalizar primeiro
É melhor diminuir isso imediatamente.
Assim, você pode evitar várias
.lower()
chamadas distrativas nos testes de despacho subsequentes.