I'm trying to write a code that will check if an inputted word can be made with the letters of another word.
So far, I have:
def is_made_from(wordA,wordB):
for l in wordA:
if wordA.count(l) <= wordB.count(l):
return True
else:
return False
I'm not sure if what I mean is being translated to code. The loop goes through every letter in wordA to check if wordB has at least the same quantity of that letter as in wordA. However, when I run a free trials, the code seems to work when it should work but it also works when it shouldn't work. For example, if I made wordA == 'whiter' and wordB == 'white', it would return True, despite wordB not having the 'r.'
At the moment you return True even if only the 1st letter matches, because if the code enters the if on the first iteration, it returns True and the loop is exited.
You are looking for something like this
def is_made_from(wordA,wordB):
for l in wordA:
if not wordA.count(l) <= wordB.count(l):
return False
return True
It works the other way round.
Pedantically-awesome version:
from collections import Counter
def is_made_from(first, second):
return len(Counter(first) - Counter(second)) == 0
(this honestly suffers from being "too clever"; calling .count() in a loop is probably more readable and performs just fine unless your words are tens of thousands of characters long)
Related
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.
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'
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()
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?!?!?"
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)))