The main problem is that your while loops should be simply if statements:
if business_type.lower() == 'b': if gallons > 8000: water_charge = gallons * .008 else: water_charge = gallons * .006 elif business_type.lower() == 'r': if gallons > 6000: water_charge = gallons * .007 else: water_charge = gallons * .005 else: # So you don't get a NameError for no water_charge water_charge = 0
The reason your while loops never terminate is two reasons: You never read the next line inside that inner loop, and a populated string like 'b' will evaluate like True:
# Strings with content act like True if 'b': print(True) # True # empty strings act as False if not '': print(False) # False
The str.lower() will lowercase the string, so 'R'.lower() returns 'r'. Otherwise there is no break condition for the while and it will spin forever.
Some other suggestions:
1) When opening files, using with eliminates the need to explicitly open and close files:
with open('somefile.txt', 'r') as fh: # Everything else goes under the with statement
2) Explicitly calling fh.readline() isn't necessary, as you can iterate over an open file directly:
with open('somefile.txt', 'r') as fh: for line in fh: # line is the string returned by fh.readline()
This will also terminate when fh is empty, or you reach the end of the file, you might not get explicitly '' when the file is empty, and you no longer need the while loop
3) It's generally bad practice (but also hard to maintain) magic-number code. For instance, what if the account number doesn't have exactly 5 characters? A more succinct way to do this would be with str.split(' '), which will split on spaces:
with open('somefile.txt', 'r') as fh: for line in fh: # This will split on spaces returning a list # ['3147', 'R', '1000'] which can be unpacked into # the three variables like below account_number, business_type, gallons = line.split(' ') # rest of your code here
In total:
# use with for clean file handling with open('somefile.txt', 'r') as fh: # iterate over the file directly for line in fh: # split and unpack account_number, business_type, gallons = line.split(' ') # enforce types gallons = float(gallons) # .strip() will remove any hanging whitespace, just a precaution if business_type.strip().lower() == 'b': if gallons > 8000: water_charge = gallons * .008 else: water_charge = gallons * .006 elif business_type.strip().lower() == 'r': if gallons > 6000: water_charge = gallons * .007 else: water_charge = gallons * .005 else: water_charge = 0.0 print("Account number:", account_number, "Water charge:$", water_charge)
while business_type == 'b' or 'B'should bewhile business_type == 'b' or business_type == 'B'