0

In a nutshell:

At the end of my program, there is a need to compare two integers whose results are inside the function itself. When I execute, I get undefined variable error.

Actually:

I am creating a hand cricket python script which we usually play as a duo. At last both the scores of the opponents are compared and the greatest wins. The operation with the variables are inside of a function, but when called outside the function, undefined variable error shows up. Help please?

import random  
while True:
    pc_b_or_b = 0  #PC probability

    #User Bowling module
    def Bowl():
        bat_PC = 0
        User_bowl = 0
        scoreofpc = 0
        ScorePC = 0
        while True:
            bat_PC = random.randrange(1,11)                 #Random int gen
            User_bowl = int(input("Your turn to bowl: "))   #int from user
            if User_bowl<1 or User_bowl>10:                 #Fool proofing user must not keep less than 1 or gr8 than 10
                print("Wrong number")
                continue
            if User_bowl == bat_PC:                         # Check if user == pc and out
                print() 
                print("PC Out!")
                print("PC Score:",scoreofpc)
                break
            else:                                           #Continuation
                print("Escape for PC. PC kept",bat_PC)
                scoreofpc += bat_PC
                print("Score:",scoreofpc)
        ScorePC = scoreofpc

    #User batting module
    def User_Batting():
        a = 0
        score = 0
        ManScore = 0
        while True:
            b = random.randrange(1,11)                  #Same as above but User is batting and pc randome int gen
            a = int(input("Your turn to bat: "))        #But here if user int == pc then out for user
            if a<1 or a>10:
                print("Wrong number")
                continue
            if a==b:
                print()
                print("Out")
                print("Score:",score)
                break
            else:
                print("Escape! PC =",b)
                score +=a
                print("Score:",score)
        ManScore = score

Actually Some more code comes here I've reduced to just these as said by StackOverflow

Main problem here, variable not defined, all other modules working perfectly

    ScorePC1 = ScorePC
    ManScore2 = ManScore

    if ScorePC1 > ManScore2:
        print("PC won the match by scoring",Score_of_PC)
    elif ScorePC1 < ManScore2:
        print("You won the match by scoring",User_Score)
    else:
        print("Your Score and PC score matched!")

    quitter = input("Do you wanna Quit? Y/N? ")
    if quitter == "yes" or quitter == "y" or quitter == "Y":
        print("Thank You for playing!")
        print("Script created by ***Techno-Sachin***")
        quit()
    elif quitter == "n" or quitter == "no" or quitter == "N":
        print("Playing again..")
        continue
    else:
        print("It's a wrong input. Try again")   

Expectaion:

At last it is expected to print the statements inside if ScorePC1 and ManScore2 comparisons.

Error:

The output is Big, but cut out to focus on the problem itself>

PC Out! PC Score: 38 Traceback (most recent call last): File "C:\Users\E.sachin\Documents\HTML5\Python Scripts\Hand_cricket20.py", line 164, in ScorePC1 = ScorePC NameError: name 'ScorePC' is not defined

morgan121
  • 2,213
  • 1
  • 15
  • 33
  • 1
    This is an issue with scope. To fix this you can either make your variables `global` or, have your functions `return` the result. I would recommend the latter. Example `def my_func(): #do some logic return my_var` then `ScorePC=my_func()` – TheLazyScripter Sep 07 '19 at 04:56
  • its a local variable in Bowl, you didn't return it or assign it to a global variable...do what Techno-Sachin said ^^^ – Derek Eden Sep 07 '19 at 05:28

7 Answers7

0

Try replacing this - ScorePC1 = ScorePC with global ScorePC1 then use it as normal by referencing it's name ScorePC anywhere.

using global keyword before a varible name makes the variables's scope global and therefore enables the access to it from outside or inside a function.

also put the same inside the function definition like

def Bowl():
   global ScorePC1

use it for both of your variables ScorePC1 and ManScore

Himanshu
  • 666
  • 1
  • 8
  • 18
  • perhaps add an alternative where`Bowl()` `return` `ScorePC1` and vice versa! – TheLazyScripter Sep 07 '19 at 04:58
  • Using a global variable is not advisable in most cases. – Irfanuddin Sep 07 '19 at 05:03
  • sure but `ScorePC1` variable maintains a state of scoring, it might need updates from various functions so without global it will need referencing from function calls a lot of times. so it is suggested to be used carefully otherwise use function call referencing. – Himanshu Sep 07 '19 at 05:12
0

You should always return values from your function. In this case you could return scoreofpc and score from the two functions. Your code would look like this:

def bowl():
    #your code
    return scoreofpc

def user_batting():
    #your code
    return score

Score1 = bowl()
Manscore = user_batting()

Alternatively, you could use Global Variables. But they are not advisable, infact, they're evil.

Irfanuddin
  • 2,295
  • 1
  • 15
  • 29
0

If the reduced code is inside the main function,then the problem is that ScorePcvariable is not defined because it is a local variable inside the Bowl() function because you initialized it there.You cant access its name in the main() function. To fix this you can either return it from Bowl() to the ScorePc or set it to be global as Himanshu said.

def Bowl():
    #code..
    return ScorePc
def main():
    ScorePc=Bowl()#this will store the returned value to ScorePc

or

def Bowl():
    global ScorePc

You should probably read more about this to understand better how it works. Here are some links: geeksforgeeks python documentation

The Niv
  • 135
  • 1
  • 7
0

The variable ScorePC is declared inside the function Bowl() , by doing so the scope of the variable is within the Bowl() meaning it cannot be accessed from outside of the function. If you want to access it outside of the function declare it outside, which is not a good design. The better design is to return the value from the function like @irfanuddin answer.

Sab
  • 485
  • 5
  • 17
0

This can be done by using global keyword in the function. See below for your reference


def Bowl():
    global ScorePc
    ....

def User_Batting():
    global ManScore
    ....

But, I would suggest returning the value from the function. if your function is carrying multiple values, then do return as an array.

Kumar KS
  • 873
  • 10
  • 21
0

You have defined ScorePC and ManScore inside functions which turns out they are only usable inside that function unless you do one of the two things.

  1. You can make the variable a function attribute. Example:

    def Bowl():
        Bowl.ScorePC = 0
    def User_Batting():
        User_Batting.ManScore = 0
    
  2. You can make the variable global. Example:

    def Bowl():
        global ScorePC
        ScorePC = 0
    def User_Batting():
        global ManScore
        ManScore = 0
    

If you want to use them in other files. You have to import the file there where you want to use. Here you will find some good examples:

Using global variables between files?

MehediMehi
  • 1
  • 1
  • 4
0

I did some modifications also.
import random def Bowl(): global ScorePC bat_PC = 0 User_bowl = 0 scoreofpc = 0 ScorePC = 0 while True: bat_PC = random.randrange(1,11) #Random int gen User_bowl = int(input("Your turn to bowl: ")) #int from user if User_bowl<1 or User_bowl>10: #Fool proofing user must not keep less than 1 or gr8 than 10 print("Wrong number") continue if User_bowl == bat_PC: # Check if user == pc and out print() print("PC Out!") print("PC Score:",scoreofpc) break else: #Continuation print("Escape for PC. PC kept",bat_PC) scoreofpc += bat_PC print("Score:",scoreofpc) ScorePC = scoreofpc

#User batting module
def User_Batting():
    a = 0
    score = 0
    ManScore = 0
    while True:
        b = random.randrange(1,11)                  #Same as above but User is batting 
and pc randome int gen
        a = int(input("Your turn to bat: "))        #But here if user int == pc then out 
for user
        if a<1 or a>10:
            print("Wrong number")
            continue
        if a==b:
            print()
            print("Out")
            print("Score:",score)
            break
        else:
            print("Escape! PC =",b)
            score +=a
            print("Score:",score)
        ManScore = score

        # Main probem here, variable not defined
        # All other modules wotking perfectly
        ScorePC1 = ScorePC
        ManScore2 = ManScore

    if ScorePC1 > ManScore2:
        print("PC won the match by scoring",ScorePC1)
    elif ScorePC1 < ManScore2:
        print("You won the match by scoring", ManScore2)
    else:
        print("Your Score and PC score matched!")

    quitter = input("Do you wanna Quit? Y/N? ")
    if quitter == "yes" or quitter == "y" or quitter == "Y":
        print("Thank You for playing!")
        print("Script created by ***Techno-Sachin***")
        exit()
    elif quitter == "n" or quitter == "no" or quitter == "N":
        print("Playing again..")
        play()
    else:
        print("It's a wrong input. Try again")

def play():
    Bowl()
    User_Batting()
play()