Using loops to call recursive function - python-3.x

I am trying to create a recursive function that takes three parameters: name of the dictionary, name of the original (This will be the key in the dict), and name of the final (trying to determine if it is possible to reach the final from the original)
My code functions well and enters the correct if statements and everything (tested using print statements) however, instead of the function returning True or False, it returns None every time.
I determined that this is because rather than calling my recursive function with "return" I only call the name of the function. However, if I include return in my code, the function only runs with the first value from the dictionary's key.
Any and all help on this would be appreciated.
def evolve(dictname, babyname, evolvedname):
if babyname == evolvedname:
return True
elif babyname in dictname.keys():
if dictname[babyname]:
for i in dictname[babyname]:
evolve(dictname,i,evolvedname)
else:
return False
else:
return False

Collect all recursive call's results, and return True if any of them is true.
Something like:
def evolve(dictname, babyname, evolvedname):
if babyname == evolvedname:
return True
elif babyname in dictname.keys():
if dictname[babyname]:
results = [] #To collect results
for i in dictname[babyname]:
results.append(evolve(dictname,i,evolvedname))
#Check if any of them is True
for res in results:
if res==True: return True
return False #No true among childs
else:
return False
else:
return False
But I think this code can be simplified to just:
def evolve(dictname, babyname, evolvedname):
if babyname == evolvedname:
return True
return any(evolve(dictname,i,evolvedname) for i in dictname.get(babyname,[]))
Lastly, although I don't know what you are trying to do, you might get an infinite loop, this is like doing dfs but without marking any node as already explored(black) or currently exploring(gray).

Related

create a function that adds to a list

I have en assignment about lists that goes like this,
Create a global variable called myUniqueList. It should be an empty list to start.
Next, create a function that allows you to add things to that list. Anything that's passed to this function should get added to myUniqueList, unless its value already exists in myUniqueList. If the value doesn't exist already, it should be added and the function should return True. If the value does exist, it should not be added, and the function should return False;
Finally, add some code below your function that tests it out. It should add a few different elements, showcasing the different scenarios, and then finally it should print the value of myUniqueList to show that it worked.
Add another function that pushes all the rejected inputs into a separate global array called myLeftovers. If someone tries to add a value to myUniqueList but it's rejected (for non-uniqueness), it should get added to myLeftovers instead."
This is the code I have wrote to create the lists and add value to the list but I dont get the output I want from this code, can someone help me explain what I do wrong how do I write so my list get filled with elements? The Output I get from the code now, you can see below.
myUniqueList = []
myLeftovers = []
def addList(newThing):
if newThing in myUniqueList:
myLeftovers.append(newThing)
return False
else:
myUniqueList.append(newThing)
return True
print(myUniqueList) # []
print(addList("Meliodas")) # returns 'True' since it's a new item
print(addList("Escanor")) # returns 'True' since it's a new item
print(addList("Meliodas")) # returns 'False' since it's already been added
print(myUniqueList) # This includes the new entries
print(myLeftovers) # This includes any repeated entries
I get
[]
False
False
False
[]
[]
Can you explain why the list dont get the words added and why I get Syntax Error on the else statement
According to your question, you were asked to create a global variable called myUniqueList. Since myUniqueList is a global list, in other to use it in a function, we have to tell the function we are using a global list by adding "global" before myUniqueList; hence your code will be as follows:
myUniqueList = []
myLeftovers = []
def add(newValue):
global myUniqueList
if newValue in myUniqueList:
addToLeftovers(newValue)
return False
else:
myUniqueList.append(newValue)
return True
def addToLeftovers(newValue):
myLeftovers.append(newValue)
# Testing the code:
print(add("Hello"))
print (myUniqueList)
print(add("Hello"))
print(myUniqueList)
print(myLeftovers)
Your Result will be as follows:
True
['Hello']
False
['Hello']
['Hello']
The first "Hello" came out TRUE while the second "Hello" came out FALSE. Then the third "Hello" was from the second hello which was rejected and now, pushed to the "myLeftovers" as stated in your question.

Python Try Except when a list is null

I've been searching for my problem here, but i can't find the exact answer to my problem.
I call a sympy function ( solve() ). This function can return a full list or an empty list.
I call this piece of code inside a while:
try:
sol = solve([eq1,eq2],[r,s])
rB = bin(abs(sol[0][0]))
sB = bin(abs(sol[0][1]))
stop = True
r = rB[2:len(rB)]
s = sB[2:len(sB)]
P = int("0b"+r+s,2)
Q = int("0b"+s+r,2)
print(P*Q == pubKey.n)
print("P = {}".format(P))
print("Q = {}".format(Q))
break
except ValueError:
pass
What i want is:
if the solve() returns an empty list, just pass. And if the solve() returns a full list, keep with the execution. The solve will be returning empty list until i find the right value.
This can be reached by checking sol[0][0], if there's a non-empty list this will work, but if the list is empty, this will throw an error (null pointer) i want try to flag it and pass.
What i'm having now is that when sol is empty, it tries to get sol[0][0], and ofc this throws an error that's not being catched by the try, and the whole code stops.
Anyone knows a solution for that? I'm not using try correctly?
Set sol in the beginning of each loop to some value and check it in the except clause
about else
try/except has an else which will be run the try block did not raise an Exception
and for has an else clause for when it was not broken out of!
for foo in iterable:
# set value so the name will be available
# can be set prior to the loop, but this clears it on each iteration
# which seems more desirable for your case
sol = None
try:
"logic here"
except Exception:
if isinstance(sol, list):
"case where sol is a list and not None"
# pass is implied
else: # did not raise an Exception
break
else: # did not break out of for loop
raise Exception("for loop was not broken out of!")

Is not using return value in Python bad practice/dangerous?

I have a function that only sometimes returns values. Below a simplified example.
def return_something(bool):
if bool:
return "Something"
else:
print("Hello ")
I figured that I could also rewrite the function as such:
def return_something():
print("Hello ")
return "Something"
As I only sometimes need the return value and when I need it the rest of the function may execute normally. Now I would call the function in two ways:
return_something()
string = return_something()
My question: When using the second design I don't use the returned value in the first function call. Is this considered bad practice and or dangerous?

python function return not working

I have a recursive traversal function to go through a JSON object and return the information that I want. The problem is that it's not returning anything. I know that the recursion is working properly because I modified to function to print out the input at each step and it was printing out the expected results - including the final step.
def wikipedia_JSON_traversal(wiki):
if type(wiki)==dict:
if 'definitions' in wiki.keys():
wikipedia_JSON_traversal(wiki['definitions'])
elif 'text' in wiki.keys():
wikipedia_JSON_traversal(wiki['text'])
else:
pass
elif type(wiki)==list:
wikipedia_JSON_traversal(wiki[0])
else:
return wiki
You need a return after each function call, the returns don't bubble up automatically.
def wikipedia_JSON_traversal(wiki):
if type(wiki)==dict:
if 'definitions' in wiki.keys():
return wikipedia_JSON_traversal(wiki['definitions'])
elif 'text' in wiki.keys():
return wikipedia_JSON_traversal(wiki['text'])
else:
pass
elif type(wiki)==list:
return wikipedia_JSON_traversal(wiki[0])
else:
return wiki

How to null out exceptions in an htmlChecker

While this is a project assignment for class I am trying to understand how to do a specific part of the project.
I need to go through an html file and check if all the opening statements are matched to closing statements. Further, they must be in the correct order and this must be checked using a stack I've implemented. As of right now I am working on extracting each tag from the file. The tough part seems to be the two exceptions that I am working on here. The and the . I need these tags to be removed so the program doesn't read them as an opening or closing statement.
class Stack(object):
def __init__(self):
self.items = []
def isEmpty(self):
return self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items[-1]
def getTag(file):
EXCEPTIONS = ['br/', 'meta']
s = Stack()
balanced = True
i = 0
isCopying = False
currentTag = ''
isClosing = False
while i < len(file) and balanced:
if symbol == "<":
if i < (len(file) - 1) and file[i + 1] == "/":
i = i + 1
isClosing == True
isCopying == True
if symbol == ">":
if isClosing == True:
top = s.pop()
if not matches(top, symbol):
balanced = False
else:
**strong text**
s.push(currentTag)
currentTag = ''
isCopying == False
if isCopying == True:
currentTag += symbol
The code reads in the file and goes letter by letter to search for <string>. If it exists it pushes it on to the stack. The matches functions checks to see if the closing statement equals the opening statement. The exceptions list is the ones I have to check for that will screw up the placing of the strings on the stack. I am having a tough time trying to incorporate them into my code. Any ideas? Before I push on to the stack I should go through a filter system to see whether that statement is valid or not valid. A basic if statement should suffice.
If I read your requirements correctly, you're going about this very awkwardly. What you're really looking to do is tokenize your file, and so the first thing you should do is get all the tokens in your file, and then check to see if it is a valid ordering of tokens.
Tokenization means you parse through your file and find all valid tokens and put them in an ordered list. A valid token in your case is any string length that starts with a < and ends with a >. You can safely discard the rest of the information I think? It would be easiest if you had a Token class to contain your token types.
Once you have that ordered list of tokens it is much easier to determine if they are a 'correct ordering' using your stack:
is_correct_ordering algorithm:
For each element in the list
if the element is an open-token, put it on the stack
if the element is a close-token
if the stack is empty return false
if the top element of the stack is a matching close token
pop the top element of the stack
else return false
discard any other token
If the stack is NOT empty, return false
Else return true
Naturally, having a reasonable Token class structure makes things easy:
class Token:
def matches(t: Token) -> bool:
pass # TODO Implement
#classmethod
def tokenize(token_string: str) -> Token:
pass # TODO Implement to return the proper subclass instantiation of the given string
class OpenToken:
pass
class CloseToken:
pass
class OtherToken:
pass
This breaks the challenge into two parts: first parsing the file for all valid tokens (easy to validate because you can hand-compare your ordered list with what you see in the file) and then validating that the ordered list is correct. Note that here, too, you can simplify what you're working on by delegating work to a sub-routine:
def tokenize_file(file) -> list:
token_list = []
while i < len(file):
token_string, token_end = get_token(file[i:])
token_list.append = Token.tokenize(token_string)
i = i + token_end # Skip to the end of this token
return token_list
def get_token(file) -> tuple:
# Note this is a naive implementation. Consider the edge case:
# <img src="Valid string with >">
token_string = ""
for x in range(len(file)):
token_string.append(file[x])
if file[x] == '>':
return token_string, x
# Note that this function will fail if the file terminates before you find a closing tag!
The above should turn something like this:
<html>Blah<meta src="lala"/><body><br/></body></html>
Into:
[OpenToken('<html>'),
OtherToken('<meta src="lala"/>'),
OpenToken('<body>'),
OtherToken('<br/>'),
CloseToken('</body>'),
CloseToken('</html>')]
Which can be much more easily handled to determine correctness.
Obviously this isn't a complete implementation of your problem, but hopefully it will help straighten out the awkwardness you've chosen with your current direction.

Resources