Reputation: 11
Whenever I run my code, I get the following error message:
Could somebody help me identify the error? I apologize for the language, but my programming teacher prefers receiving our scripts in Swedish.
The gist of the program, is that it allows a police officer to register (inmatning) stolen cars in a database (brottby.txt). The officer can also check if a license plate is registered in the database (kontroll), deregister a license plate (avregistrering) and print a full list of all stolen cars (forteckning).
The error occurs when I run the section that prints the full list of stolen cars (designated by "while state_forteckning:"). I print every line from the document to the console, but whatever script I write thereafter encounters similar exceptions.
# Importerar os och sys
import os
import sys
# Startlägen för while-loopar
state_pagaende = True
state_inmatning = False
state_kontroll = False
state_avregistrering = False
state_forteckning = False
state_avsluta = False
# Definierar korrekta värden för registreringsskyltar
bokstaver = "abcdefghjklmnoprstuwxyz"
tal = "0123456789"
# Skapa registerfil
try:
f = open('brottby.txt', 'x')
except:
pass
# Huvudloop (för omstart)
while state_pagaende:
# Välkomstprompt
print ("=======================================\n""POLISMYNDIGHETEN I BROTTBY: BILREGISTER\n""=======================================\n\n")
# Alternativmeny
alternativ = input("VÄLJ ETT ALTERNATIV [1-5]:\n\n""1.INMATNING\n""2.KONTROLL\n""3.AVREGISTRERING\n""4.FÖRTECKNING\n""5.AVSLUTA\n\n")
print ("\n\n")
# Bestämmer vilken alternativloop som ska startas
if (alternativ == str(1)):
state_inmatning = True
elif (alternativ == str(2)):
state_kontroll = True
elif (alternativ == str(3)):
state_avregistrering = True
elif (alternativ == str(4)):
state_forteckning = True
elif (alternativ == str(5)):
state_avsluta = True
else:
print ("OGILTIG INMATNING!\n\n")
continue
# Inmatning av ny stulen bil
while state_inmatning:
print ("*INMATNING*\n\n")
# Behandling av bokstäver i registreringsnumret
registreringsbokstaver = input("MATA IN REGISTRERINGSNUMMRETS TRE FÖRSTA TECKEN [BOKSTÄVER]:\n\n")
print ("\n")
for tkn in registreringsbokstaver:
if (tkn.lower() in bokstaver and len(registreringsbokstaver) == int(3)):
continue
else:
print ("OGILTIG INMATNING!\n\n")
state_inmatning = False
# Behandling av siffror i registreringsnumret
registreringssiffror = input("MATA IN REGISTRERINGSNUMMRETS TRE SISTA TECKEN [SIFFROR]:\n\n")
print ("\n")
for tkn in registreringssiffror:
if (tkn.lower() in tal and len(registreringssiffror) == int(3)):
continue
else:
print ("OGILTIG INMATNING!\n\n")
state_inmatning = False
# Definierar registreringsnumret
registreringsnummer = registreringsbokstaver + registreringssiffror
# Kontrollerar om registreringsnumret redan finns i registerfilen
if registreringsnummer.upper() in open('brottby.txt').read():
# Om registreringsnumret redan är registrerat
print ("REGISTRERINGSNUMMER", registreringsnummer.upper(), "FINNS REDAN I DATABASEN!\n\n")
else:
# Om registreringsnumret inte är registrerat
with open("brottby.txt", "a") as f:
f.write("\n" + registreringsnummer.upper())
print ("REGISTRERINGSNUMMER", registreringsnummer.upper(), "ÄR TILLAGD I DATABASEN!\n\n")
# Frågar användaren om hen vill avsluta programmet eller återgå till huvudmenyn
fortsatt_inmatning = input("VILL DU MATA IN ETT TILL REGISTRERINGSNUMMER? [JA/NEJ]\n\n")
print ("\n")
# Fortsätt inmatning
if (fortsatt_inmatning.upper() == "JA"):
continue
# Återgår till huvudmenyn
elif (fortsatt_inmatning.upper() == "NEJ"):
state_inmatning = False
# Ogiltig inmatning
else:
print ("OGILTIG INMATNING!\n\n")
state_inmatning = False
# Kontroll av registreringsnummer gentemot databasen
while state_kontroll:
print ("*KONTROLL*\n\n")
# Inmatning av registreringsnummer för sökning
soktregistreringsnummer = input("VILKET REGISTRERINGSNUMMER VILL DU KONTROLLERA? [UTAN MELLANSLAG]\n\n")
print ("\n")
# Kontrollerar att registreringsnumret som ska kontrolleras har rätt längd
# Om registreringsnumret har rätt längd
if (len(soktregistreringsnummer) == int(6)):
# Kontrollerar registreringsnummer gentemot databasen
if (soktregistreringsnummer.upper() in open('brottby.txt').read()):
print("FORDON", soktregistreringsnummer.upper(), "ÄR REGISTRERAD SOM STULEN I DATABASEN!\n")
else:
print("FORDON", soktregistreringsnummer.upper(), "ÄR INTE REGISTRERAD SOM STULEN I DATABASEN!\n")
# Om registreringsnumret har fel längd
else:
print ("OGILTIG INMATNING!\n")
state_kontroll = False
# Frågar användaren om hen vill avsluta programmet eller återgå till huvudmenyn
fortsatt_kontroll = input("VILL DU KONTROLLERA ETT TILL REGISTERINGSNUMMER? [JA/NEJ]\n\n")
print ("\n")
# Kontrollera ett till registreringsnummer
if (fortsatt_kontroll.upper() == "JA"):
pass
# Återgår till huvudmenyn
elif (fortsatt_kontroll.upper() == "NEJ"):
state_kontroll = False
# Ogiltig inmatning
else:
print ("OGILTIG INMATNING!\n\n")
state_kontroll = False
while state_avregistrering:
print ("*AVREGISTRERING*\n\n")
# Inmatning av registreringsnummer för avregistrering
avregistrering = input("VILKET REGISTRERINGSNUMMER VILL DU AVREGISTRERA FRÅN DATABASEN? [UTAN MELLANSLAG]\n\n")
print ("\n")
# Kontrollerar att registreringsnumret har rätt längd
# Om registreringsnumret har fel längd
if (len(avregistrering) != int(6)):
print ("OGILTIG INMATNING!\n")
state_avregistrering = False
# Om registreringsnumret har rätt längd
else:
# Kontrollerar om registreringsnumret finns i databasen
# Om registreringsnumret inte finns i databasen
if avregistrering.upper() not in open('brottby.txt').read():
print ("REGISTRERINGSNUMMER", avregistrering, "FINNS INTE I DATABASEN!\n")
state_avregistrering = False
# Om registreringsnumret finns i databasen
else:
# För att ta bort ett registreringsnummer ur databasen, måste vi skriva över all information utom den vi vill ta bort till en ny databas
# Vi förbereder genom att döpa om den nuvarande databasen (den ska sen raderas)
os.rename('brottby.txt', 'gammalbrottby.txt')
# Skriver över all information från nuvarandra databas till ny, undantaget det avregistrerade registreringsnumret
with open("gammalbrottby.txt", "r") as input:
with open("brottby.txt", "w") as output:
for line in input:
# Om registreringsnumret vi vill ta bort inte finns på en viss rad, skriv över den raden till den nya filen
if (avregistrering.upper() not in line):
output.write(line)
# Om registreringsnumret vi vill ta bort finns i en viss rad, skriv inte över den
else:
continue
# Vi har nu skapat en ny databas, och raderar därför den gamla
os.remove('gammalbrottby.txt')
print ("FORDON", avregistrering, "ÄR NU AVREGISTRERAD FRÅN DATABASEN!")
# Frågar användaren om hen vill avsluta programmet eller återgå till huvudmenyn
fortsatt_kontroll = input("VILL DU AVREGISTRERA ETT TILL REGISTRERINGSNUMMER FRÅN DATABASEN? [JA/NEJ]\n\n")
print ("\n")
# Avregistrera ett till registreringsnummer
if (fortsatt_kontroll.upper() == "JA"):
pass
# Återgår till huvudmenyn
elif (fortsatt_kontroll.upper() == "NEJ"):
state_kontroll = False
# Ogiltig inmatning
else:
print ("OGILTIG INMATNING!\n\n")
state_kontroll = False
# Printar förteckning av alla stulna bilar
while state_forteckning:
print ("*FÖRTECKNING*\n\n")
# För att förteckningen ska vara välformaterad, måste alla blankrader tas bort ur databasen
# Vi döper om nuvarande databasen, som sedan ska raderas
os.rename('brottby.txt', 'gammalbrottby.txt')
# Kopierar gamla databasen rad för rad till en ny databas, undantaget om det är en blankrad
with open("gammalbrottby.txt", "r") as input:
with open("brottby.txt", "w") as output:
for line in input.readlines():
if not line.strip():
continue
else:
output.write(line)
# Raderar gamla databasen
os.remove('gammalbrottby.txt')
# För att förteckningen ska vara välformaterad, måste det sista registreringsnumret i dokumentet följas av en nyrad
with open("brottby.txt", "a") as f:
f.write("\n")
# Printar nu hela databasen, rad för rad, i bokstavsordning (sorted)
forteckningslista = []
with open("brottby.txt", "r") as f:
for line in sorted(f):
print (line)
# Återgår till huvudmenyn
print ("\n")
state_forteckning = False
# Avsluta programmet
while state_avsluta:
print ("*AVSLUTAR PROGRAMMET*\n\n")
# Avslutar programmet
sys.exit()
Upvotes: 0
Views: 143
Reputation: 55770
The problem is that you are redefining, or "shadowing" the name of the builtin function input
. This example reproduces the problem:
while True:
foo = input('What? ')
print('Foo is ', foo)
with open('/dev/null', 'w') as input: # <-- input is being redefined here!
pass
# run the code:
What? bar
Foo is bar
Traceback (most recent call last):
...
foo = input('What? ')
TypeError: '_io.TextIOWrapper' object is not callable
In the first iteration of the loop, the builtin input
function is called to get user input, then the name input
is reassigned to the file object in the with
statement. So now input
refers to the file object, an instance of the TextIOWrapper
class.
In the second iteration of the loop, input
is called again, but now input
is a TextIOWrapper
, which isn't callable, so the TypeError
is raised.
The offending line in your code is:
with open("gammalbrottby.txt", "r") as input:
Change the variable name input
to something else, for example:
with open("gammalbrottby.txt", "r") as inputfile:
with open("brottby.txt", "w") as output:
for line in inputfile:
...
Upvotes: 1