Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Resetting Global Variables?
#1
I will try to put this as explanatory as possible since more questions or replies may/could come from this question, but I have about 400 lines of codes, 13 functions, and about 12 global variables. As I am coming to a close with all the functions working with each other, I notice that when the code finishes without errors, some of my global variables are not being reset. They are retaining their values until a certain period and then finally gives the variable a new value. I will post as much code as I can without giving sensitive data. How would you properly declare a global variable with use for multiple functions as well as re-assigning the variables when needed?

def FindCustName(CustomerSaleID):
    global CustomerName
    global Vin
    global Fnum
    CustomerName = ""
    Vin = str(CustomerIndex[int(float(LoadedSales['CC'][InxLoc]))][2])[-8:]
    FNum= str(CustomerIndex[CustomerSaleID][3])
    if ItemTag == "Lube" or str(CurHA).find("EntPrise") > 0:
        CustomerName = str(CustomerIndex[CustomerSaleID][3])
        return CustomerName
    else:
        CustomerName = str(CustomerIndex[CustomerSaleID][0])
    return CustomerName
global CustomerName
CustomerName = ""


Currently I have been assinging my global variables within the function that they are first called/created from. What is highlighted red is setup because it seems I have to declare some value before using the global variable. In other words, it seems to never let me just declare a global variable-I have to set the value as well. I have no global variables assigned or created outside any functions. Again I have 13 total functions with at least 8 functions having at least one global variable. I feel I am going about this the wrong way. Any suggestions? Thanks.

Note: If possible, I would love to post the entire script with sensitive data removed because I would love to hear everyones opinion on the code. So if this is something that becomes requested frequently, I will do my best to post the entire code.
Reply
#2
Why are you using global variables? They're notoriously hard to debug, and often viewed as poor code architecture.

If I inherited that code and had to fix it, I'd start removing the global variables just to wrap my head around how things work. Have you tried removing them? We can potentially help you move away from them, but personally I wouldn't even try to debug them as-is.
Reply
#3
It seems that I have found some workaround or a solution. Haven't quite figured out yet why it necessarily works, but if anyone could explain that would be awesome. So I moved my variables that need to be global to their own function (since they need to use functions anyhow to obtain the correct value). After declaring their own global variables in their respective functions, it seems that I was then able to update my global variable properly. Here is what I did.

def FindVin():
    global Vin
    Vin = str(CustomerIndex[int(float(LoadedSales['CC'][InxLoc]))][2])[-8:]
    return Vin
And the main Function before FindVin is called.

            def Main():
                CustomerSaleID = CustomerSaleOBJID()
                Vin = FindVin()
                FPnum = FindFPnum()

(Sep-28-2018, 04:31 PM)micseydel Wrote: Why are you using global variables? They're notoriously hard to debug, and often viewed as poor code architecture.

If I inherited that code and had to fix it, I'd start removing the global variables just to wrap my head around how things work. Have you tried removing them? We can potentially help you move away from them, but personally I wouldn't even try to debug them as-is.

I posted right as you did so I didn't see your post before I had posted my own response. I cannot find a good source tutorial on how to properly use variables outside/with other functions. How would you use a variable globally without being global?
Reply
#4
(Sep-28-2018, 04:35 PM)WuchaDoin Wrote: How would you use a variable globally without being global?

With parameters and return values:

>>>> def add2(x):
...     return x + 2
...
>>> z = 5
>>> z = add2(z)
>>> z
7
Also with classes, which can retain values within an instance of the class. There are links to tutorials for both in my signature below.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
(Sep-28-2018, 05:14 PM)ichabod801 Wrote:
(Sep-28-2018, 04:35 PM)WuchaDoin Wrote: How would you use a variable globally without being global?

With parameters and return values:

>>>> def add2(x):
...     return x + 2
...
>>> z = 5
>>> z = add2(z)
>>> z
7
Also with classes, which can retain values within an instance of the class. There are links to tutorials for both in my signature below.

With posting this example, I've noticed the problem I keep encountering is that looks like it calls for global variables. Here is how it is setup and why I am having to use global variables. I know there is a work around which is why I am posting the snippet.

First I have main called:
            def Main():
                CustomerSaleID = CustomerSaleOBJID()
                Vin = FindVin()
                FPnum = FindFPnum()
Then each function is called in the proper order in Main().
def FindVin():
    Vin = str(CustomerIndex[int(float(LoadedSales['CC'][InxLoc]))][2])[-8:]
    return Vin

def FindFnum():
    Fnum = str(CustomerIndex[CustomerSaleID][3])
    return Fnum

def CustomerSaleOBJID():
    CustomerSaleID = int(float(LoadedSales['CC'][InxLoc]))
    return CustomerSaleID
When the code reaches FindFnum() and has to use the variable CustomerSaleID (which should already be declared by then); This is where I begin to encounter my problem. I need to use CustomerSaleID in multiple functions, but using what it shown above; it seems to create a local variable? Vin, CustomerSaleID, and FPnum will be use throughout all 13 functions. Would the workaround being that I would have to declare a local variable to be used within each function?
i.e.
def FindFnum():
    CustomerSaleID = CustomerSaleOBJID()
    Fnum = str(CustomerIndex[CustomerSaleID][3])
    return Fnum
Reply
#6
Think of a function as a calculator. You give it some info, it gives you some response. If you give it "4+3", it will ALWAYS give you "7" as a response. It won't look up what 7 currently means, and sometimes return "8", it'll always give you the same response for a given argument.

It's getting hard for you to track down errors, because your functions aren't black boxes. They either don't take arguments, or use those arguments to get a part of an external whole.

Let's take FindFnum() for example:
def FindFnum():
    CustomerSaleID = CustomerSaleOBJID()
    Fnum = str(CustomerIndex[CustomerSaleID][3])
    return Fnum
What's a CustomerIndex? What does CustomerSaleOBJID return when you don't pass it anything? Ideally, CustomerSaleOBJID would return every single customer sales record you have, for every single customer you've ever done business with, because you didn't narrow it down at all. But it doesn't. It returns whatever the magic number InxLoc is, from whatever the mysterious LoadedSales is.

From these snippets, it looks like you're not really using functions at all. It looks like you're using a dict to hold some value, and then doing something with it, using functions as a sort of nickname to parts of the dict.
Reply
#7
(Sep-28-2018, 06:41 PM)nilamo Wrote: From these snippets, it looks like you're not really using functions at all. It looks like you're using a dict to hold some value, and then doing something with it, using functions as a sort of nickname to parts of the dict.

Precisely. I am using dictionaries to compress the data to grab only the most useful data. I have 9 dictionaries total. I then use the data from the dictionaries with the functions for faster results rather than using an array to sift through each line of data separately. I am working with anywhere to as little as 200 sales to upwards of 1 Mil+ sales. So with assigning each sale ID to a dictionary key, I can assign each sale ID (dictionary key) their sale notes to quickly access that specific sales information.

List of Dictionaries:
CustomerIndex
CustomerItemIndex
ClassIndex
SaleNotesIndex
S_HouseAccountsIndex
HouseAccountsIndex
HAmod (used for calling either S_HouseAccountsIndex or HouseAccountsIndex)
IsToEmailIndex
IsToEmail_S_Index

I don't mind posting my entire code, but I don't know what the forum rules are for posting entire codes.
Reply
#8
(Sep-28-2018, 06:59 PM)WuchaDoin Wrote: I am working with anywhere to as little as 200 sales to upwards of 1 Mil+ sales.
And these are uniquely generated each time you run the program? Why isn't this info in a database or something?
Reply
#9
I will explain as best I can (please ask if still I am missing something).

We have a main DB. All of the information I have is directly from the Database. I then turn the information into invoices that are importable to quickbooks. All the data is already pre-loaded into a CSV format which is then used for each dictionary.

1. I pull all of our sales from the previous day (either pyodbc or MS Access).

2. Each sale has multiple items retaining a separate row for each item. Therefore, I could be dealing with a total of 10 rows for a single sale because the sale has multiple items.

3. Each sale can either have customer ID's associated with them or not.

4. Each sale can either have an Account associated with it or not

5. Each sale can have either an adjusted or reversed sale linked to the actual sale. (so a single sale can extend to about 50 rows because of 2 extra sales that are associated with that sale; this leads to a column titled 'ACUTALSALEID' that I use from the DB to contrast which sales have multiple sales associated with them)

With these sales, I have to locate all the necessary information to convert each sale into an importable invoice layout which is where the dictionaries come in.

Customers themselves have their own table in our DB. I export and convert this table in a dictionary to be used with the information from the sales.

Customer Accounts are also in their own table in our DB. I also have to export and convert our Accounts list to a dictionary to quickly be called using the Customers information(i.e. using the Customer ID as the dictionary key for Customer Accounts).

To work with, on average, 1k to 10k sales, it seems to be more convenient to place all the back-end data (Customer info, Account info, etc) into a dictionary to quickly be called based on the information provided for each sale.

I hope this makes sense and apologies if not.
Reply
#10
I'm going to back down to simple things, and rewrite your three function example with parameters:

def Main(CustomerIndex, LoadedSales, InxLoc):
    CustomerSaleID = CustomerSaleOBJID(LoadedSales, InxLoc)
    Vin = FindVin(CustomerIndex, LoadedSales, InxLoc)
    Fnum = FindFnum(CustomerIndex, CustomerSaleID)

def FindVin(CustomerIndex, LoadedSales, InxLoc):
    Vin = str(CustomerIndex[int(float(LoadedSales['CC'][InxLoc]))][2])[-8:]
    return Vin
 
def FindFnum(CustomerIndex, CustomerSaleID):
    Fnum = str(CustomerIndex[CustomerSaleID][3])
    return Fnum
 
def CustomerSaleOBJID(LoadedSales, InxLoc):
    CustomerSaleID = int(float(LoadedSales['CC'][InxLoc]))
    return CustomerSaleID
So each value that a function needs is passed to that function as a parameter when it is called. To do this, you have to specify that the function is expecting that parameter when it is defined. You say this Fnum is needed in 13 different functions. So each one of those would be defined with Fnum as a parameter, and when each one is called, Fnum would get passed to that function as a parameter. All of this is explained in more detail in the functions tutorial linked to in my signature below. Including what Nilamo alluded to, where you can assign default values to parameters, so that the function can be called without that parameter, if it is a common (but not always) used parameter.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Trying to understand global variables 357mag 5 1,064 May-12-2023, 04:16 PM
Last Post: deanhystad
  Global variables or local accessible caslor 4 984 Jan-27-2023, 05:32 PM
Last Post: caslor
  global variables HeinKurz 3 1,101 Jan-17-2023, 06:58 PM
Last Post: HeinKurz
  Clarity on global variables JonWayn 2 904 Nov-26-2022, 12:10 PM
Last Post: JonWayn
  resetting an iterator to full Skaperen 7 6,809 Feb-20-2022, 11:11 PM
Last Post: Skaperen
  variables vcnt, ocnt, and mcnt adding previous values and not resetting to 0 archanut 2 1,884 Feb-12-2021, 06:56 PM
Last Post: deanhystad
  Global variables not working hobbyist 9 4,615 Jan-16-2021, 03:17 PM
Last Post: jefsummers
  Global vs. Local Variables Davy_Jones_XIV 4 2,595 Jan-06-2021, 10:22 PM
Last Post: Davy_Jones_XIV
  Global - local variables Motorhomer14 11 4,127 Dec-17-2020, 06:40 PM
Last Post: Motorhomer14
  Question regarding local and global variables donmerch 12 4,976 Apr-12-2020, 03:58 PM
Last Post: TomToad

Forum Jump:

User Panel Messages

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