Wednesday, January 20, 2021

Python - Scope (Day 12)

This is a 100 Days challenge to learn a new language (Python). 100 Days of Code - The Complete Python Pro Bootcamp 

I will post some notes to motivate myself to finish this challenge.


Scope



Like an apple tree inside your house fence. Then only you and your family can access this apple tree. If there is an apple tree outside your fence and others. Then everyone can access it.


Local Scope



Ex:
# Custom Function
def log_count():
# Define a Local Scope Variable
    count = 1
    print(count)

# Call a custom function
log_count()
# Try to access a variable which is defined in a custom function
print(count)

Result:

NameError: name 'count' is not defined


The instruction print(count) which is outside of log_count() function will throw an error NameError: name 'count' is not defined because 'count' is in a local scope (Like people who is outside your fence and try to access your apply tree)


Global Scope



Ex:
# Define a Global Scope Variable
count = 1

  # Custom Function
def log_count():
    # Access a global variable
    print(count)


log_count()
# Access a global variable
print(count)

Result:

1
1


Since 'count' is in global scope, everyone can access it no matter he is inside or outside the log_count() function.


Namespace



The concept of Global and Local scope do not only apply to variables, but also basically it apply to everything your named. Everything you named have its namespace, and namespace will be valid in certain scope.

We can modify previous example as below.

Ex:
# Global Scope Variables
count = 1

# Custom Function
def demo():
# Define a Local Function
    def log_count():
# Access a global variable
        print(count)

# Try to access a local function
log_count()
print(count)

Result:

NameError: name 'log_count' is not defined


Then log_count() function will throw an error NameError: name 'log_count' is not defined since log_count is the local function inside demo() function.


Block Scope in Python?



Ex:
score = 70
if score >= 60:
# Define a Local Variable ???
    message = "You Pass"

# Try to access a local variable ???
print(message)

Result:
You Pass


Unlike other language, the example above is totally working in python. Block like 'if', 'while', or 'for' does not count as creating local scope.


Modify Global Variables?



Ex:
# Global Scope Variables
score = 70

# Custom Function
def reset_score():
     # Local Scope Variables
    score = 0
    print(score)

# Call a custom function to reset a global variable
reset_score()
print(score)

Result:
0
70


As we discussed before, the score = 0 will create another local variable inside reset_score function. If the output is done by design, then it is fine, but please don't use the same name like global variables. It will reduce the readability.


Modify Global Variables? - Method 1



However if the result is not what you want (we do want to modify the global variable from 70 to 0), you need to give it a global tag to make it work as expected.

Ex:
# Global Scope Variables
score = 70

# Custom Function
def reset_score():
# Tag score as a global variable
    global score
      # Modify global variable
    score = 0
    print(score)

# Call a custom function to reset a global variable
reset_score()
print(score)

Result:
0
0



Modify Global Variables? - Method 2 (Recommended)



Using function input and output to modify the global variables.

Ex:
# Global Scope Variables
score = 70

# Custom Function to get an input and return an output
def reset_score(score):
    score = 0
    print(score)
    return score

# Passing current global variable and override it by its output
score = reset_score(score)
print(score)


Result:
0
0



Constants V.S. Global Variables



Constants have it naming convention in case you modify it accidently.

Ex:
PI = 3.14159



Challenge - Number Guessing Game



Build a simple number guessing game
* Provide two level: easy and hard
* easy level: 10 attempts
* hard level: 5 attempts
* indicate whether it is too high or low

Flow:

Ex:
import random

EASY_LEVEL_LIVES = 10
HARD_LEVEL_LIVES = 5

# Setup game lives based on selected game level
def chooseGameLevel():
    """Return game lives"""

    mode = input("Choose a difficulty. Type 'easy' or 'hard': ")

    if mode == "easy":
        lives = EASY_LEVEL_LIVES
    else:
        lives = HARD_LEVEL_LIVES

    return lives

 # Game
def game():
    print("Welcome to Number Guessing Game!")
    print("The number is between 1 and 100")

    # Randomly generate a number between 1 and 100
    answer = random.randint(1, 100)

    # Setup game lives
    lives = chooseGameLevel()

    while lives > 0:
        print(f"You have { lives } attemps remainding to
guess the number.")

        guess = int(input("Make a guess: "))

        if guess == answer:
            print(f"You got it! The answer was {answer}")
            return

        if guess > answer:
            print("Too High")
            lives -= 1
        else:
          print("Too Low")
            lives -= 1

        if lives == 0:
            print(f"You have run out of guesses, you lose")
            return
        else:
            print("Guess again.")

game()


No comments:

Post a Comment