I have been testing some my code and for some reason my if statement is being ignored. The first if statement works but the second if statement doesn't, i have tried changing it to elif and it still doesn't work. Thanks in advance.
import random
diff = input("What is the ritual difficulty? ")
level = input("How many ritual levels do you have that pertain to this ritual? ")
bag = []
for success in xrange(10):
bag.append("Success")
bag.append("Flaw")
bag.append("Fail")
extra = level - diff
if extra >= 1:
extra = extra / 2
int(extra)
for chance in xrange(extra):
bag.append("Success")
if extra < 0:
for chance in xrange(extra):
bag.append("Flaw")
bag.append("Fail")
bag.append("Backlash")
print bag
random.shuffle(bag)
outcome = bag.pop()
print "The outcome of the ritual is: ", outcome
You second if will be entered if the diff is larger than the level. However, even if it does get entered it won't actally do something:
if extra < 0:
for chance in xrange(extra):
bag.append("Flaw")
bag.append("Fail")
bag.append("Backlash")
The xrange function will yield an empty "list" (it's not actually a list, as the documentation for xrange explains) for negative values, i.e. nothing will be appended to the bag.
It is not ignored, but when you run a for loop on xrange(extra) with extra being negative, then obviously this loop is immediately terminated.
P.S.: you might wanna try xrange(-extra) instead...
Related
I'm trying to create a function that is similar to a shopping list where the function asks the users for 2 inputs, the first one being of the item and the second one being the number of said item the user wants, the only caveat being that the total number of items needs to be exactly 10.
def manualInput():
items = []
noitems = []
x = 1
while sum(noitems) != 10 and sum(noitems) < 10:
try:
i = str(input(f'Item {x}: '))
noi = int(input(f'No. of {i}: '))
items.append(i)
noitems.append(noi)
x = x+1
except ValueError:
print('Check inputs and try again')
items.clear()
noitems.clear()
manualInput()
if sum(noitems) > 10:
print('Number of items need to be exactly 10. Try again')
items.clear()
noitems.clear()
manualInput()
return items, noitems
Now this function works perfectly fine if the user does it perfectly the first time around. However if a ValueError is thrown or the sum of the number of items is greater than 10, the lists always return as empty lists despite the function asking the users for their inputs again.
For example if the user wants to type in Oranges and Apples and wants 6 and 4 of each respectively and manages to input all the information correctly, the first time around, the function returns (['Oranges', 'Apples'], [6, 4]) which is what I want.
In the event of an error however, lets say the user accidently inputs Oranges Apples 6 5 , the function does print out Number of items need to be exactly 10. Try again but when the user inputs all the information again, correctly this time, the function does stop but returns ([], []).
I've tried taking out the item.clear() and noitems.clear() commands but this just results in the function returning (['Oranges', 'Apples'], [6, 5])
So to sum it up I don't know why my lists aren't being appended the second time around when I call the function again in the event of an error. It was my understanding that when u call a function within a function it sort of acts like a loop where the function is run again from the top.
It seems you have not understood recursion and the advantage of it.
Your function creates everytime it gets called a new empty items and noitems list. That's why it is impossible to "remember" the last state.
You have to pass them as function arguments - so that the different rounds of calls can share the state of these two lists.
Second, the while loop is an imperative programming construct - recursion replaces the loop - or should replace it. So you have to get rid of it.
Third, naming in programming is one of the most critical and hardest thing.
noitems tells a reader: "there are no items" - but what you mean are 'Number of items" - call it num_items avoid misinterpretable names.
Fourth, programming is communication. Communication requires that you follow conventions of the peer group with/to which you communicate. Writing Python code means you address your code - besides to the machines especially - to the community of people writing Python code (and who have to maintain the machines and your code). - Be it your successor at work, your colleagues, or your instructor in the course. This means: Always follow the Python code conventions and guidelines (style guide https://peps.python.org/pep-0008/ - in other languages - usually the google style guide for that language).
The style guide says: You don't name in python in camelCase, but in snake_case.https://peps.python.org/pep-0008/
So call it manual_input() - not manualInput() (camelCase is JavaScript and Java convention).
def manual_nput(items = [], num_items = []):
if sum(num_items) == 10: # this is the recursion exit condition
return items, num_items # culminating in returning the result
elif sum(num_items) < 10: # these are the different cases
item = str(input(f'Item {len(items)}: '))
num_item = int(input(f'No. of {item}: '))
return manual_input(items + [item], num_items + [num_item])
# they usually end in a recursive call of the function
# with updated arguments
else: # the number of items is > 10
# in this case remove the last item and call the manual_input again
print('Number of items need to be exactly 10. Try again')
return manual_input(items[:-1], num_items[:-1])
# this [:-1] removes the last input and puts the state of
# items and num_items back to the beginning of the previous call
In my tutorial book, the writer formate this program as shown in code no.2. while my intuitive tells me to write the program like shown in code no.1. Both programs get the job done for me, but is there a difference between these two codes? If there is, which way is better, in your opinion?
#1
total = 0
count = 0
while (True):
inp = input('Enter a number: ')
if inp == 'done':
break
else:
value = float(inp)
total = total + value
count = count + 1
average = total / count
print('Average:', average)
#end of 1
#2
total = 0
count = 0
while (True):
inp = input('Enter a number: ')
if inp == 'done': break
value = float(inp)
total = total + value
count = count + 1
average = total / count
print('Average:', average)
#end of 2
There isn't any difference in how the code runs, sometimes it might be nicer to use a one line if statement. One way isn't objectively better, it comes down to context and personal preference. So choose the way you prefer. If you are ever in any doubt about Python Syntax and its style check out the official Python Style Guide.
One of the key takes from the style guide is that readability counts, so try to pick the most readable option.
I think your way is more readable, but the extra tab on the if statement as well as the else statement is not necessary. I prefere the first option because of the readability
If you are more comfortable using the first syntax, then you can use it without any problem.
However, let me explain the differences between the two code:
Using 'break' means that whenever inp == 'done' is true, then you will exit the current loop and continue. Hence, using an 'else' is not mandatory, because it either reaches or do not reach what you wrote in your 'else' statement, it cannot go in both the if and the else statement.
Otherwise, that is pretty much it, both codes will give you the same thing :D!
So I am a total beginner yet this is 100% my code and I am proud of it. Now mind you I need a little cleaning up, however it does what I want it too. My issue is this: In order to turn this in for credit, one of the things is that procedures(functions) should not contain more than 18 lines. My function gameCont() has many more. Would anyone have suggestions on how I could shorten it up? Additionally I am obviously challenged when it comes to function parameters so any help is appreciated. Please be gentle as I am BRAND NEW! :)
game1 = "When dealing with SCUBA diving there are many dangers to consider. The very first one is _1_. \
I mean if you take water into your lungs, you are NOT SCUBA diving. Another is rising to the surface too quickly which could \
result in the _2_. Now this is a funny name, as I am sure when it happens, you dont feel 'bendy'. Let's also consider Nitrogen Narcosis.\
If you dont know what that is, well when you are very deep and your body is absorbing more nitrogen than it is used to, you can get \
feeling kinda _3_ feeling as though you just drank not one, but _4_ martinis"
game1_answers = ["drowning", "bends", "drunk", "2"]
game2 = "When you first learn to dive you are taught to do dives within a no DECOmpression limit(NDL). \n This means you do not want to \
stay that deep too long or you will rack up _1_. \n If you DO stay longer than what the NDL allows, you will have an obligation to \
take your time getting to the surface allowing that _2_ gas to leave your body. If you were taking IN gas you may call it \
in-gassing, but when you are decompressing, it may be called _3_-gassing. You are taught also, how to read _4_"
game2_answers = ["deco", "nitrogen", "off", "tables"]
game3 = "Equipment used by cold water divers such as myself are as such. On my head I would wear a _1_. To help regulate the breathing\
pressure from my SCUBA tank I would use a _2_. To help me propel through the water I would place_3_ on my feet. Considering \
we cannot see underwater I need to be wearing a _4_ on my face. Diving in the tropic, many people would use wetsuits, however it's\
very cold where I dive so we wear _5_ suits."
game3_answers = ["hood", "regulator", "fins", "mask", "dry"]
def howManyTries():
gameTries = raw_input("Thanks for giving my quiz a try, how many attempts do you want? ")
return int(gameTries)
def game_choice(): #this function is used to determin which difficulty the user wants and returns the proper game and answer list
user_input = raw_input("Greetings. This is my Udacity project for fill in the blanks. Which one of my options would you like?\
easy, hard, or hardest? Please take note of capitalization ")# this will define the user_input variable to raw input placed in by user
print ("\n" * 20)# just something to clean up the screen
print "Decided to choose " + user_input + '?' " Well " + user_input + " it is"# this confirms to the user which difficulty they chose.
print ""
print ""
if user_input == "easy": #easy returns game1 and game1 answers
return game1, game1_answers
elif user_input == "hard": # hard returns game2 and game2 answers
return game2, game2_answers
elif user_input == "hardest": #hardest returns game3 and game 3 answers
return game3, game3_answers
else:
print "It seems that " + user_input + " is not a valid response" #in case the user doesnt choose or spell choice correctly
def gameCont():
blanks = 1 #this assings blank to 1 which will tell the user which blank they are guessing in below prompt
attempts = howManyTries() #this calls the howManyTries function for a user choice integer
quiz, answers = game_choice() #this returns 2 values (game# and game# answers)
while attempts > 0: #while attempts (called from function) is greater than 0 we will loop this
print quiz #prints the chosen quiz for user updated each time the loop runs with correct answer
print("\n" * 10) #clears some more screen to loook better for the user
guess = raw_input("Reading the above paragraph, What would your guess be for _" + str(blanks) + "_") #asks for guess for current blank which always starts at 1
print("\n" * 10) #clears some more screen to loook better for the user
if guess == answers[blanks - 1]: #because indexing count starts at zero, and blanks start at 1 this will check if answer is equal to blanks - 1
print "As you can see your correct choice has replaced the variable, great job!!"#this will print if the guess is correct
quiz = quiz.replace("_" + str(blanks) +"_", answers[blanks - 1]) # here is the line of code that replaces the blank with the correct guess
blanks += 1 # this adds 1 to the blank which will prompt the user to move to the NEXT blank when loop begins again
if blanks > len(answers):
print ("\n" * 10)
print "YOU DID IT!! Here is the final paragraph with all the correct answers"
print ("\n" * 2)
print quiz
break
elif guess != answers[blanks -1]: #if the answer does not match the list index
attempts = attempts - 1 #then we will subtract 1 from the attempts
print ("\n" * 10)
print "Oops that is not correct, there should be hints in the paragraph" # lets user know they were wrong
print "You have " + str(attempts) + " attempts left." # lets the user know how many attempts they have left
print ""
if attempts < 1:
print "Well it looks like you are out of choices, Try again?"
break
print "Thanks for playing"
gameCont()
All of the printing that you're doing could be done in a separate function
def game_print(newlines_before, text, newlines_after)
print ("\n" * newlines_before + text + "\n" * newlines_after)
Two suggestions:
Delegate tasks that are accomplished by your function to smaller functions. So, for example, if you had a function that needed perform task A and performing that task could be divided into tasks B, C, and D, then create helper functions and call them inside of the function that does task A.
You have long strings, maybe store them somewhere else? Create a class just for constant strings of related functions and access that when you need a particular string. It'll make it less likely that you'll make a mistake when you need to use that string in multiple locations.
class Constants:
str1 = "..."
str2 = "..."
print(Constants.str1)
you can call a function from inside another function. inside an if statement you could call a small new function that just prints some stuff. this should make it easy to get the function size down.
something like this should work:
def correct(quiz, blanks):
print "As you can see your correct choice has replaced the variable, great job!!"
quiz = quiz.replace("_" + str(blanks) +"_", answers[blanks - 1]) # here is the line of code that replaces the blank with the correct guess
blanks += 1 # this adds 1 to the blank which will prompt the user to move to the NEXT blank when loop begins again
if blanks > len(answers):
print ("\n" * 10)
print "YOU DID IT!! Here is the final paragraph with all the correct answers"
print ("\n" * 2)
print quiz`
remember that you still want to break after calling that function in order to exit your loop.
I'm very new at coding, and I'm trying to create a shop list with items and prices on it.
That is, once typed in all the items, the function should calculate the sum and stop the moment you exceed the budget.
So I wrote something like:
def shoplist():
list={"apple":30, "orange":20, "milk":60......}
buy=str(input("What do you want to purchase?")
If buy in list:
While sum<=budget:
sum=sum+??
shoplist ()
I really don't know how to match the input of an item with the price in the list...
My first thought is to use 'if', but it's kinda impractical when you have more than 10 items on the list and random inputs.
I'm in desperate need of help....So any suggestions would be nice!! (or if you have a better solution and think me writing it this way is complete garbage... PLEASE let me know what those better solutions areðŸ˜ðŸ˜ðŸ˜
The code you post will not run in python. list is a builtin and should not be used for a variable name, and is doubly confusing since it refers to a dict object here. input() already returns a str so the cast has no effect. if and while should be lowercase, and there is no indentation, so we have no way of knowing the limits of those statements.
There are so many things wrong, take a look at this:
def shoplist(budget):
prices = {"apple":30, "orange":20, "milk":60}
# Initialise sum
sum = 0
while sum <= budget:
buy = input("What do you want to purchase?")
# Break out of the loop if the user hts <RETURN>
if not buy: break
if buy in prices:
sum += prices[buy] # This gets the price
else:
print("Invalid item", buy)
shoplist(142)
So what have I changed? The budget has to come from somewhere, so I pass it in as a parameter (142, I made that up). I initialise the sum to zero, and I moved the while loop to the outside.
Notice as well lots of whitespace - it makes the code easier to read and has no effect on performance.
Lots of improvements to make. The user should be shown a list of possible items and prices and also how much budget there is left for each purchase. Note as well that it is possible to go over budget since we might only have 30 in the budget but we can still buy milk (which is 60) - we need another check (if statement) in there!
I'll leave the improvements to you. Have fun!
Take a look at this as an example:
# this is a dictionary not a list
# be careful not using python reserved names as variable names
groceries = {
"apple":30,
"orange":20,
"milk":60
}
expenses = 0
budget = 100
cart = []
# while statements, as well as if statements are in lower letter
while expenses < budget:
# input always returns str, no need to cast
user_input = input("What do you want to purchase?")
if user_input not in groceries.keys():
print(f'{user_input} is not available!')
continue
if groceries[user_input] > budget - expenses:
print('You do not have enough budget to buy this')
user_input = input("Are you done shopping?Type 'y' if you are.")
if user_input == 'y':
break
continue
cart.append(user_input)
# this is how you add a number to anotherone
expenses += groceries[user_input]
print("Shopping cart full. You bought {} items and have {} left in your budget.".format(len(cart), budget-expenses))
I've made some changes to your code to make it work, with explanation including using comments indicated by the # symbol.
The two most important things are that all parentheses need to be closed:
fun((x, y) # broken
fun((x, y)) # not broken
and keywords in Python are all lowercase:
if, while, for, not # will work
If, While, For, Not # won't work
You might be confused by True and False, which probably should be lowercase. They've been that way so long that it's too late to change them now.
budget = 100 # You need to initialize variables before using them.
def shoplist():
prices = { # I re-named the price list from list to prices
'apple' : 30, # because list is a reserved keyword. You should only
'orange' : 20, # use the list keyword to initialize list objects.
'milk' : 60, # This type of object is called a dictionary.
} # The dots .... would have caused an error.
# In most programming languages, you need to close all braces ().
# I've renamed buy to item to make it clearer what that variable represents.
item = input('What do you want to purchase? ')
# Also, you don't need to cast the value of input to str;
# it's already a str.
if item in prices:
# If you need an int, you do have to cast from string to int.
count = int(input('How many? '))
cost = count*prices[item] # Access dictionary items using [].
if cost > budget:
print('You can\'t afford that many!')
else:
# You can put data into strings using the % symbol like so:
print('That\'ll be %i.' % cost) # Here %i indicates an int.
else:
print('We don\'t have %s in stock.' % item) # Here %s means str.
shoplist()
A lot of beginners post broken code on StackOverflow without saying that they're getting errors or what those errors are. It's always helpful to post the error messages. Let me know if you have more questions.
Pretty new to python/programming in general, this is my biggest project yet.
I am writing a program that will do SUVAT equations for you. (SUVAT equations are used to find the displacement, start/end velocity, acceleration and time travelled by an object with constant velocity, you may call them something different.)
I made this list:
variables = ["Displacement", "Start Velocity", "End Velocity", "Acceleration", "Time"]
which is used in the following while/for loop:
a = 0
while a==0:
for variable in variables:
# choice1 is what the user is looking to calculate
choice1 = raw_input("Welcome to Mattin's SVUVAT Simulator! Choose the value you are trying to find. You can pick from " + str(variables))
# will execute the following code when the for loop reaches an item that matches the raw_input
if choice1 == variable:
print "You chave chosen", choice1
variables.remove(variable) #Removes the chosen variable from the list, so the new list can be used later on
a = 1 # Ends the for loop by making the while loop false
# This part is so that the error message will not show when the raw_input does not match with the 4 items in the list the user has not chosen
else:
if choice1 == "Displacement":
pass
elif choice1 == "Start Velocity":
pass
elif choice1 == "End Velocity":
pass
elif choice1 == "Acceleration":
pass
# This error message will show if the input did not match any item in the list
else:
print "Sorry, I didn't understand that, try again. Make sure your spelling is correct (Case Sensitive), and that you did not inlcude the quotation marks."
Hopefully the comments I have written in the code should explain my intentions, if not, feel free to ask anything.
The problem is that when I run the code, and input choice1, the for loop activates the last line of code:
else:
print "Sorry, I didn't understand that, try again. Make sure your spelling is correct (Case Sensitive), and that you did not inlcude the quotation marks."
and then prompts me to enter the input again, and will do this as many times as it needs to get to the item on the list that I am typing.
However, I specifically coded that if what I input does not match the item on the list the for loop is currently checking, but does match one of the other items on the list, then it should pass and loop round to checking the next item.
I am probably doing something stupid, but I don't see it, so please help me figure out what I have to do to get my desired result? I assumed it was the syntax I had wrong so that is why that is the title.
Thanks for any help, I appreciate it.
Besides the problem with the indentation in your pasted code, I would rewrite it as such:
while True:
choice = raw_input('...')
if choice in variables:
print "You chave chosen", choice
# Remove the chosen member from the list
variables = [v for v in variables if v != choice]
# Break out of loop
break
# Print error messages etc.
Also remember that string comparisons are case sensitive. I.e 'Displacement' != 'displacement'.