jeudi 19 mars 2020

Python3.7 - How deep a global variable is usable?

It may seem a silly question: How deep in the loops and conditionals a global variable is used?

I have the following piece of code (the full code is provided at the end):

blockchain = []
index_ul = 0
...

def print_blockchain_elements():
    for block in blockchain:
        print('Outputting block:')
        print(block)

        if block == blockchain[index_ul]:
            print("block matches!")
            index_ul += 1

while True:
    print("Please choose: ")
    print("Press 1 for: Add a new transaction value")
    print("Press 2 for: Outputting the blockchain blocks")
    user_choice = get_user_choice()

    if user_choice == "1":
        tx_amount = get_transaction_value()
        add_value(tx_amount, get_last_blockchain_item())
    else:
        print_blockchain_elements()

When I run the code and the if statement if '''block == blockchain[index_ul]:''' is hit, i got the following error message:

Traceback (most recent call last):
  File "/home/v/blc.py", line 67, in <module>
    print_blockchain_elements()
  File "/home/v/blc.py", line 48, in print_blockchain_elements
    if block == blockchain[index_ul]:
UnboundLocalError: local variable 'index_ul' referenced before assignment

Now, i work in Visual Studio Code. when writing index_ul at blockchain[index_ul], VSC provides me hints for autocomplete, as it sees the variable. Why I get this local variable error when the variable is defined globally?

The rest of the code (I know that I have an endless while loop):

#!/usr/bin/env python3.7


# Initializing our blockchain list
blockchain = []
# This index value is used in the if statement in order to test correct functioning of the "for" loop when parsing list items
index_ul = 0

# The following declared function returns the value of the last positional element of the blockchain list

def get_last_blockchain_item():
    """ It returns the last value of the current blockchain"""
    return blockchain[-1] #the -1 is the first negative positional index, meaning, the last item in a list


# This function accepts 2 arguments.
# One of the arguments is required when calling the function (transaction_amount);
# Another one is an optional argument when calling the function (last_transaction);
# The optional argument is optional because it is a default argument, meaning that has its value defined when the function is declared
def add_value(transaction_amount, last_transaction=[1]): 
    """ Append a new value as well as the last blockchain value to the blockchain

    Arguments:
        :transaction_amount: The amount that should be added.
        :last_transaction: The last blockchain transaction (default [1])
    """
    # This code calls a method (.append) on an existing global variable of type string
    # append() method adds a value at the end of the list
    # In this case the added value is a list, marked with []
    blockchain.append([last_transaction, transaction_amount])


# The purpose of the following function is to: 1. Get user input at console 2. return the user input value as a float
def get_transaction_value():
    """ It returns the input of the user (a new transaction amount) as a float"""
    user_input = float(input("Amount: ")) #input() function is used to get a user input at console
    return user_input

def get_user_choice():
    user_input = input("Your choice: ")
    return user_input

def print_blockchain_elements():
    # The following loop goes through the list items and print each item individually
    # Then, the internal if statement verifies that the block/item parsed by for loop is indeed the next item in the list (by using indexes)
    for block in blockchain:
        print('Outputting block:')
        print(block)

        if block == blockchain[index_ul]:
            print("block matches!")
            index_ul += 1

# Get the first transaction input and add the value to the blockchain
tx_amount = get_transaction_value() #here I define a variable "tx_amount" with the value = to the result of the "get_user_input() function"
add_value(tx_amount) # Here, i call the function , specifying a value only for the "transaction_amount" variable of the function,
                     # the second argument of the function gets its default value last_transaction=[1]


while True:
    print("Please choose: ")
    print("Press 1 for: Add a new transaction value")
    print("Press 2 for: Outputting the blockchain blocks")
    user_choice = get_user_choice()

    if user_choice == "1":
        tx_amount = get_transaction_value()
        add_value(tx_amount, get_last_blockchain_item())
    else:
        print_blockchain_elements()
print(blockchain)

'''

Aucun commentaire:

Enregistrer un commentaire