Bottom Page

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.
Quote
#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.
Feel like you're not getting the answers you want? Checkout the help/rules for things like what to include/not include in a post, how to use code tags, how to ask smart questions, and more.

Pro-tip - there's an inverse correlation between the number of lines of code posted and my enthusiasm for helping with a question :)
Quote
#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?
Quote
#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

Quote
#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
Quote
#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.
Quote
#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.
Quote
#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?
Quote
#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.
Quote
#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

Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Please help me understand how to use global variables joew 6 239 Jan-05-2020, 06:03 PM
Last Post: joew
  Global Variables - Some Points Needing Clarification. adt 4 261 Nov-30-2019, 01:23 PM
Last Post: adt
  modifying variables in local or global space Skaperen 2 210 Aug-14-2019, 07:13 AM
Last Post: Skaperen
  Global variable does not seem to be global. Columbo 6 457 Jul-15-2019, 11:00 PM
Last Post: Columbo
  Global variables not changing ThemePark 3 466 Mar-02-2019, 11:24 AM
Last Post: Larz60+
  help with threading module and passing global variables ricardons 1 1,094 Feb-21-2019, 12:48 PM
Last Post: stullis
  Use of global variables from several modules. Jstechg 3 552 Jan-03-2019, 03:39 AM
Last Post: scidam
  Trouble with global variables maymac789 1 625 Mar-29-2018, 03:15 AM
Last Post: Mekire
  Is This Code Ok? How Can I Avoid Using Global Variables? digitalmatic7 9 1,691 Feb-15-2018, 09:32 AM
Last Post: DeaD_EyE
  Variable Resetting Issue Niicollas__ 8 1,190 Jan-20-2018, 08:52 PM
Last Post: j.crater

Forum Jump:


Users browsing this thread: 1 Guest(s)