Given a stringified phone number of non-zero length, write a function that returns all mnemonics for this phone number in any order.
`
def phoneNumberMnemonics(phoneNumber, Mnemonics=[''], idx=0):
number_lookup={'0':['0'], '1':['1'], '2':['a','b','c'], '3':['d','e','f'], '4':['g','h','i'], '5':['j','k','l'], '6':['m','n','o'], '7':['p','q','r','s'], '8':['t','u','v'], '9':['w','x','y','z']}
if idx==len(phoneNumber):
return Mnemonics
else:
new_Mnemonics=[]
for letter in number_lookup[phoneNumber[idx]]:
for mnemonic in Mnemonics:
new_Mnemonics.append(mnemonic+letter)
phoneNumberMnemonics(phoneNumber, new_Mnemonics, idx+1)
`
If I use the input "1905", my function outputs null. Using a print statement right before the return statement, I can see that the list Mnemonics is
['1w0j', '1x0j', '1y0j', '1z0j', '1w0k', '1x0k', '1y0k', '1z0k', '1w0l', '1x0l', '1y0l', '1z0l']
Which is the correct answer. Why is null being returned?
I am not very good at implementing recursion (yet?), your help is appreciated.
There are different recursive expressions of this problem, but the simplest to think about when you are starting out is a "pure functional" one. This means you never mutate recursively determined values. Rather compute fresh new ones: lists, etc. (Python does not give you a choice regarding strings; they're always immutable.) In this manner you can think about values only, not how they're stored and what's changing them, which is extremely error prone.
A pure-functional way to think about this problem is this:
If the phone number is the empty string, then the return value is just a list containing the empty string.
Else break the number into its first character and the rest. Recursively get all the mnemonics R of the rest. Then find all the letters corresponding to the first and prepend each of these to each member of R to make a new string (This is called a Cartesian cross product, which comes up often in recursion.) Return all of those strings.
In this expression, the pure function has the form
M(n: str) -> list[str]:
It's accepting a string of digits and returning a list of mnemonics.
Putting this thought into python is fairly simple:
LETTERS_BY_DIGIT = {
'0':['0'],
'1':['1'],
'2':['a','b','c'],
'3':['d','e','f'],
'4':['g','h','i'],
'5':['j','k','l'],
'6':['m','n','o'],
'7':['p','q','r','s'],
'8':['t','u','v'],
'9':['w','x','y','z'],
}
def mneumonics(n: str):
if len(n) == 0:
return ['']
rest = mneumonics(n[1:])
first = LETTERS_BY_DIGIT[n[0]]
rtn = [] # A fresh list to return.
for f in first: # Cartesian cross:
for r in rest: # first X rest
rtn.append(f + r); # Fresh string
return rtn
print(mneumonics('1905'))
Note that this code does not mutate the recursive return values rest at all. It makes a new list of new strings.
When you've mastered all the Python idioms, you'll see a slicker way to code the same thing:
def mneumonics(n: str):
return [''] if len(n) == 0 else [
c + r for c in LETTERS_BY_DIGIT[n[0]] for r in mneumonics(n[1:])]
Is this the most efficient code to solve this problem? Absolutely not. But this isn't a very practical thing to do anyway. It's better to go for a simple, correct solution that's easy to understand rather than worry about efficiency before you have a solid grasp of this way of thinking.
As others have said, using recursion at all on this problem is not a great choice if this were a production requirement.
The correct list (Mnemonics) was generated for the deepest call of the recursion. However, it was not passed back to previous calls.
To fix this, the Mnemonics not only needs to be returned in the "else" block, but it also needs to be set to equal the output of the recursive function phone Number Mnemonics.
def phoneNumberMnemonics(phoneNumber, Mnemonics=[''], idx=0):
number_lookup={'0':['0'], '1':['1'], '2':['a','b','c'], '3':['d','e','f'], '4':['g','h','i'], '5':['j','k','l'], '6':['m','n','o'], '7':['p','q','r','s'], '8':['t','u','v'], '9':['w','x','y','z']}
print(idx, len(phoneNumber))
if idx==len(phoneNumber):
pass
else:
new_Mnemonics=[]
for letter in number_lookup[phoneNumber[idx]]:
for mnemonic in Mnemonics:
new_Mnemonics.append(mnemonic+letter)
Mnemonics=phoneNumberMnemonics(phoneNumber, new_Mnemonics, idx+1)
return Mnemonics
I still feel that I'm lacking sophistication in my understanding of recursion. Advice, feedback, and clarifications are welcome.
The contents of the ScheduledStartDate list is either None or a string.
How can I change my codes below to detect and skip the ScheduledStartDate[j] that contains None? And only run the statements when it is not None.
j = 0
while j< len1:
if (ScheduledStartDate[j] == None):
else:
ScheduledStartDate[j] = datetime.datetime.strptime(ScheduledStartDate[j], format)
j=j+1
To my understanding this looks like it should work, however you may want to remove the else statement and just change the logic of your if statement.
j = 0
while j< len1:
if ScheduledStartDate[j] is not None:
ScheduledStartDate[j] = datetime.datetime.strptime(ScheduledStartDate[j], format)
j=j+1
If your objective is to actually remove the None values then you can see how it's done here. Otherwise there is no way to know which values are None and which are strings without going through the entire list.
Also on another note, if you'd like your code to have that nice color scheme you see in all other questions, add the python tag to the question. Makes your code easier to read.
Hoping someone can help me with just pseudocode. I can't copy the code here as it's not entirely my own.
I have a function that looks like this:
for result in results_set:
if conditionA:
# When conditionA is true, test on this_attribute.
if result.this_attribute == "interesting string":
# do things.
if result.this_attribute == "another interesting string"
# do different things.
else:
# ConditionA is false? Test on that_other_attribute instead.
if result.that_other_attribute == "interesting string"
# do the same exact things as above for "interesting string"
if result.that_other_attribute == "another interesting string"
# do the same exact things as above for "another interesting string"
It seems very inefficient to have the test for conditionA or conditionB be inside the for loop since I deal with results_sets that can be thousands of lines long. Plus the code looks bad because I'm just repeating myself.
Feels like I should be able to test for conditionA / B before the loop takes place, and tell Python what attribute of "result" to compare next based on that test.
Which attribute I test will always depend on the value of ConditionA. I may end up with a ConditionB, C or D in the near future as well which will require checking on a third, fourth or fifth attribute of result.
Currently I solved this by having two nearly identical functions that each have their own "for" without the ConditionA test inside it... but that looks bad and will become a nightmare when B, C or D roll around.
Is it possible to have an attribute placeholder somehow? If so, how please?
Edit:
I am trying to achieve something like this....
result = a filler value used only to reference attribute names
if ConditionA:
check_attribute = result.this_attribute
else:
check_attribute = result.that_other_attribute
for result in results_set:
if check_attribute == "interesting string":
# do things.
if check_attribute == "another interesting string"
# do different things.
Using getattrs might get you somewhere here, however unlikely that may sound. Right above the for loop, you could do
value_to_check = "this_attribute" if conditionA else "that_other_attribute".
Yes, those were strings.
Next, in the for loop, you could do
result_value = getattr (result, value_to_check)
if result_value == "interesting string": #thing to do
elif result_value == "another interesting string": #other thing to do
def Change(_text):
L = len(_text)
_i = 2
_text[_i] = "*"
_i += 2
print(_text)
How can I add a mark e.g:* every two Index In String
Why are you using _ in your variables? If it is for any of these reasons then you are OK, if it is a made up syntax, try not to use it as it might cause unnecessary confusion.
As for your code, try:
def change_text(text):
for i in range(len(text)):
if i % 2 == 0: # check if i = even (not odd)
print(text[:i] + "*" + text[i+1:])
When you run change_text("tryout string") the output will look like:
*ryout string
tr*out string
tryo*t string
tryout*string
tryout s*ring
tryout str*ng
tryout strin*
If you meant something else, name a example input and wished for output.
See How to create a Minimal, Complete, and Verifiable example
PS: Please realize that strings are immutable in Python, so you cannot actually change a string, only create new ones from it.. if you want to actually change it you might be better of saving it as a list for example. Like they have done here.
Are you trying to separate every two letters with an asterix?
testtesttest
te*st*te*st*te*st
You could do this using itertools.zip_longest to split the string up, and '*'.join to rebuild it with the markers inserted
from itertools import zip_longest
def add_marker(s):
return '*'.join([''.join(x) for x in zip_longest(*[iter(s)]*2, fillvalue='')])
I'm super new to python, and trying to create a very simple function to be used in a larger map coloring program.
The idea of the function is to have a set of variables attributed to different regions (string1) with colors assigned to them, (r,g,b) and then test if the regions touch another region of the same color by recursively looking through a set of region borders (string2) to find variables+colors that match.
The input format would look like this:
("Ar, Bg, Cb", "AB,CB,CA")
Would return True, meaning no two regions of the same color touch.
Here's my code segment so far:
def finding_double_char_function(string1, string2):
if string2=="":
return True
elif string2[0]+"r" and string2[1]+"r" in string1 or string1[::-1]:
return False
elif string2[0]+"g" and string2[1]+"g" in string1 or string1[::-1]:
return False
elif string2[0]+"b" and string2[1]+"b" in string1 or string1[::-1]:
return False
else:
return finding_double_char_function(string1, (string2[3:]))
I keep getting false when I expected True. Can anyone help? Thanks a lot.
You have several problems in this, but your main problem is that you don't seem to know the order of bindings in an expression. What you've written is a little more readable like this:
elif string2[0]+"r" and
((string2[1]+"r" in string1) or
string1[::-1]) :
In other words, you've used strings as boolean values. The value you get from this is not what you expected. I think what you're trying to do is to see whether either constructed string (such as "Ar") is in string 1, either forward or backward.
"in" can join only one pair of strings; there's no distributive property of "and" and "or" over "in".
Here's the first part rewritten properly:
elif (string2[0]+"r" in string1) and
(string2[1]+"r" in string1)
Does this get you going?
Also, stick in print statements to trace your execution and print out useful values along the way.
If I undestood correctly your problem could be solved like this:
def intersect(str1, str2):
if (not str2):
return True
if (str1[str1.find(str2[0]) + 1] == str1[str1.find(str2[1]) + 1]):
return False
else:
return intersect(str1, str2[3:])