Only the first conditions is being validated in a python function - python

def dice():
import random
print("******************************")
print("***** DICE GENERATOR ******")
print("******************************")
#dice choice
user_select=int(input("""Choose the type of dice to roll.
(1)1d4
(2)1d6
(3)1d10
(4)1d12
(5)1d20
:"""))
if user_select==1:
dice=random.randint(1,4)
print(dice)
return
if user_select==2:
dice=random.randint(1,6)
print(dice)
return
if user_select==3:
dice=random.randint(1,10)
print(dice)
return
if user_select==4:
dice=random.randint(1,12)
print(dice)
return
if user_select==5:
dice=random.randint(1,20)
print(dice)
return
in the example code above if i give the input as 1 then a random number is generated but or anything else there is no return.I checked in the visualiser ,it is returning a None for all values except 1

This is because you are returning straight after the first condition. I would recommend reading a book on python and understand how functions and returns work.
http://www.learnpython.org/

You have to realise that functions end if any return statement is reached. Functions are small pieces of code that work together on a certain job/goal. Once they are done with it they can return stuff or just nothing, depending on the data types you are working with and the goal of the function.
In your case you need to put only one return after the last print statement.

As stated by others, the problem is that the return is not within the if block. A common way to do what you want is to use elif:
def dice():
import random
print("******************************")
print("***** DICE GENERATOR ******")
print("******************************")
#dice choice
user_select=int(input("""Choose the type of dice to roll.
(1)1d4
(2)1d6
(3)1d10
(4)1d12
(5)1d20
:"""))
if user_select==1:
dice=random.randint(1,4)
elif user_select==2:
dice=random.randint(1,6)
elif user_select==3:
dice=random.randint(1,10)
elif user_select==4:
dice=random.randint(1,12)
elif user_select==5:
dice=random.randint(1,20)
else:
dice=None
print(dice)
(edit) notice that a return statement is not needed at the end of a function because python will automatically return None here. Its harmless and some people prefer to have them.

Related

When returning a value from a function in python, it comes back empty

I am making a minmax algorithm for a simple board game. When the findparent function returns data, sometimes it works fine, othertimes it comes back empty for some reason. Please help.
Below is the malfunctioning part of the code.
from sys import maxsize
class Node(object):
def __init__(self,idepth,iplayernum,iboard):
self.idepth=idepth
self.iplayernum=iplayernum
self.iboard=iboard
self.children=[]
self.createchildren()
def createchildren(self):
if self.idepth>=0:
for x in range(0,4):
if self.iboard[x]>0:
for y in range(1,self.iboard[x]+1):
xiboard=self.iboard.copy()
xiboard[x]-=y
self.children.append(Node(self.idepth-1,-self.iplayernum,xiboard))
def checknodes(node,turn,ibestvalue,bestchoice):
for n in range(len(node.children)):
nchild=node.children[n]
childarr=[nchild,nchild.iboard]
for z in range(0,(idepth-nchild.idepth)):
childarr=findparent(childarr[0],inode)
print(childarr,'after return')
bestchoice=childarr[1]
if nchild.idepth>0:
checknodes(nchild,turn*-1,ibestvalue,bestchoice)
return(bestchoice)
def findparent(fnode,node):
for n in range(len(node.children)):
nhild=node.children[n]
if nhild==fnode and nhild.iboard==fnode.iboard:
print([node,node.iboard],'before return')
return [node,node.iboard]
elif nhild.idepth>0:
findparent(fnode,nhild)
iboardstart=[7,5,3,1]
idepth=3
icurplayer=1
row=int(input('The board is\n{}\n{}\n{}\n{}\nWhat row would you like to take from?'.format(iboardstart[0],iboardstart[1],iboardstart[2],iboardstart[3])))-1
amount=int(input('\nHow many would you like to take?'))
iboardstart[row]-=amount
icurplayer*=-1
inode=Node(idepth,icurplayer,iboardstart)
bestchoice=-100
ibestvalue=-icurplayer*maxsize
bestchoice=checknodes(inode,-1,ibestvalue,bestchoice)
iboardstart=bestchoice
print('Computer plays\n{}\n{}\n{}\n{}'.format(iboardstart[0],iboardstart[1],iboardstart[2],iboardstart[3]))
icurplayer*=-1
If you run it just input 1 for row and 1 for amount and see what it prints out.
Hope you can help me guys, I would really appreciate it.
Your issue is that findparent doesn't actually return anything from its recursive call.
However it's not as simple as return findparent(fnode,nhild) as this has the possibility of returning None if it's searching in the wrong branch. So you would need to get the value from the recursive call, check that the value exists, and then return it if it does.
You might try something like this:
def findparent(fnode, node):
value = None
for nchild in node.children:
if nchild is fnode and nchild.iboard == fnode.iboard:
print([node, node.iboard], 'before return')
value = [node, node.iboard]
elif nchild.idepth > 0:
value = findparent(fnode, nchild)
if value:
return value
As a side note, when looping through elements of a list, it's better to use
for nchild in node.children:
instead of
for n in range(len(node.children)):
nchild=node.children[n]
It seems there is a typo in checknodes method :
Try changing
childarr=findparent(childarr[0],inode)
into
childarr=findparent(childarr[0],node)

50% Probability of multiple elements on Python

I'm trying to create a "football" game on python and if the user wants to pass the ball, my code is supposed to have a 50% probability of having an incomplete pass or a completion yielding between 3 and 15 yards
I know that to print the yardage, the code would look something like
import random
input("Enter r to run and p to pass")
p = print(random.randint(3,15))
but I'm not sure how to make "Incomplete" show up as a 50% probabilty
You can use the code below. As you have defined a statement to pick a random number between 3-15, you can create another statement to pick 0 or 1 (not %50 guaranteed). Also in your code, you are assigning return value of the print function to a parameter. This is definitely wrong! Print function returns nothing so assigning it to another variable is meaningless.
x = random.randint(0,1)
if x == 1:
random.randint(3,15)
else:
# incomplete pass
You could use something like this.
import random
inp = input("Enter r to run and p to pass")
if(inp == "p"):
print(random.choice([random.randint(3,15),0]))
elif(inp == "r"):
print("ran successfully")
This: random.choice([random.randint(3,15),0]) is the important bit. random.choice takes multiple values (in this case 2) in a list, and picks one randomly (2 values => 50% probability).
I also fixed the input output thing. To get input from the user you assign the value of input to a variable like this: example = input("Your input here: "). If you ran that line of code, and answered with potato for instance, you'd be able to print example and get potato (or whatever the user answered) back.
If you'd like to really flesh your game out, I'd suggest looking into template strings. Those let you do wonderful things like this:
import random
inp = input("Enter r to run and p to pass")
if(inp == "p"):
print(random.choice([f"Successfully passed the ball {random.randint(3,15)} yards","You tripped, the ball wasn't passed."]))
elif(inp == "r"):
print("Ran successfully.")

Handling input data quality with checks & default value

I am trying to write a code for squaring the user input number in Python. I've created function my1() ...
What I want to do is to make Python to take user input of a number and square it but if user added no value it gives a print statement and by default give the square of a default number for e.g 2
Here is what I've tried so far
def my1(a=4):
if my1() is None:
print('You have not entered anything')
else:
b=a**2
print (b)
my1(input("Enter a Number"))
This is a better solution:
def my1(a=4):
if not a:
return 'You have not entered anything'
else:
try:
return int(a)**2
except ValueError:
return 'Invalid input provided'
my1(input("Enter a Number"))
Explanation
Have your function return values, instead of simply printing. This is good practice.
Use if not a to test if your string is empty. This is a Pythonic idiom.
Convert your input string to numeric data, e.g. via int.
Catch ValueError and return an appropriate message in case the user input is invalid.
You're getting an infinite loop by calling my1() within my1(). I would make the following edits:
def my1(a):
if a is '':
print('You have not entered anything')
else:
b=int(a)**2
print (b)
my1(input("Enter a Number"))
When I read your code, I can see that you are very confused about what you are writing. Try to organize your mind around the tasks you'll need to perform. Here, you want to :
Receive your user inputs.
Compute the data.
Print accordingly.
First, take your input.
user_choice = input("Enter a number :")
Then, compute the data you received.
my1(user_choice)
You want your function, as of now, to print an error message if your type data is not good, else print the squared number.
def my1(user_choice): # Always give meaning to the name of your variables.
if not user_choice:
print 'Error'
else:
print user_choice ** 2
Here, you are basically saying "If my user_choice doesn't exists...". Meaning it equals False (it is a bit more complicated than this, but in short, you need to remember this). An empty string doesn't contain anything for instance. The other choice, else, is if you handled your error case, then your input must be right, so you compute your data accordingly.
In your second line, it should be
if a is None:
I think what you want to do is something like the following:
def m1(user_input=None):
if user_input is None or isinstance(user_input, int):
print("Input error!")
return 4
else:
return int(user_input)**2
print(my1(input("Input a number")))

python define a variable in an if statement

I want to make a coin toss / dice roll in python but i cannot figure out how to define / change a variable inside an if statement.
import random
def roll(number):
if(number==1):
{print("Take a moment to think that through")}
if(number==2):
{b=random.randint(0,1)
if(b=0):
{ba=1}
else:
{bb=1}
}
the part, {b=random.randint(0,1)} the = is highlighted red and marked as a syntax error. I also tried this:
import random
b=0
def roll(number):
if(number==1):
{print("Take a moment to think that through")}
if(number==2):
{b+=random.randint(0,1)
if(b=0):
{ba=1}
else:
{bb=1}
}
that gives the same error, and the = is highlighted, not the +
and before you ask, the function roll(number) is called in the shell. the shell is my interface.
import random
def roll(number):
if number==1:
print("Take a moment to think that through")
if number==2:
b=random.randint(0,1)
if b==0:
ba=1
else:
bb=1
Python doesn't use curly braces, you should write your codes like this.Also you have to return something in your function.This is how you can use your function/variables with another methods.
import random
def roll(number):
if number==1:
my_string="Take a moment to think that through"
return my_string
if number==2:
b=random.randint(0,1)
if b==0:
ba=1
else:
bb=1
return ba,bb
Something like this, I don't know your whole code so.
You should also think about what should happen if someone enters, for example, roll(15).
import random
def roll(number):
if number==1:
print("Take a moment to think that through")
elif number==2:
b=random.randint(0,1)
if b==0:
ba=1
else:
bb=1
else:
print("What should happen in this case?")
Also, #grrr: if b==0

Creating a number of functions that need to be able to call each other in Python

So first let me say that I am a novice at Python and functions seem to be out of my comprehension for the moment but where I am having trouble is having 3 functions be able to call each other. Here is my code(yes I know it is terribly wrong but you should see where I am going):
def menu():
count=gearboxes
cost=subtotal
return subtotal
def quantity():
gearboxes=raw_input("How many gearboxes would you like to order? ")
return menu()
def subtotal(cost):
if (gearboxes<=10):
cost=gearboxes*100.0
print cost
elif (gearboxes>10 and gearboxes<20):
cost=(gearboxes-10)*80.0+1000.0
print cost
elif (gearboxes>20):
cost=(gearboxes-20)*70.0+1000.0+800.0
print cost
else:
print "wtf m8"
return menu()
def summary():
print "="*80
print "%60s %20f %20f" % ("motors",count,cost)
print "="*80
print quantity()
print subtotal(menu)
print summary(menu)
There is it and any help would be greatly appreciated if you could explain also kind of how functions call on each other.
Thanks!
fixed version(still working)
def quantity():
motors=raw_input("How many motors would you like to order? ")
gearboxes=raw_input("How many gearboxes would you like to order? ")
sensors=raw_input("How many sensor boards would you like to order? ")
return int(motors),int(gearboxes),int(sensors)
def subtotal(motors,gearboxes,sensors):
if motors<=10 and gearboxes<=15:
motorCost=motors*100
gearboxCost=gearboxes*50
sensorCost=sensors*66
return motorCost, gearboxCost, sensorCost
if motors>10 and motors<=20 and gearboxes>15 and gearboxes<=30:
motorCost=(motors-10)*80+1000
gearboxCost=(gearboxes-15)*40+750
sensorCost=sensors*66
return motorCost, gearboxCost, sensorCost
elif motors>20 and gearboxes>30:
motorCost=(motors-20)*70+1000+800
gearboxCost=(gearboxes-30)*30+750+600
sensorCost=sensors*66
return motorCost, gearboxCost, sensorCost
def summary(motors,gearboxes,sensors,motorCost,gearboxCost,sensorCost):
print "="*80
print "%60s %20d %20d" % ("motors",motors,motorCost)
print "%60s %20d %20d" % ("gearboxes",gearboxes,gearboxCost)
print "%60s %20d %20d" % ("sensor boards",sensors,sensorCost)
print "="*80
def menu():
a,b,c=quantity()
d,e,f=subtotal(a,b,c)
summary(a,b,c,d,e,f)
return
menu()
I made some changes to your code. Treat a function like a question. When you call the function; you're asking the question. What you pass to return is the answer to the question. So when someone asks for the subtotal of some number of gearboxes; we return cost, whatever that may be.
We can then store the return values (the answers) in variables and use them later. For example, to pass to another function. Try to follow how information flows through the program.
def quantity():
count=raw_input("How many gearboxes would you like to order? ")
return int(count)
def subtotal(count):
if count<=10:
cost=count*100.0
return cost
elif count>10 and count<20:
cost=(count-10)*80.0+1000.0
return cost
elif count>20:
cost=(count-20)*70.0+1000.0+800.0
return cost
def summary(count, cost):
print "="*80
print "%60s %20f %20f" % ("motors",count,cost)
print "="*80
def menu():
items = quantity()
sub = subtotal(items)
summary(items, sub)
if __name__ == '__main__':
menu()
"subtotal" already calls menu() so I'm not sure what you are asking since you are already calling one function within the other.
Also, I can't see what your program is supposed to do - if your function names would be verbs (print_menu, get_menu, set_menu, throw_menu_on_moon, calculate_subtotal, ...) it would be better to understand for humans.
Also, the names you use (on the right hand side of =) within a function must be known there, so for example
def menu():
count=gearboxes
makes no sense (because "gearboxes" is unknown - on the other hand, "count" is fine since it defines new variable - since it is on the left hand side of =)...
Note that variables are only known within the function you defined them in, so
def f():
gearboxes = 2
def menu():
count=gearboxes
would make no sense either.
But
def f():
return 2
def menu():
gearboxes=f()
count=gearboxes
would make perfect sense.
Read the
def calculate_subtotal(gearbox_count):
as "to calculate subtotal of gearbox count do".
If you then say anywhere outside:
calculate_subtotal(5)
^^^^^^^^^^^^^^^^^^^^^
then the underlined part will be replaced by the result returned.
Otherwise, in Python the lines (in a block) are executed one after another - if you want to do multiple things in sequence, you can just write them one line each, one after another.
"return" is not "goto", "return" gives back the result - and control - to the caller of the function. Then the result is placed into the program "instead of the call".

Categories

Resources