Python Forum
Global variables or local accessible
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Global variables or local accessible
#1
Hi to all, allow me a small intro : i am self taught in programing , first learn to program in "c" (arduino) and later playing with a raspberry pi board i start reading in internet articles etc about python programming.
i have written a python program to function a system with motor-belt movement and works fine as i wanted without any problem, so not need to change anything.

The problem is that because i was familiar with c coding it was easier for me to use global variables to my code that is something i read a lot that is not the right way to do with python

i wrote a simple python code that i am using some global variables, so if any one has the free time to alter the code to see how should be if was written using local variables .
i have seen some online examples how to use local variables but havent understand how could be applied to my code so that is why i wrote the code above to understand it as an example. (i have some variables that are used in a lot of different Functions and can be changed also inside these functions )

Description of the code : At 1st boot moves the belt to the left , after that waits to import/type the position want to move

Here is the example Code :

# Virtual mode of a motor moving a belt in 3 positions, 1 Start/left, 2 Middle, 3 End/Right
# Normal code is based to work with the physical world with the help of Raspberry GPIO pins for switches inputs ( switches for 3 positions left middle and right )
# This one is simplified to bare minimal (no import for gpios etc ) to work in any system with Python installed


import time

Position = ""
call = ""

def stop():
    print("Motor stopped")
    if call == "1" :
        print("Belt at Left Position")
    if call == "2" :
        print("Belt at Middle Position")
    if call == "3" :
        print("Belt at Right Position")
    time.sleep(2.0)
    main()


def Left():
    global Position
    command = input("Type stop to stop the motor : ")
    while command != "stop" :
        try :
            print("keep moving to : " + call)
            command = input("Type stop to stop the motor : ")
        except :
            pass
    if  command == "stop" :
        print("Slow down motor")
        Position = "Left"
        stop()

def Middle():
    global Position
    command = input("Type stop to stop the motor : ")
    while command != "stop":
        try:
            print("keep moving to : " + call)
            command = input("Type stop to stop the motor : ")
        except:
            pass
    if command == "stop":
        print("Slow down motor")
        Position = "Middle"
        stop()


def Right():
    global Position
    command = input("Type stop to stop the motor : ")
    while command != "stop":
        try:
            print("keep moving to : " + call)
            command = input("Type stop to stop the motor : ")
        except:
            pass
    if command == "stop":
        print("Slow down motor")
        Position = "Right"
        stop()


def main():
    global call
    print("###########################################################")
    print(" ")
    print("type :  '1' = Move Left , '2' = Move middle , '3' = Move Right , 'Q' = Quit ")
    while True:
        call = input("Please type something : ")
        if call == "1" and Position != "Left":
            print("call is: " + call)
            Left()
        elif call == "1" and Position == "Left" :
            print("You are All ready on " + Position)

        if call == "2" and Position != "Middle":
            print("call is: " + call)
            Middle()
        elif call == "2" and Position == "Middle":
            print("You are All ready on " + Position)

        if call == "3" and Position != "Right":
            print("call is: " + call)
            Right()
        elif call == "3" and Position == "Right":
            print("You are All ready on " + Position)

        if call == "Q" :
            Quit()
        if call != "1" or call != "2" or call != "3" or call != "Q" :
            print("Wrong Type Command, Please try again")

def first_boot():
    global Position
    print(">>>>>>>>>>>>>>>>--<<<<<<<<<<<<<<<<<<<<")
    print(">>>>>>>>>>>>>>>>--<<<<<<<<<<<<<<<<<<<<")
    print(" ")
    print("Booting for 1st time")
    print("moving motor - belt to the left position - calibrate")
    time.sleep(3.5)
    print("OK !!  LEFT position.......  Starting main function")
    Position = "Left"
    time.sleep(2)

def Quit():
    print("Thanks for using me,  Have a nice Day !!")
    quit()

first_boot()
main()
Thanks in Advance

Ps: English is not my native language
Reply
#2
Hello,

indeed true, using global variables and the global keyword is considered bad style and should be prevented. Except that using global variables is in 99% of all cases unnecessary, including your case.

Fixing your programm is fairly simple: just pass the position as an argument to the function and make the function return the new position, so it is available in your main function. Passing and returning values to / from functions is one of the basics in Python. In case you don't know I suggest to read the corresponding cheapers in the Python tutorial at docs.python.org .
Generally speaking, using global variables is considered bad style, as it makes the state of a program hard to somewhat impossible to trace.

Couple of other comments:

call doesn't need to be global anyway, as it is used only within main.

Line 20 is unnecessary and can lead to an recursion error. When a function is finished, it return to the point in the code from where it was called. In you case main calls e.g. left, left may call stop. When stop is finished it returns to left which return to main.

Never use blank try... except, that's wrong in 99,9% of all cases. Errors need to be caught specifically. Using blank try... exceptwill catch any error, including programming and syntax error. This can lead to an unexpected behaviour and hard to trace bugs.

Line 111 will lead to an error, as quiet is not defined.

Regards, noisefloor
Reply
#3
Fixing your program is not all that simple. Your program has a design flaw that will eventually result in a recursion limit exceeded exception. This would take a while, so let's speed things up a bit.
import random

def stop():
    main()
 
def Left():
    stop()

def Middle():
    stop()

def Right():
    stop()

def main():
    random.choice((Left, Middle, Right))()

main()
Error:
File "...", line 7, in stop main() File "...", line 19, in main random.choice((stop, Left, Middle, Right))() blah, blah, blah calling some function that calls main that calls another function that calls stop() that calls main ... until eventually File "C:\Program Files\Python311\Lib\random.py", line 239, in _randbelow_with_getrandbits k = n.bit_length() # don't use (n-1) here because n can be 1 ^^^^^^^^^^^^^^ RecursionError: maximum recursion depth exceeded while calling a Python object
You should use a loop in main() instead of using recursion. main() should call Left(). Left() should do it's thing and call stop. stop() should do it's thing and end, letting control return to Left(). Left() should execute any remaining code (currently none) and end, letting control return to main().

This does the same thing as above, but it runs forever without consuming more and more resources.
import random

def stop():
    pass
 
def Left():
    stop()

def Middle():
    stop()

def Right():
    stop()

def main():
    while True:
        random.choice((Left, Middle, Right))()

main()
Reply
#4
You write programs like a C programmer, except for that infinite recursion thing. You are going to find Python very frustrating for a little while, but after a few months you will never want to use C again.

This is how I would write your program.
"""
Virtual mode of a motor moving a belt in 3 positions, 1 Start/left, 2 Middle, 3 End/Right
Normal code is based to work with the physical world with the help of Raspberry GPIO pins for switches inputs ( switches for 3 positions left middle and right )
This one is simplified to bare minimal (no import for gpios etc ) to work in any system with Python installed
"""

import time


class State:
    """Really simple state machine for simulation"""
    moves = {"1": "Left", "2": "Middle", "3": "Right"}

    def __init__(self):
        self.position = "Undefined"
        self.call = ""

    def start_move(self, call):
        """Begin moving to a new position"""
        self.call = call

    def moving_to(self):
        """Where am I moving"""
        return self.moves.get(self.call, "Undefined")

    def move_completed(self):
        """Where am I at"""
        self.position = self.moves.get(self.call, "Undefined")


def stop():
    STATE.move_completed()
    print("Motor stopped")
    print(f"Belt at {STATE.position} Position")
    time.sleep(2.0)


def move_to_position(call):
    STATE.start_move(call)
    while True:
        command = input("Type stop to stop the motor : ")
        if command == "stop":
            break
        print("keep moving to :", STATE.moving_to())
    stop()


def first_boot():
    print(">>>>>>>>>>>>>>>>--<<<<<<<<<<<<<<<<<<<<")
    print(">>>>>>>>>>>>>>>>--<<<<<<<<<<<<<<<<<<<<\n")
    print("Booting for 1st time")
    print("moving motor - belt to the left position - calibrate")
    STATE.start_move("1")
    time.sleep(3.5)
    print("OK !!  LEFT position.......  Starting main function")
    STATE.move_completed()
    time.sleep(2)


def main():
    choices = ", ".join([f"'{key}' = {value}" for key, value in STATE.moves.items()])
    prompt = f"Enter move ({choices}, Q = Quit): "

    first_boot()
    while True:
        print("###########################################################\n")
        call = input(prompt)
        if call == "Q":
            print("Thanks for using me,  Have a nice Day !!")
            break
        elif call not in State.moves:
            print("Wrong Type Command, Please try again")
        elif STATE.call == call:
            print("You are All ready on", STATE.position)
        else:
            move_to_position(call)


STATE = State()
main()
Global variables should be avoided because they eventually will lead to confusion. For a short program like this I don't mind having 1 global variable. Use PEP8 naming conventions. A global variable should be all uppper case
Reply
#5
Quote:noisefloor
Thanks for your tips Heart

Quote:deanhystad
Thank you... the truth is that i havent run for more than one day my true program to come up to that problem so thank you noticing to have it in my mind Heart

Quote:deanhystad
Thank you.. Heart i think you understand my bigger issue with python.. that i using it with the logic of C programing .
Thanks for the time you spend to change my code to a better python logical one ... now i can make a comparison between them to understand better how must swift my logic to adjust better with python programing


Thank you all for the help
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  It's saying my global variable is a local variable Radical 5 1,178 Oct-02-2023, 12:57 AM
Last Post: deanhystad
  Trying to understand global variables 357mag 5 1,123 May-12-2023, 04:16 PM
Last Post: deanhystad
  Delete all Excel named ranges (local and global scope) pfdjhfuys 2 1,799 Mar-24-2023, 01:32 PM
Last Post: pfdjhfuys
  global variables HeinKurz 3 1,152 Jan-17-2023, 06:58 PM
Last Post: HeinKurz
  How to use global value or local value sabuzaki 4 1,157 Jan-11-2023, 11:59 AM
Last Post: Gribouillis
  Clarity on global variables JonWayn 2 949 Nov-26-2022, 12:10 PM
Last Post: JonWayn
  Global variables not working hobbyist 9 4,742 Jan-16-2021, 03:17 PM
Last Post: jefsummers
  Global vs. Local Variables Davy_Jones_XIV 4 2,658 Jan-06-2021, 10:22 PM
Last Post: Davy_Jones_XIV
  Global - local variables Motorhomer14 11 4,268 Dec-17-2020, 06:40 PM
Last Post: Motorhomer14
  from global space to local space Skaperen 4 2,326 Sep-08-2020, 04:59 PM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020