Function returns None unexpectedly - python

Ok. So I finished this piece of code I have been working on, but I have a major problem. I doesn't return correctly.
if is_word(wordlist, decodedText):
print 'entered if statement'
print answer
return answer
this is the piece of code that isn't working. The rest of the program isn't necessary. The line about entering the if statement was just a debug, so I would actually know that it did enter. The next print statement was to make sure that my variable answer actually was assigned to something, like it was elsewhere in the program.
Now, this is what the code is giving me:
entered if statement
[(0, -6), (3, -18), (12, -16)]
None
I also tried using type(answer) to make sure that I didn't have some weird bug I wasn't seeing, but it was just saying it was a list.
So, why am I getting a None return??
answer = []
def find_best_shifts_rec(wordlist, text, start):
"""
Given a scrambled string and a starting position from which
to decode, returns a shift key that will decode the text to
words in wordlist, or None if there is no such key.
Hint: You will find this function much easier to implement
if you use recursion.
wordlist: list of words
text: scambled text to try to find the words for
start: where to start looking at shifts
returns: list of tuples. each tuple is (position in text, amount of shift)
"""
global answer
for shift in range(27):
decodedText = apply_shift(text[start:], -shift)
if is_word(wordlist, decodedText):
print 'entered if statement'
print answer
return(answer)
split = decodedText.split()
if is_word(wordlist,split[0]) == True:
answer.append((start, -shift))
find_best_shifts_rec(wordlist, decodedText, (start+(len(split[0])+1)))
break
print find_best_shifts_rec(wordlist, "JufYkaolfapxQdrnzmasmRyrpfdvpmEurrb?", 0)
This is the rest of my function. Let me know if there is something else you need to see.

the problem was you were not returning your recursive result ....
if is_word(wordlist,split[0]) == True:
answer.append((start, -shift))
return find_best_shifts_rec(wordlist, decodedText, (start+(len(split[0])+1)))

Related

Write a function named first_word that returns the first word in a string

My buddy sent me a screenshot a question he was stuck on for an assessment and asked if I was able to help. So I took a shot at it and it's been two days now and this is haunting my dreams.
Question: "create a function named first_word that takes in a string and returns the first word.
Given Code:
assert first_word("Random string here") == "Random"
assert first_word("Another random string here") == "Another"
assert first_word("Again a random string... etc.") == "Again"
print("Excerscise is complete"
What I have Tried amongst other variations:
def first_word(x):
print(first_word.split().pop(0))
return first_word
assert first_word("Random string here") == "Random"
assert first_word("Another random string here") == "Another"
assert first_word("Again a random string... etc.") == "Again"
print("Excerscise is complete"
def first_word(x):
print(first_word.split()
return
assert first_word("Random string here") == "Random"
assert first_word("Another random string here") == "Another"
assert first_word("Again a random string... etc.") == "Again"
print("Excerscise is complete"
I have tried a lot of different combinations and can't think to add them all, I have looked up online and I can't seem to make the code work how it was for the assessment. I can return the first letter but I cannot wrap my brain around how to get the first word.
This assessment my friend is doing has no actual impact on me, and it's already passed so he will gain nothing from this. I merely want to understand how to complete this task that will help me figure out why it is failing.
I currently work in eDiscovery and am working towards getting my security + and OSCP. I feel gaining any knowledge of python will be beneficial. Any help would be appreciated. Thank you very much
-Oerml
You have the right basic idea here:
def first_word(x):
print(first_word.split().pop(0))
return first_word
but are confused about the syntax:
first_word is the function, and x is the string parameter that you're trying to get the first word of. first_word.split() doesn't make sense, because you can't split() a function. What you can split() is x.
You're mixing up print and return. Your function is supposed to return the first word (not first_word, which is the function itself, but the string you get by splitting x), and not print it.
This should work:
def first_word(x):
return x.split()[0]

Is there an alternative to .endswith()?

I am trying to write an if, elif else clause, so that depending on the German word ending, we can see is it should go with der, die or das.
Here is my code:
word = input ("Enter word: ")
if (word.endswith('er' 'ismus')):
print ("der")
elif (word.endswith('falt' 'heit' 'keit' 'schaft' 'ung')):
print ("die")
else (word.endswith('chen' 'lein')):
print ("das")
I have also tried using suffix with square brackets but everything goes grey when I do that and so I can assume it won't work. And clearly true and false are not adequate responses for what I need. Is there anything else I can try?
Thanks in advance!
The endswith method really only checks if the word ends with one thing, but you can do something like:
def word_ends_with_one_of(word, options):
for option in options:
if word.endswith(option):
return True
return False
Then call that with:
suffix_die = ['falt', 'heit', 'keit', 'schaft', 'ung']
suffix_der = ['er', 'ismus']
suffix_das = ['chen', 'lein']
if word_ends_with_one_of(word, suffix_die):
print ("die")
elif word_ends_with_one_of(word, suffix_der):
print ("der")
elif word_ends_with_one_of(word, suffix_das):
print ("das")
As an aside, your else clause is currently problematic, it should not have a condition attached to it (unless it's a typo and you meant to have an elif instead).
Now, even though that you be a useful function to have for other purposes, you may want to consider a more application focused method since you'll be introducing a function anyway. By that, I mean something more closely suited to your specific needs, such as:
def definite_article_for(word):
# Could also use word_ends_with_one_of() in here.
if word.endswith('er'): return 'der'
if word.endswith('ismus'): return 'der'
if word.endswith('falt'): return 'die'
:
if word.endswith('lein'): return 'das'
return None
}
Then use article = definite_article_for(my_word) to get the article you want.

Why does this code not work for all inputs

I am trying to write python code that takes two strings as input and checks if all the characters of the second string are present in the first string. If so, then the output is the second string. If not, the output is the string "This does not work". I have tested this procedure for a variety of inputs, and it typically works, but not always. For example, if my two inputs are "helo" and "olhe", respectively, the output is "This does not work," whereas it should be "olhe" since all the characters in "olhe" are present in "helo."
Here is my code
def fix_machine(debris,product):
n = 1
while True:
first_element = product[0:n]
find_first_element = debris.find(first_element)
if first_element == product:
return product
break
n = n + 1
if find_first_element == -1:
return "This does not work"
break
So why does this not work?
You could do this as a more elegant solution, assuming that you strictly want all of the second string characters to be present in first.
def fix_machine(first, second):
for character in second:
if character not in first:
return False
return second
This returns correct input for your code. Not entirely sure what is wrong with your code as I have not stepped through.
EDIT: Albert has a much more elegant solution, reference his
As far as I understood you just want to compare two strings containing different characters.
For doing so, I would suggest converting both strings to a set which then provides (in contrast to a list) order-less comparison of its elements.
def check_string(first_str, second_str):
# convert strings to sets in order to compare characters
if set(first_string) == set(second_string):
return second_str
else:
return 'This does not work.'
first_string = 'helo'
second_string = 'olhe'
print(check_string(first_string, second_string))
# prints True
first_string = 'helo'
second_string = 'hello'
print(check_string(first_string, second_string))
# prints True
first_string = 'helo'
second_string = 'helofoo'
print(check_string(first_string, second_string))
# prints 'This does not work.'
I agree that you should step through that code with a debugger (maybe try PyCharm if you don't have an IDE set up yet) to see what went wrong. Would be hard to explain whats going wrong but I think it has something to do with first_element = product[0:n]. This will return increasingly larger segments of the string. i.e. 'ol' on the second run through.
Here's an alternative way of writing it
def fix_machine(debris, product):
all_present = all(letter in debris for letter in product)
return product if all_present else 'This does not work'

Python issue with replace statement?

I've been write this practice program for while now, the whole purpose of the code is to get user input and generate passwords, everything almost works, but the replace statements are driving me nuts. Maybe one of you smart programmers can help me, because I'm kinda new to this whole field of programming. The issue is that replace statement only seems to work with the first char in Strng, but not the others one. The other funcs blower the last run first and then the middle one runs.
def Manip(Strng):
#Strng = 'jayjay'
print (Strng.replace('j','h',1))
#Displays: 'hayjay'
print (Strng.replace('j','h',4))
#Displays: 'hayhay'
return
def Add_nums(Strng):
Size=len(str(Strng))
Total_per = str(Strng).count('%')
# Get The % Spots Position, So they only get replaced with numbers during permutation
currnt_Pos = 0
per = [] # % position per for percent
rGen = ''
for i in str(Strng):
if i == str('%'):
per.append(currnt_Pos)
currnt_Pos+=1
for num,pos in zip(str(self.ints),per):
rGen = Strng.replace(str(Strng[pos]),str(num),4);
return rGen
for pos in AlphaB: # DataBase Of The Positions Of Alphabets
for letter in self.alphas: #letters in The User Inputs
GenPass=(self.forms.replace(self.forms[pos],letter,int(pos)))
# Not Fully Formatted yet; you got something like Cat%%%, so you can use another function to change % to nums
# And use the permutations function to generate other passwrds and then
# continue to the rest of this for loop which will generate something like cat222 or cat333
Add_nums(GenPass) # The Function That will add numbers to the Cat%%%
print (rGen);exit()

Nested Loop 'If'' Statement Won't Print Value of Tuple

Current assignment is building a basic text adventure. I'm having trouble with the following code. The current assignment uses only functions, and that is the way the rules of the assignment state it must be done.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if selection == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"
firstResponse = 'You chose option one.'
secondResponse = 'You chose option two.'
thirdResponse = 'You chose option three.'
responses = [(0, firstResponse), (1, secondResponse),( 0, thirdResponse)]
make_selections(responses)
My intention in that code is to make it so if the user selects a 1, it will return firstResponse, if the user selects 2 it will return secondResponse, etc.
I am basically just bug testing the code to make sure it produces the appropriate response, hence the "Error man..." string, but for some reason it just loops through the error message without printing the appropriate response string. Why is this?
I know that this code is enumerating the list of tuples and I can call them properly, as I can change the code to the following and get the expected output:
for i, v in enumerate(response):
i += 1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
print i, v
Also, two quick asides before anyone asks:
I know there is currently no way to get out of this while loop. I'm just making sure each part of my code works before I move on to the next part. Which brings me to the point of the tuples.
When I get the code working, a 0 will produce the response message and loop again, asking the user to make a different selection, whereas a 1 will produce the appropriate response, break out of the loop, and move on to the next 'room' in the story... this way I can have as many 'rooms' for as long of a story as I want, the player does not have to 'die' each time they make an incorrect selection, and each 'room' can have any arbitrary amount of options and possible responses to choose from and I don't need to keep writing separate loops for each room.
There are a few problems here.
First, there's no good reason to iterate through all the numbers just to see if one of them matches selection; you already know that will be true if 1 <= selection <= len(response), and you can then just do response[selection-1] to get the v. (If you know anything about dicts, you might be able to see an even more convenient way to write this whole thing… but if not, don't worry about it.)
But if you really want to do this exhaustive search, you shouldn't print out There is an error man after any mismatch, because then you're always going to print it at least twice. Instead, you want to only print it if all of them failed to match. You can do this by keeping track of a "matched" flag, or by using a break and an else: clause on your for loop, whichever seems simpler, but you have to do something. See break and continue Statements, and else Clauses on Loops in the tutorial for more details.
But the biggest problem is that raw_input returns a string, and there's no way a string is ever going to be equal to a number. For example, try '1' == 1 in your interactive interpreter, and it'll say False. So, what you need to do is convert the user's input into a number so you can compare it. You can do that like this:
try:
selection = int(selection)
except ValueError:
print "That's not a number!"
continue
Seems like this is a job for dictionaries in python. Not sure if your assignment allows this, but here's my code:
def make_selections(response):
selection = raw_input('-> ')
print response.get(selection, err_msg)
resp_dict = {
'1':'You chose option one.',
'2':'You chose option two.',
'3':'You chose option three.'
}
err_msg = 'Sorry, you must pick one of these choices: %s'%sorted(resp_dict.keys())
make_selections(resp_dict)
The problem is that you are comparing a string to an integer. Selection is raw input, so it comes in as a str. Convert it to an int and it will evaluate as you expect.
You can check the type of a variable by using type(var). For example, print type(selection) after you take the input will return type 'str'.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if int(selection) == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"

Categories