Function call unresolved reference - python

for my coding course we had to make a lottery odds calculator, which has to include 2 functions and a main function. However, when I am trying to call one funtion to the main one I get the unresolved reference error. I don't know why it is doing it, this is the first exercise where I have 2 functions and a main. It might be that I have 2 bad/useless functions, since the instructions said to choose whatever functions seem logical.
from math import factorial
def fraction(prob):
frac=1/prob
return frac
def winProb(total, drawn):
facTot=factorial(total)
facDraw=factorial(drawn)
facBoth=factorial(total-drawn)
prob = float(facTot/(facBoth*facDraw))
return prob
def main():
total=int(input("Enter the total number of lottery balls: "))
drawn=int(input("Enter the number of the drawn balls: "))
if total < 0:
print("The number of balls must be a positive number.")
elif drawn <0:
print("The number of balls must be a positive number.")
elif drawn > total:
print("At most the total number of balls can be drawn.")
else:
print("The probability of guessing all", drawn, "balls correctly is 1/", fraction(prob))
if __name__ == "__main__":
main()
Unresolved reference comes when I try to call fraction(prob) in the last line

The full error probably tells you that prob is undefined. While you may have defined it within winProb it is out of the scope of main so it doesn't exist there yet. You need to define prob right after total and drawn within main:
prob = winProb(total, drawn)
Alternatively, replace fraction(prob) with fraction(winProb(total, drawn))

Related

How to use if condition inside a loop?

I want to solve a problem given by our teacher. The problem is: make a Python program that verifies if a number is a perfect square. If it's a perfect square it, shows a message and if not it shows another message.
This is my attempt:
n = int(input('choose a number'))
for i in range(1,n):
if n//i==i:
d=i
print(n,'is a perfect square and its root is,',d)
During my attempt, I couldn't add the else condition where the number is not a perfect square.
Using your range method and without importing math, you could have done this:
n = int(input('choose a number: '))
for i in range(1,n+1):
if i**2 == n: ## square the i and see if it equals n
print(n,'is a perfect square and its root is:',i)
break ## stop here
else:
if i == n: ## when all the i's have been tried, give up
print(n,'is not a perfect square')
you gave this a good go. Has your teacher taught you about importing modules yet? Basically, a module is like a Python file, and you can take functions from that file and use them in your file. One module is 'math' and holds a function called 'sqrt' that calculates the square root of a given number. If this square root is a whole number (has no remainder) the given number is square -- is not, it's not square. See the program I wrote below:
import math
num = int(input("Number = "))
square_root = math.sqrt(num)
if square_root % 1 == 0:
print(f"It's square. {int(square_root)} squared gives {num}")
else:
print("It's not square")

Why are these functions not defined, and does this work? How do I debug this?

I need help with this problem:
Implement the roll_dice function in hog.py. It takes two arguments: a positive integer called num_rolls giving the number of dice to roll and a dice function. It returns the number of points scored by rolling the dice that number of times in a turn: either the sum of the outcomes or 1 (Sow Sad).
The Sow Sad rule:
Sow Sad. If any of the dice outcomes is a 1, the current player's score for the turn is 1.
To obtain a single outcome of a dice roll, call dice(). You should call dice() exactly num_rolls times in the body of roll_dice. Remember to call dice() exactly num_rolls times even if Sow Sad happens in the middle of rolling. In this way, you correctly simulate rolling all the dice together.
from random import randint
def roll_dice():
final_sum = 0
numrolls = 0
while numrolls > 0 and numrolls <=10:
final_sum= numrolls.dice()
numrolls+=1
return numrolls
if numrolls.dice==1:
numrolls=1
print("SOW SAD, score for this turn is 1")
final_sum+=numrolls
return final_sum
print(final_sum)
def dice():
value = 0
while value > 0:
return randint(1,6)
return dice
Implement the roll_dice function in hog.py. It takes two arguments: a positive integer called num_rolls giving the number of dice to roll and a dice function
As instructed, your function needs arguments
It returns the number of points scored by rolling the dice that number of times in a turn
Assuming you're using a newer version of Python3, type hints can be added to functions
either the sum of the outcomes or 1 ... call dice() exactly num_rolls times in the body of roll_dice. Remember to call dice() exactly num_rolls times even if Sow Sad happens in the middle of rolling.
list-comprehension can be used to run the function to roll multiple dice, and you can then check for ones or sum the lists
import random
def dice() -> int:
return random.randint(1, 6) # assumed to be 6 sided die
def roll_dice(num_rolls, dice_fn) -> int:
# roll a number of times, and store the results
rolls = [dice_fn() for _ in range(num_rolls)]
# if there's a 1, that's the score, else add all roll values
return 1 if any(r == 1 for r in rolls) else sum(rolls)
if __name__ == "__main__":
num_rolls = input("rolls: ")
# pass in the dice function, don't call it
print(roll_dice(int(num_rolls), dice))
Compared to your attempt ...
functions ideally shouldn't be nested unless you have a good reason for it. That's more of an advanced topic
return statements are used to return values to other places, and nothing after them will run within that same function
Types matter. A function name should not be referenced by a number, or vice versa. This is a hard problem in Python to deal with
Dot-notation is reserved for classes and modules. There are no classes defined. The only module you have here is the imported random

How do I keep track of the number of inputs by a user, and display them in a string?

I have a class project, where I am making a number guessing game. I have the following requirements:
#1. A main() function that holds the primary algorithm, but itself only passes information among other functions. main() must have the caller for random_int()
#2. A function called in main() (not nested in main()!) that compares the user's guess to the number from random_int() and lets the user know if it was too high or too low.
#3. A function called in main() that asks the user for a new guess.
#4. A function that prints out a string letting the user know that they won.
#5. Tell the user how many guesses it took them to get the correct answer.
I am struggling to determine how to keep track of the number of times a user guesses before they reach the correct number, and display that number in a string. I currently have a while loop in the function main():
def main(random_int, new_guess, user_attempts): #Function that holds the main algorithim and calls all of the functions in the program
r = random_int(size) #Setting parameters to generate a random number between 1 - 1000
n = new_guess() #Assigns the user's input as "guess", and calls the function "new_guess"
while n != r: #While loop to continue until user guesses correct number
if n > r:
print("The number you guessed is too high, guess again.")
elif n < r:
print("The number you guessed is too low, guess again.")
attempts =+ 1
n = new_guess()
if n == r: #If user guesses correct number, call "win" function
win(random_int, new_guess, user_attempts)
And am attempting to take the value of attempts, and store it in the function user_attempts(): where I can call it in the function win():. I keep getting the error - TypeError: 'int' object is not callable
The full program for context:
#Python number guessing game
#Import randrange module
from random import randrange
#Initialize variables
attempts = 0
size = 1000
def random_int(size): #Generates a random integer from given parameters (size)
return randrange(1, size+1)
def new_guess(): #Prompts the user to enter an integer as their guess
guess = int(input("Enter your guess (between 1 - 1000): "))
return guess
def user_attempts():
a = attempts
return a
def win(random_int, new_guess, user_attempts): #Prints that the answer is correct, along with the number of guesses it took
random_int = random_int(size)
a = user_attempts()
if a >= 2: #If it took the user more than 1 attempt, uses "guesses" for proper grammar
print("You guessed the correct number", str(random_int()), ", you win! It took you ", str(user_attempts()), " guesses.")
elif a < 2: #If it took the user only 1 attempt, uses "guess" for proper grammar
print("You guessed the correct number", str(random_int()), ", you win! It took you ", str(user_attempts()), " guess.")
def main(random_int, new_guess, user_attempts): #Function that holds the main algorithim and calls all of the functions in the program
r = random_int(size) #Setting parameters to generate a random number between 1 - 1000
n = new_guess() #Assigns the user's input as "guess", and calls the function "new_guess"
while n != r: #While loop to continue until user guesses correct number
if n > r:
print("The number you guessed is too high, guess again.")
elif n < r:
print("The number you guessed is too low, guess again.")
attempts =+ 1
n = new_guess()
if n == r: #If user guesses correct number, call "win" function
win(random_int, new_guess, user_attempts)
main(random_int, new_guess, user_attempts) #Calls the "main" function, runs the program
For your "int object is not callable" error, that means you are calling an integer variable like it is a function. I think it's where you do:
random_int = random_int(size)
The first call to random_int may work if it's a function, but then you're assigning a local variable called random_int the return value of that function, which is an integer. So the next time you call random_int, it's an integer instead of a function. To fix it, you should use a different variable name besides random_int, since that is what you called your function.
+= vs =+
It looks like you have:
attempts =+ 1
But you probably mean to swap the + and =:
attempts += 1
attempts =+ 1 is like attempts = +1, where + is unary positive (like unary negative).

Python Monty hall n number of doors

I have a model of the Monty Hall program running but I need to figure out how to ask the user for the number of doors of in this case, hiding places. The code for the simulation works, it's just the starting section I need help with. This is what I have so far, thanks for any help in advance.
import random
#Ask the user for how many runs to simumlate
runs = int(input("How many games do you want to simulate?"))
switchwins, nonswitchwins, switchlosses, nonswitchlosses = 0, 0, 0, 0
# Get the random number started with a seed
random.seed()
#run once for user switching and once for user not switching
for swap in True,False:
# Do everything for the number of runs we have
for i in range(runs):
#Ask the user for the number of hiding places which must be greater than 3
while True:
hidingplaces = int(input("This game requires 3 or more hiding places. How many would you like?"))
if hidingplaces < 3:
#return error
raise ValueError(f'doors must be greater than three, not {hidingplaces}')
else:
break
# All prizes are nothing apart from one which holds the coin
prizes = ['nothing', 'nothing', 'coin']
# Randomly mix them up
random.shuffle(prizes)
#select a random location
ChoiceA = random.randrange(hidingplaces)
# print("Before the prize is revealed, I will show you what is in one of the other hiding places")
# remove one of the other hiding places which has nothing as a prize and isn't ChoiceA
for currentlocation, contents in enumerate(prizes):
if currentlocation != ChoiceA and contents == "nothing":
showlocation = currentlocation
# print("There is nothing in this location", showlocation)
break
if swap:
#swap to the other location
for currentlocation, contents in enumerate(prizes):
if currentlocation != ChoiceA and currentlocation != showlocation:
swap_to = currentlocation
# check if the swapped choice is a win
if prizes[swap_to] == "coin":
switchwins +=1
else:
switchlosses +=1
# when not swapping locations check for win
else:
if prizes[ChoiceA] == "coin":
nonswitchwins +=1
else:
nonswitchlosses +=1
print("This is the number of wins if the user switched", round((switchwins/runs)*100,1), "%")
print("This is the number of wins if the user didn't switch", round((nonswitchwins/runs)*100,1),"%")
The error I'm getting is:
IndexError Traceback (most recent call last)
<ipython-input-15-e7e700a3b515> in <module>()
57 # when not swapping locations check for win
58 else:
---> 59 if prizes[ChoiceA] == "coin":
60 nonswitchwins +=1
61 else:
IndexError: list index out of range
The problem you're reporting is not, after all, with the user input routine. It is that you are allowing the user to specify hidingplaces > 3 while at the same time hardcoding the list prizes to have exactly 3 entries. ChoiceA, which can be (randomly) set to any number less than hidingplaces, is used as an index into prizes. It raises the exception you report whenever ChoiceA happens to be greater than 2.
Strategies to fix this might include (a) making use of the value of hidingplaces when you define the list of prizes or (b) using ChoiceA % len(prizes) as the index into prizes instead of just ChoiceA. Note that these have different effects on the statistical behavior of the simulation: the correct choice depends on how you want it to behave. From the comment next to your existing definition of prizes, this definition is probably what you intend:
prizes = [ 'coin' ] + [ 'nothing' ] * ( hidingplaces - 1 )
I have fixed your code. I rewrote it and simplified it, fixed some syntax errors, and fixed some indent errors.
Check the comments in the code.
EDIT: I have fixed the code.
def askDoors():
'''
Ask the user for the number of hiding places which must be greater than 3
'''
return int(input("This game requires 3 or more hiding places. How many would you like?"))
hidingplaces = askDoors()
while hidingplaces < 3:
# return error
print('Doors must be greater than three, not %d.' % hidingplaces)
hidingplaces = askDoors()
print('Start.') # put game here (recommended to use a function)
EDIT: For the second problem, just change prizes to prizes = ['coin'] and add this right after it.
for i in range(hidingplaces):
prizes.append('nothing')

UnboundLocalError, and TypeError

I am a beginner. My error is UnboundLocalError: local variable 'n' referenced before assignment. I have looked for answers but I dont understand most of the code.
def numberOfSquares(n):#This is where I get the user input.
n= int(input("Please input a number higher than 1 to be the number of squares drawn."))
while n < 0:
print("Please try another number.")
n= int(input("Please input a number higher than 1 to be the number of squares drawn."))
print("Thanks for your contribution!")
def main():# I call the other function in this one, and draw n number of squares. I have not even put #the different colors on it yet.
numberOfSquares(n)
import turtle
for i in range(n):
turtle.circle(40,steps= 4)
turtle.left(45)
turtle.forward(50)
n-=1
turtle.write("Colors of the Rain")
main()
It seems that you are misusing method variables. You are passing n to numberOfSquares while you really want to get a return value instead.
def number_of_squares():
# Your code here, and finally
return n
Then in your main():
n = number_of_squares()
As to the second error, you have a typo. The method turtle.cicrle receives steps argument not step.
turtle.circle(40, steps=4)
And finally, there is a strong naming convention in python. All methods should be lower-case with underscores like number_of_squares, not camel-case (numberOfSquares).

Categories