Python recursive function stuck in infinite loop despite Try statement - python

I want to write a simple function that prints out a row of a pandas dataframe. If the dataframe has already been loaded into memory, I don't want to reload it. If it has not been loaded into memory when the function is called for the first time, I want to load it.
I am using a Try statement to test whether the dataframe exists (Testing if a pandas DataFrame exists). The alternative options for doing this produce NameError as the DF has not been initialised to None or empty.
global dfIndices
def getSeriesInfo(seriesCode,verbose=False):
try:
if verbose:
print(dfIndices.loc[seriesCode])
else:
print(dfIndices.loc[seriesCode]['Data Item Description'])
# catch when it hasn't even been defined
except NameError:
print('I am here.')
dfIndices = pd.read_excel(dirAppData+'Indicies.xlsx')
dfIndices.set_index('Series ID',inplace=True)
getSeriesInfo(seriesCode,verbose)
getSeriesInfo('A2304402X')
Assuming I have not already loaded the dfIndicies dataframe, I would expect when first calling the function, that the Try statement would fail, the dataframe would be loaded, the function called again, the Try passed and the function stop exceuting.
Instead, I get an infinite loop.
So that I can learn something, why doesn't this work as expected and what should I do differently?
Thanks

Related

Running the same code but with two different datasets (inputs)

I have a code in JupyterLab that consists of several functions spread in several cells. The first function generates a dataset that is used in all other functions after it.
What I have to do is run the same code twice but with one of the functions modified. So it would look like this:
data_generating_function() # this function should only be ran once so it generates the same dataset for both trials
function_1() # this is the function that is to be modified once, so there are two version of this function
function_2() # this function and all functions below it stay the same but should be ran twice
function_3()
function_4()
function_5()
So I would run data_generating_function() once and generate the dataset. Then I would run one version of function1() and all the functions below it, then I would run another version of function1() and all the other functions below it.
What would be a good way to implement this? I could obviously duplicate the code and just change some function names, I could also put it all into a single cell and create a for loop. However is there a better way that would ideally preserve multiple cells too?
Thank you
Simply iterate over your two choices for the first function:
data_generating_function()
for func1 in (function1a, function1b):
func1()
function_2()
function_3()
function_4()
function_5()
Apologies if I misunderstood the question, but could you not do the following:
Cell 1:
# define all functions
Cell 2:
dataset = data_generating_function()
Cell 3:
# Run version 1 of function 1 on dataset
result_1_1 = function_1_v1(dataset)
result_2_1 = function_2(result_1_1)
result_3_1 = function_3(result_2_1)
function_4(result_3_1)
Cell 4:
# Run version 2 of function 1 on dataset
result_1_2 = function_1_v2(dataset)
result_2_2 = function_2(result_1_2)
result_3_2 = function_3(result_2_2)
function_4(result_3_2)
This solution assumes that:
you define functions with return values
that passing around the results is not "expensive"
You can also persist the results in a file if the latter is not the case.
To reduce code duplication in function_1, you can add a parameter that switches between the two versions.
You should try to avoid modifying or directly iterating over functions whenever possible. The best thing to do in this case would be to add a boolean parameter to function1 specifying which version of the function you want to run. It would look something like this:
def function1(isFirstTime):
if isFirstTime:
# do stuff the first time
pass
else:
# do stuff the second time
pass
You could then iterate over the functions:
data_generating_function()
for b in (True, False):
function1(b)
function2()
function3()
# ...

How to stop Function reassigning Boolean value within loop

Im trying to learn Python via creating a basic language-learning app to test myself. In order to get it to test me with a different word each time I have tried to write a function that generates an intial key ONLY IF it is the first time it is run (after this i have another function which should generate a different key).
In order to do this I have tried to us a Boolean (isfirsttime) which I initially set to False within the main loop of the particular Tkinter window in which this part of the code runs (sorry if I'm not explaining this particulary well am admittedly a total begginer!).
Within my function I then check if this value is False and then - it is - i generate a key and pass out this plus the value TRUE.
Back in the main loop I then assign the value True to the variable isfirsttime.
I think that the problem is that in the main loop the isfirsttime is FIRST assigned to False (to get the function checkfirst to work the first time) but this means that every time it is run it resets the Boolean to False.
Could anybody explain to me how I can reassign the value of isfirst time to TRUE after the first time the code has run, in a way that will cause the checkfirst function to PASS everytime after that? (I know that my problem has something to do with scope but i cannot figure it out - and have tried functions within functions and endlessly reassigning variables so I'm obviously not getting something here!)
Many thanks!
isfirsttime == False
def checkfirst():
if isfirsttime==False:
for item in categories:
newkey=random.choice(list(tempdict))
print("key is" + newkey)
isfirsttime=not isfirsttime
print(str(isfirsttime) + "isfirsttime")
return newkey, True
else:
pass
genkey=checkfirst()[0]
isfirsttime=checkfirst()[1]
You can make the call like this:
genkey, isfirsttime = checkfirst()
However, you still need to do something about the second time that checkfirst() is called.
Also, reading the comments under your question you need to sort out the assignment to isfirsttime:
isfirsttime = False # assign isfirsttime to False
def checkfirst():
# stuff omitted

Break out of a loop using a method in another module

So basically, using exec(), I made an infinitely scaleable list of abilities for my game. The name of the method for the ability is stored in one module as a string and that string is appended to the header to call the actual method from another module.
Example:
Main module:
exec("ptwo." + curboard.tmp[ptwo.position].effect)
The effect is assigned by a list in a module
effects = ["jump()", "skip(), extra_turn(), none()"]
and each item in the list corresponds to a method in another module
def none(self):
print("This tile has no effect.")
So for the extra turn effect i want to make it inject a continue command into the loop so the turn loop starts again from the top.
Just returning continue made it error out. Ditto with bare continue

How to pass a result from a function that requires GUI input (python)?

I'm writing a python script that takes user input through a GUI and then passes that along to a function that basically reads through text files and checks that what the user requested is there. This function returns an array with True or False for each check.
I want to use this array in a different function (def markup()), but if I call it without giving the function the user input, I get an error.
Is there a way for me to store the results of this function and pass it without needing the user input each time?
Pseudo code:
def clickButton():
userInput = [A,B,C,D,E]
textCheck(userInput)
def textCheck(userInput):
*code for checking text creates an array named allResults*
return allResults
def markup():
results = textCheck()
print(results)
You need to manage allResults as a persistent object. One way is to pass the results everywhere as a parameter, such that whatever thread is executing always has a handle to the list. Another way is to (shudder) make it a global variable -- this is somewhat dangerous as a habit, but may be the easiest for you to implement and maintain. You can also create a Results class and instantiate an object that persists as long as you need it.
I can't recommend one over another without having the flow of the main program.
I ended up calling markup(allResults) at the end of textChecker(). It worked.

Read the value returned by a function without updating it?

I have some code that will update and return a value every fifteen seconds.
def set_interval(func, sec):
def func_wrapper():
set_interval(func, sec)
func()
t = threading.Timer(sec, func_wrapper)
t.start()
return t
def gem_price():
return random.randint(1,1000)
print ("Updated")
set_interval(gem_price, 15)
Later within the code, I want to output the value that was returned by the function 'gem_price'. The way I've been going about this is by printing the function itself.
print(gem_price())
The problem I have is, everytime I output the 'gem_price' using this method, it will update the value. I would like to able to output the value without having to update it.
Is there any way to do this? Thanks in advance!
If you want to print value after every 15 sec, you can use this:
import time
while True:
...
Yourcode
...
print('The answer is....', answer)
time.sleep(15)
gem_price() just returns a random integer between 1 and 1000 every time it is called. It does not store anything.
If you want to store this value, just assign it to a variable: value = gem_price() and then use this variable and not the function (unless you want another value, but to keep it you should assign it to another var).
It seems you don't completely understand how functions work, by the way. A variable inside of a function gets deleted when the function exits (generally). Also, the execution flow stops after the return statement, so your print is never reached and thus never executed.
You should read this part of the Python tutorial. Actually, all of it.

Categories

Resources