Let me expalain what the real problem is.
i am having two strings :
str1="QKHE=K"
str2="Qkhek" #this string donot have '=' inthe same index 'k' is here.
i wanted to match the two strings and the desire result should be like
result="Qkhe=k"#case sensitive
i tried my function :
def matchCap(cap1=None,cap2=None):
if cap1==None or cap2==None:
return cap1
else:
cap1=list(cap1)
cap2=list(cap2)
dictionary = (zip(cap1, cap2))
print(list(dictionary))
final_cap=[]
for key, value in dictionary:
if key=='#' or key=='=':
final_cap.append(key)
else:
final_cap.append(value)
final_cap=''.join(final_cap)
return final_cap
But the zip function not workingwell because of different lengths of list.
so basically i am having two string ..amm like two captcha answers . Gave captcha example for the case sensitive .
i want the result captcha answer is Qkhe=k
One thing you can do is, when you encounter # or = in the string, you can append both the key and value, like this...
def matchCap(cap1=None,cap2=None):
if cap1==None or cap2==None:
return cap1
else:
cap1, cap2 = list(cap1), list(cap2)
dictionary = (zip(cap1, cap2))
final_cap = []
for key, value in dictionary:
if key in ('#', '='):
final_cap.append(key)
final_cap.append(value)
else:
final_cap.append(value)
final_cap = ''.join(final_cap)
return final_cap
print(matchCap("QKHE=K","Qkhek"))
Output:-
Qkhe=k
str1="QKHE=K"
str2="Qkhek"
def matchCap(cap1=None,cap2=None):
if cap1==None or cap2==None:
return cap1
else:
cap1=list(cap1)
cap2=list(cap2)
final_cap=[]
cap_2_i = 0
for cap_1 in range(len(cap1)):
key = cap1[cap_1]
value = cap2[cap_2_i]
if key=='#' or key=='=':
final_cap.append(key)
else:
final_cap.append(value)
cap_2_i += 1
final_cap=''.join(final_cap)
return final_cap
matchCap(str1, str2)
Result: 'Qkhe=k'
You don't need to use zip, just for iterates through it.
Define a variable i that represents the index position of the value from cap2, and i is accumulated each time a value is taken from cap2.
def matchCap(cap1=None, cap2=None):
if cap1 is None or cap2 is None:
return cap1
else:
total_len = len(cap2)
i = 0
final_cap = []
for index, value in enumerate(cap1):
if value == '#' or value == '=':
final_cap.append(value)
else:
final_cap.append(cap2[i])
i += 1
if i >= total_len:
break
final_cap = ''.join(final_cap)
return final_cap
print(matchCap("QKHE=K", "Qkhek"))
# Qkhe=k
Related
testdeck = ['rock']
finaldeck = ['apple','banana','napalm','ice',5,6,7,8]
def deckhelp(testdeck,finaldeck):
testnumber = 0
testlength = len(testdeck)
for index, (card, item) in enumerate(zip(testdeck, finaldeck)):
if isinstance(item, int): #checks if item is an integer
finaldeck[index] = card
print(finaldeck)
testnumber += 1
if testnumber == testlength:
print('done')
pass
deckhelp(testdeck,finaldeck)
I want rock to replace the 5 located in finaldeck, can't seem to make it happen
This is not an appropriate use of zip() because you only want to iterate through testdeck when you reach the integers in finaldeck.
You also need to use return, not pass, to end the function when you reach the end of testdeck.
def deckhelp(testdeck, finaldeck):
testindex = 0
testlength = len(testdeck)
for index, item in enumerate(finaldeck):
if isinstance(item, int):
finaldeck[index] = testdeck[testindex]
testindex += 1
if testindex == testlength:
print('done')
return
Zip only works in testdeck and finaldeck have the same length. Instead, you can use something like this:
def deckhelp(testdeck, finaldeck):
replace_index = 0
for i, val in enumerate(finaldeck):
if isinstance(val, int):
finaldeck[i] = testdeck[replace_index]
replace_index += 1
if replace_index == len(testdeck):
print("done")
return
So I wrote this code with the help of Stack Overflow users that transfers points to an individual based on whether "++" or "--" appears behind an individual.
def get_name(input):
return input.replace("+", "").replace("-", "")
def keep(actions: list):
g = {}
for s in actions:
if '->' in s:
names = s.split('->')
g[names[1]] = g[names[0]]
g[names[0]] = 0
else:
name = get_name(s)
if name not in g:
g[name] = 0
if "++" in s:
g[name] += 1
if "--" in s:
g[name] -= 1
return {x:g[x] for x in g if g[x] != 0}
print(keep(["Jim++", "John--", "Jeff++", "Jim++", "John--", "John->Jeff",
"Jeff--", "June++", "Home->House"]))
So most of the program is alright, however, when I put "Home->House" into it, it returns a KeyError. I kinda understand why it does that, but I'm clueless as to how to fix that...
I tried browsing the internet for solutions but all they recommended was to use .get(), which doesn't really help me solve the issue.
How can I make my output just neglect if like an element doesn't have "++" or "--" in it... like how can I make sure if an input is just "Jim" instead of "Jim++" or "Jim--", the function would just neglect it...
So in my example, if the input for keep is
["Jim++", "John--", "Jeff++", "Jim++", "John--", "John->Jeff", "Jeff--", "June++", "Home->House "]
the output would be
{'Jeff': -2, 'June': 1, 'Jim': 2}
instead of KeyError
You get KeyError because g[names[1]] = g[names[0]] is trying to access element in dictionary that isn't there. You get the same issue with simple print(keep(["John->Jeff"])), because there are no ++ or -- actions executed first to initialise those keys ("John" and "Jeff" in g
Based on your desired output you want to ignore such actions that are for non existing keys.
Add if names[1] in g and names[0] in g: into your keep implementation i.e.
Edit: also g[names[1]] = g[names[0]] needs to change to g[names[1]] += g[names[0]] to product correct outcome.
def get_name(input):
return input.replace("+", "").replace("-", "")
def keep(actions: list):
g = {}
for s in actions:
if "->" in s:
names = s.split("->")
if names[1] in g and names[0] in g:
g[names[1]] += g[names[0]]
g[names[0]] = 0
else:
name = get_name(s)
if name not in g:
g[name] = 0
if "++" in s:
g[name] += 1
if "--" in s:
g[name] -= 1
return {x: g[x] for x in g if g[x] != 0}
In your code, when you get Home->House, it's the first appearence of both the keys. That's why you get KeyError when you try to execute g[names[1] = g[names[0]]: g[names[0]] is g['Home'], but this entry doesn't exist in your dict. You can simply solve swapping the order of the lines:
if '->' in s:
names = s.split('->')
g[names[0]] = 0
g[names[1]] = g[names[0]]
To neglect strings which haven't the "++" or the "--", you can simply add an if before performing get_name(s):
else:
if '++' in s or '--' in s:
name = get_name(s)
if name not in g:
g[name] = 0
if "++" in s:
g[name] += 1
if "--" in s:
g[name] -= 1
This code returns the expected output
Your code actually does ignore examples which do not include "++" or "--" in the else-section of your function.
The KeyError occurs because neither "Home" nor "House" appear in the List of input strings before you try to move the entry of "Home" into the entry of "House". Because the keys "Home" and "House" are not in your dictionary g you get a KeyError.
Below is a solution which does what you want.
def get_name(input):
return input.replace("+", "").replace("-", "")
def keep(actions: list):
g = {}
for s in actions:
if '->' in s:
names = s.split('->')
if names[0] in g.keys() and names[1] in g.keys():
g[names[1]] = g[names[0]] + g[names[1]]
g[names[0]] = 0
else:
name = get_name(s)
if name not in g:
g[name] = 0
if "++" in s:
g[name] += 1
if "--" in s:
g[name] -= 1
return {x:g[x] for x in g if g[x] != 0}
print(keep(["Jim++", "John--", "Jeff++", "Jim++", "John", "John--", "John->Jeff",
"Jeff--", "June++", "Home->House"]))
I added a check to make sure the keys exist in dict d when the input string includes a "->".
In order to get the output you indicated in your question, which includes 'Jeff': -2, you also need to make sure to add the value of the original key to the value of the new key. This is done in line
g[names[1]] = g[names[0]] + g[names[1]]
Otherwise the output will say 'Jeff': -3 as the input string "Jeff++" will be ignored.
I am trying to count the 'name' keys in this nested composed dict-list and i am getting 3 in place of 6 ,i think my problem is with the base case in the recursive function count_elem(tree)
def define_tree3():
tree3 ={'name':'GAS','grade':0.8,'children':[{'name':'CSA','grade':0.5,'children':[{'name':'MB','grade':0.1},{'name':'TA','grade':0.6}]},{'name':'IIW','grade':0.9,'children':[None,{'name':'IP','grade':0.99}]}]}
return tree3
#this fuction is to delete the given key from the given dict and retur the new dict
def delkey(dict1,key):
d=dict(dict1)
del d[key]
return d
#this function is to count the numbers of 'name'
def count_elem(tree):
if len(tree)==0:
return 0
else:
for i in tree:
if i == None:
return 0
elif i == 'name':
return 1+ count_elem(delkey(tree,i))
elif i == 'grade':
return count_elem(delkey(tree,i))
elif i == 'children':
for j in tree[i]:
if j == None:
continue
else:
return count_elem(j)
a=define_tree3()
print(count_elem(a))
This is not an answer to your question. I just tried to solve it and used a different approach. Might be useful as a reference.
tree3 = {'name':'GAS','grade':0.8,'children':[{'name':'CSA','grade':0.5,'children':[{'name':'MB','grade':0.1},{'name':'TA','grade':0.6}]},{'name':'IIW','grade':0.9,'children':[None,{'name':'IP','grade':0.99}]}]}
def count_name(entity):
count = 0
name = 'name'
# print('\n')
# print(count, entity)
if type(entity) == dict:
count += sum([key == name for key in entity.keys()])
for value in entity.values():
# print(count, value)
if type(value) == list:
count += sum([count_name(member) for member in value])
return count
count_name(tree3)
I am developing a breadth-first-search algorithm for a factorization problem and am running into an interesting/confusing bug when attempting to break out of a while loop. If you run the code below, it will fail inside the "construct_path" method, stating :
File "main.py", line 96
break
SyntaxError: 'break' outside loop
but I am inside of a while loop! If anyone could give me some advice on this issue, I would really appreciate it. Thanks in advance.
from numpy import random
import itertools
import Queue
#Finding multiples, BFS problem
#Given input of list with unique integers 0 - 9 and n = range(0,1000000), calculate smallest multiple of n and unique combination of values in the list
#Example : Input : list = {0,1,2} , n = 3,
# output = 12
# Input : list = {0,1,2} , n = 50
# Output = 200
class Problem:
def __init__(self):
self.n = random.randint(0,10000000)
listSize = random.randint(1,9)
mainSet = set()
self.mainList = []
while True:
toAdd = random.randint(0,9)
if(toAdd not in self.mainList):
self.mainList.append(toAdd)
if(len(self.mainList) == listSize):
break
def get_start_state(self):
s = ''.join(map(str, self.mainList))
return int(s)
def is_goal(self, state):
return True
def get_sucessors(self):
print "Getting successors"
def breadth_first_search(problem):
# a FIFO open_set
open_set = Queue.Queue()
# an empty set to maintain visited nodes
closed_set = set()
# a dictionary to maintain meta information (used for path formation)
meta = dict() # key -> (parent state, action to reach child)
# initialize
start = problem.get_start_state()
meta[start] = (None, None)
open_set.put(start)
while not open_set.empty():
parent_state = open_set.get()
print "{} {}".format("parent_state is ", parent_state)
if problem.is_goal(parent_state):
return construct_path(parent_state, meta)
for (child_state, action) in problem.get_successors(parent_state):
if child_state in closed_set:
continue
if child_state not in open_set:
meta[child_state] = (parent_state, action)
open_set.put(child_state)
closed_set.add(parent_state)
#collect path to desired answer
def construct_path(state, meta):
action_list = list()
while True:
row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
return action_list.reverse()
x = Problem()
breadth_first_search(x)
Could be that you have a mix of tabs and spaces so that the break in line 96 looks like it is indented to be below action_list.append(action) but effectively it is below the while. That would explain the error at least.
It is just a guess. But it could be like this, using a visible tabwidth of 4 in the editor:
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
To the Python interpreter this looks like this (because it assumes a tabwidth of 8):
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
This is still valid but obviously means a different thing and would put your break outside of the while loop.
i've searched the forum and found similar questions, but no luck in solving my problem.
My code is designed to swap every two letters of each word using recursion and print the result. For words with an even amount of letters, the word "None" is included in the output and i don't know how to fix...
here's the code:
def encryptLine(line, count):
headline = line[count:]
if length(headline) > 0:
if count == length(line) - 1:
new = headline
return new
elif count <= length(line):
new = head(tail(headline)) + head(headline)
new = new + str(encryptLine(line, count+2))
return new
print(encryptLine('abcd', 0))
the output for 'abcd' is badcNone, which is correct except for the word None. the output for 'abcde' is 'badce', which is correct...
thanks in advance for your help!
Add return "" to the function definition, that is
def encryptLine(line, count):
headline = line[count:]
if length(headline) > 0:
if count == length(line) - 1:
new = headline
return new
elif count <= length(line):
new = head(tail(headline)) + head(headline)
new = new + str(encryptLine(line, count+2))
return new
return ""
Otherwise, the function will return None if length(headline) > 0 does not hold.
None is here because your function return nothing.
There is 1 case where you return nothing it is
if length(headline) <= 0:
In Python, if there is no return to a function and you try to access to a return value, the value will be None.