Pythonic way to construct data structures [closed] - python

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I have implemented the following code which works perfectly without any problem. But I am not satisfied with it because it doesn't look pretty? More than anything I feel like it doesn't look like pythonic way to do it.
So I thought I ll take suggestions from the stackoverflow community. This metod is getting its data from sql query which is in another method that method return a dictionary and based the data in that dictionary I am doing pattern match and counting process. I would like to do this in a pythonic way and return a better data structure.
Here is the code:
def getLaguageUserCount(self):
bots = self.getBotUsers()
user_template_dic = self.getEnglishTemplateUsers()
print user_template_dic
user_by_language = {}
en1Users = []
en2Users = []
en3Users=[]
en3Users=[]
en4Users=[]
en5Users=[]
en_N_Users=[]
en1 = 0
en2 = 0
en3 = 0
en4 = 0
en5 = 0
enN = 0
lang_regx = re.compile(r'User_en-([1-5n])', re.M|re.I)
for userId, langCode in user_template_dic.iteritems():
if userId not in bots:
print 'printing key value'
for item in langCode:
item = item.replace('--','-')
match_lang_obj = lang_regx.match(item)
if match_lang_obj is not None:
if match_lang_obj.group(1) == '1':
en1 += 1
en1Users.append(userId)
if match_lang_obj.group(1) == '2':
en2 += 1
en2Users.append(userId)
if match_lang_obj.group(1) == '3':
en3 += 1
en3Users.append(userId)
if match_lang_obj.group(1) == '4':
en4 += 1
en4Users.append(userId)
if match_lang_obj.group(1) == '5':
en5 += 1
en5Users.append(userId)
if match_lang_obj.group(1) == 'N':
enN += 1
en_N_Users.append(userId)
else:
print "Group didn't match our regex: " + item
else:
print userId + ' is a bot'
language_count = {}
user_by_language['en-1-users'] = en1Users
user_by_language['en-2-users'] = en2Users
user_by_language['en-3-users'] = en3Users
user_by_language['en-4-users'] = en4Users
user_by_language['en-5-users'] = en5Users
user_by_language['en-N-users'] = en_N_Users
user_by_language['en-1'] = en1
user_by_language['en-2'] = en2
user_by_language['en-3'] = en3
user_by_language['en-4'] = en4
user_by_language['en-5'] = en5
user_by_language['en-n'] = enN
return user_by_language

You can avoid all these lists and add the data directly to the user_by_language dict.
I would define it as:
user_by_language = collections.defaultdict(list)
After matching the regex, just do this:
user_by_language['en-%s-users' % match_lang_obj.group(1)].append(userId)
In the end, you grab all the lengths of these elements and save them as en-1, en-2...

Related

Solving Google Code Jam 2022 "Chain Reaction" [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 days ago.
Improve this question
I´m trying to solve this problem from the Qualification Round of the contest. It successfully solves the sample, but I receive a WA (Wrong Answer) for the cases. Can anyone figure out what is wrong with my code?
I tried my best looked solutions on google, but I could not find any difference between my code and the code of other contestants.
offline = True
if(offline):
f = open("Input")
f = f.read()
f = f.split("\n")
numCases = int(f[0])
readingLine = 1
else:
numCases = int(input())
myFun = []
IPointTo = []
pointsToMe = [[] for _ in range(1)]
def greater(a,b):
if(a>b): return a
return b
def fun(i):
#Returns a pair [fun, max]
#fun = a + b
# a = fun is the sum of the fun() of all children, except the one with the lowest max
# b = greater(fun of myself, max of the child with the lowest max)
# "max" is the value greater(myfun, max of the child with lowest max)
global myFun,IPointTo,pointsToMe
if (pointsToMe[i].__len__() == 0): return [myFun[i],myFun[i]]
a = 0
for j in range(pointsToMe[i].__len__()):
child = pointsToMe[i][j]
aux = fun(child)
a += aux[0]
if(j==0 or aux[1] < lowestMax):
funOfTheChildWithLowestMax = aux[0]
lowestMax = aux[1]
a -= funOfTheChildWithLowestMax
b = greater(myFun[i],lowestMax)
return [a+b,greater(myFun[i],lowestMax)]
for case in range(numCases):
myFun = []
IPointTo = []
for i in range(3):
if(offline):
line = f[readingLine]
readingLine += 1
else:
line = input()
if(i==0):
N = int(line)
if(i==1):
line = line.split(" ")
for x in line: myFun.append(int(x))
if(i==2):
line = line.split(" ")
for x in line: IPointTo.append(int(x)-1)
pointsToMe = [[] for _ in range(N)]
for i in range(N):
if(IPointTo[i] != -1): pointsToMe[IPointTo[i]].append(i)
sum = 0
for i in range(N):
if(IPointTo[i] == -1):
aux = fun(i)
sum += aux[0]
print("Case #{}: {}".format(case + 1, sum))

How do i check if 2 sentences are similar in my chatbot

I made the simplest kind of chatbot possible. Its one that answers your questions depending on what you wanted it to answer to the same question before. The code is kinda like this:
question = []
answer = []
qcount = 0
stop = 0
b = 0
while stop == 0:
b = 0
q = input("Ask me anything: ")
if q == "stop":
exit()
for i in range(qcount):
if q == question[i]:
b = 1
print(answer[i])
if b == 0:
question.append(q)
qcount = qcount + 1
a = input("How should i answer that? ")
answer.append(a)
Is there a way of turning
if q == question[i]
to
if q is similar to question[i]
?
Aryan Mishra already provided you the answer. I have similar answer for you. You can try this as well. You dont need counters and exit statements. You can define the while statement itself as a gate keeper.
I made some more improvements. While this will NOT give you a perfect chatbot, it comes closer.
question = []
answer = []
q = input("Ask me anything: ")
while q.lower() != 'stop':
i = -1
z = q.lower().split()
z.sort()
for x in question:
y = x.split()
y.sort()
if all(elem in y for elem in z):
i = question.index(x)
if i >= 0:
print(answer[i])
else:
question.append(q.lower())
a = input("How should i answer that? ")
answer.append(a)
q = input("Ask me anything: ")
Output:
Ask me anything: What is your Name
How should i answer that? Joe
Ask me anything: What your name
Joe
Ask me anything: name
Joe
Ask me anything: your name
Joe
Ask me anything: what name
Joe
Ask me anything: what is name
Joe
As you can see, when you ask "what is name" it still assumes you are asking what is your name. You need to work with this to get to a more sophisticated bot. Hope this helps you move in the right direction.
My previous answer is also posted here. Since we are comparing a string to a list, it has to an exact match. checking for q in question does not really give you an advantage. You will need to split the words and compare them. Thats what I did in my new response (see above)
question = []
answer = []
q = input("Ask me anything: ")
while q.lower() != 'stop':
if q.lower() in question:
i = question.index(q.lower())
print (answer[i])
else:
question.append(q.lower())
a = input("How should i answer that? ")
answer.append(a)
q = input("Ask me anything: ")
To Make A Fuzzy Finder Do This By Replacing if q == question[i] to if q in question[i] this does not look for a specific word but looks for a keyword
question = []
answer = []
qcount = 0
stop = 0
b = 0
while stop == 0:
b = 0
q = input("Ask me anything: ")
if q == "stop":
exit()
for i in range(qcount):
if q in question[i]: # HERE IS THE ANSWER
b = 1
print(answer[i])
if b == 0:
question.append(q)
qcount = qcount + 1
a = input("How should i answer that? ")
answer.append(a)

how to fix infinite " " printing on While statement? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
im trying to code this caesar cipher decoder, but whenever the input message has any " "(spaces) it just print " " infinitely
[ps: just started coding]
already tried to change -if- to check if meslist[x] is equal to " ", but it doesent seems like a "valid" thing
here is the code:
import string
letras = list(string.ascii_lowercase)
message = input("qual sua menssagem codificada?")
cod = input("qual a numeração da cifra?")
meslist = list(message)
trans = True
num = len(meslist)
x = 0
while trans:
if num > x:
if meslist[x] in letras:
a = letras.index(meslist[x])
print(letras[a + 2])
x = x + 1
trans = True
else:
print(" ")
trans = True
elif num == 0:
trans = False'
just expecting for it to print it the right way.
I fixed the code as below :
while trans:
if num > x:
if meslist[x] in letras:
a = letras.index(meslist[x])
print(letras[a + 2])
x = x + 1
trans = True
else:
print(" ")
trans = True
# to increase x by 1, to take the next char. in the next loop
x = x + 1
# num == x means the end of the loop
elif num == x:
trans = False

Python class variable in recursion function [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
class Solution(object):
def decode(self, s):
sub_s = ""
while self.i < len(s) and s[self.i] != "]":
if not s[self.i].isdigit():
sub_s += s[self.i]
self.i += 1
else:
n = 0
while self.i < len(s) and s[self.i].isdigit():
n = n * 10 + int(s[self.i])
self.i += 1
self.i += 1
seq = self.decode(s)
self.i += 1
sub_s += seq * n
return sub_s
def decodeString(self, s):
self.i = 0
return self.decode(s)
I'm working on leetcode problem 394 decoding string problem the problem is to convert a string.
s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
The above solution is a Python version which was translated from author bluedawnstar cpp solution.
self.i is maintaining the global state throughout the recursion, is there a more Pythonic way to maintaining such variable instead using self?
You can use the following function instead with no need for a class variable:
def decode(s):
repeat = output = ''
index = 0
while index < len(s):
char = s[index]
index += 1
if char.isdigit():
repeat += char
elif char == '[':
substring, offset = decode(s[index:])
output += substring * int(repeat)
index += offset
repeat = ''
elif char == ']':
break
else:
output += char
return output, index
def decodeString(s):
return decode(s)[0]
so that:
print(decodeString("3[a]2[bc]"))
print(decodeString("3[a2[c]]"))
print(decodeString("2[abc]3[cd]ef"))
outputs:
aaabcbc
accaccacc
abcabccdcdcdef
That's a perfectly fine way to do it.
But it isn't really "global"; it's restricted to that class instance. If you have two instances of the class, each will have their own separate copy of self.i.

How could I write this function the pythonic way? [duplicate]

I have a string like '....(((...((...' for which I have to generate another string 'ss(4)h5(3)ss(3)h2(2)ss(3)'.
'.' corresponds to 'ss' and the number of continous '.' is in the bracket.
'(' corresponds to 'h5' and the number of continuos '(' is in the bracket.
Currently I'm able to get the output 'ss(4)h5(3)ss(3)' and my code ignores the last two character sequences.
This is what I have done so far
def main():
stringInput = raw_input("Enter the string:")
ssCount = 0
h5Count = 0
finalString = ""
ssString = ""
h5String = ""
ssCont = True
h5Cont = True
for i in range(0, len(stringInput), 1):
if stringInput[i] == ".":
h5Cont = False
if ssCont:
ssCount = ssCount + 1
ssString = "ss(" + str(ssCount) + ")"
ssCont = True
else:
finalString = finalString + ssString
ssCont = True
ssCount = 1
elif stringInput[i] == "(":
ssCont = False
if h5Cont:
h5Count = h5Count + 1
h5String = "h5(" + str(h5Count) + ")"
h5Cont = True
else:
finalString = finalString + h5String
h5Cont = True
h5Count = 1
print finalString
main()
How to modify the code to get the desired output?
I don’t know about modifying your existing code, but to me this can be done very succinctly and pythonically using itertools.groupby. Note that I’m not sure if the 'h2' in your expected output is a typo or if it should be 'h5', which I’m assuming.
from itertools import chain, groupby
string = '....(((...((...'
def character_count(S, labels): # this allows you to customize the labels you want to use
for K, G in groupby(S):
yield labels[K], '(', str(sum(1 for c in G)), ')' # sum() counts the number of items in the iterator G
output = ''.join(chain.from_iterable(character_count(string, {'.': 'ss', '(': 'h5'}))) # joins the components into a single string
print(output)
# >>> ss(4)h5(3)ss(3)h5(2)ss(3)
#Kelvin 's answer is great, however if you want to define a function yourself, you could do it like this:
def h5ss(x):
names = {".": "ss", "(": "h5"}
count = 0
current = None
out = ""
for i in x:
if i == current:
count += 1
else:
if current is not None:
out += "{}({})".format(names[current], count)
count = 1
current = i
if current is not None:
out += "{}({})".format(names[current], count)
return out

Categories

Resources