Reputation:
I'm learning Python and trying to build code where the for loop checks if a string is empty or non-numeric before it proceeds to add everything. How do I prevent it from going there and instead instruct it to loop through b to e?
Upvotes: 0
Views: 1334
Reputation: 231
You should check your inputs and then compute the result. These are two separate concerns your code has to handle. Do not do these different operations simultaneously. In your case you try return the sum after having checked only the first element of chocolate
. Of course this fails if your second element already is e.g. None
.
You should also take care about your variable naming. In Python, everything you define outside the function is also known inside the function scope:
x = 1
def f(y):
print(x) # x is known here, will print 1
print(y) # will print 2
f(y=2)
Hence
chocolate = [...]
def f(chocolate): # overwrites the `chocolate` variable defined previously
print(chocolate) # will print 1 instead of the list
f(chocolate=1)
Anyhow, to address your example, you should to something like the following:
A = input("Please input the price of the first chocolate:")
...
E = input("Please input the price of the 5th chocolate:")
CHOCOLATE = [A, B, C, D, E]
# naming convention: global variables, i.e. such declared outside a function/class scope
# should be capitalized
def chocolatebill(chocolates):
_validate_input(chocolates)
bill_day = sum(map(int, chocolates))
bill_week = 5 * bill_day
return f"Your bill for today is {bill_day}. The total bill for this week is {bill_week}."
def _validate_input(chocolates):
if len(chocolates) != len(set(chocolates)):
# this does not need to be checked every time in the for loop
raise Exception("Double check your input. The price of each chocolate must be different.")
for i in chocolates:
if not i: # checks if the input is an empty string (evaluates to True if empty)
raise Exception("You missed a price. Go back and input each price again.")
elif not i.isnumeric(): # instead of `... == False`
raise Exception("You missed a price. Go back and input each price again.")
print(chocolatebill(CHOCOLATE))
A few points here:
input
method always results in an empty string (''
), never in None
Exception
. Ideally you even want dedicated exceptions, e.g. InvalidPriceError
like
class InvalidPriceError(Exception):
pass
raise InvalidPriceError("You missed a price. Go back and input each price again.")
This makes your code much more expressive.sum(map(int, chocolates))
is valid for an arbitrary number of chocolate prices. Here sum
returns the sum of elements in a a list-like element. map(int, chocolates)
here maps the int
method onto the chocolates
list, i.e. trys to apply it to each element and returns a list of the result (i.e. a generator to be precise)._validate_input
function because it is supposed to be a "private" method. I.e. it is supposed to be only used inside the scope of the chocolatebill
function. This is a Python naming. convention.There is even a lot more to mention here, but I don't want to stress you with too much information. I think this is already enough.
Upvotes: 0
Reputation: 11
if i == None:
- this condition will not work if variable == ''
I replaced it with if not all(tuple(map(bool, chocolate)))
- it is going to make all empty elements in list bool type. If element is empty it will be False else True. all() function checks if all the elements in list are True - it will return True.
Also i replaced this elif i.isnumeric() == False:
, with this not all(tuple(map(str.isdigit, chocolate)))
, this code will use for each element method isdigit, works like previous one.
So then i think this elif len(chocolate) != len(set(chocolate)):
part of your code is quite ok
Instead of this long code billday = int(a) + int(b) + int(c) + int(d) + int(e)
, you can use sum() function: billday = int(a) + int(b) + int(c) + int(d) + int(e)
And the last one i replaced code in else with f string: f"Your bill for today is {billday}. The total bill for this week is, {5 * billday}."
This is the final code:
b = input("Please input the price of the 2nd chocolate:")
c = input("Please input the price of the 3rd chocolate:")
d = input("Please input the price of the 4th chocolate:")
e = input("Please input the price of the 5th chocolate:")
chocolate = [a, b, c, d, e]
def chocolatebill(chocolate):
if not all(tuple(map(bool, chocolate))) or not all(tuple(map(str.isdigit, chocolate))):
return "You missed a price. Go back and input each price again."
elif len(chocolate) != len(set(chocolate)):
return "Double check your input. The price of each chocolate must be different."
else:
billday = sum(map(int, chocolate))
return f"Your bill for today is {billday}. The total bill for this week is, {5 * billday}."
print(chocolatebill(chocolate))```
Upvotes: 1
Reputation: 236114
There are several mistakes in your code:
None
use is
, not ==
.Upvotes: 1