Making dictionary item frequency - python

I want to know why it's not counting the element ?
I made an key then in each iteration it should increase the value.
def isAnagram( s, t):
if len(s) != len(t):
return False
d_1 = {}
d_2 = {}
for i in range(len(s)):
d_1[s[i]] =+ 1
d_2[t[i]] =+ 1
print(d_1)
print(d_2)
return True if d_1 == d_2 else False
s = 'aabb'
t = 'bbaa'
print(isAnagram(s,t))
OUTPUT :
d_1 = {'a': 1, 'b': 1}
d_2 = {'b': 1, 'a': 1}

First, you have an error, to add value to the variable you need to do
d_1[s[i]] += 1
d_2[t[i]] += 1
Second, the function fails because you need to define the key and value before modifying the value.
Working function:
def isAnagram( s, t):
if len(s) != len(t):
return False
d_1 = {}
d_2 = {}
for i in range(len(s)):
try: # checking if the character in the dictionary exists
d_1[s[i]]
except KeyError:
d_1[s[i]] = 0
try: # checking if the character in the dictionary exists
d_2[t[i]]
except KeyError:
d_2[t[i]] = 0
d_1[s[i]] += 1
d_2[t[i]] += 1
print(d_1)
print(d_2)
return True if d_1 == d_2 else False
s = 'aabb'
t = 'bbaa'
print(isAnagram(s,t))

as mentioned in comments. you should use += instead of =+.
+= means adding the value to the previous value stored. while
=+ here means = (assigning the value)
def isAnagram(s, t):
if len(s) != len(t):
return False
d_1 = {}
d_2 = {}
for i in range(len(s)):
d_1[s[i]] += 1
d_2[t[i]] += 1
print(d_1)
print(d_2)
return True if d_1 == d_2 else False
s = 'aabb'
t = 'bbaa'
print(isAnagram(s,t))

add a .lower() to Domagoj's answer to be case-insensitive.
so this will also work:
s = 'Betrug'.lower()
t = 'Erbgut'.lower()
{'b': 1, 'e': 1, 't': 1, 'r': 1, 'u': 1, 'g': 1}
{'e': 1, 'r': 1, 'b': 1, 'g': 1, 'u': 1, 't': 1}
True

Don’t reinvent the wheel!
from collections import Counter
def isAnagram(s, t):
return Counter(s) == Counter(t)
s = "aabb"
t = "bbaa"
print(isAnagram(s,t)) # => True

Related

Debugging code for Roman to Integer on leetcode

I decided to do the Roman to Integer leetcode in python 3, however I can't get my code to pass all of their tests. I'm getting 3583/3999 passed tests.
here's my code:
class Solution:
def romanToInt(self, s: str) -> int:
count = 0
if "IV" in s:
count += 4
s = s.replace("IV", "")
elif "IX" in s:
count += 9
s = s.replace("IX", "")
elif "XL" in s:
count += 40
s = s.replace("XL", "")
elif "XC" in s:
count += 90
s = s.replace("XC", "")
elif "CD" in s:
count += 400
s = s.replace("CD", "")
elif "CM" in s:
count += 900
s = s.replace("CM", "")
for c in s:
if c == 'I':
count += 1
elif c == 'V':
count += 5
elif c == 'X':
count += 10
elif c == 'L':
count += 50
elif c == 'C':
count += 100
elif c == 'D':
count += 500
elif c == 'M':
count += 1000
return count
not totally sure what's wrong, I'm aware this isn't the most efficient way of doing it, but I just want to get the code to work
I tried debugging it and changed some things around.

Get NameError when printing out the result, but I've assigned a variable to it

seq = 'TGCCTTGGGCACCATGCAGTACCAAACGGAACGATAGTG'
for nucleotide in seq:
if nucleotide == 'A':
a_nt = seq.count('A')
elif nucleotide == 'G':
g_nt = seq.count('G')
elif nucleotide == 'C':
c_nt = seq.count('C')
elif nucleotide == 'T':
t_nt = seq.count('T')
elif nucleotide == 'N':
n_nt = seq.count('N')
else:
sys.exit("Did not code")
print(a_nt, g_nt, c_nt, t_nt, n_nt)
Error:
NameError: name 'n_nt' is not defined. Did you mean: 'a_nt'?
If the nucleotide is not in 'AGCTN', sys.exit("no this code").
Even counts of N is zero, it should be printed out.
If I print out a, g, c, and t, it works well. But n_nt is not working.
Just count everything without the for loop, then all variables are set, even if zero:
seq = 'TGCCTTGGGCACCATGCAGTACCAAACGGAACGATAGTG'
a_nt = seq.count('A')
g_nt = seq.count('G')
c_nt = seq.count('C')
t_nt = seq.count('T')
n_nt = seq.count('N')
print(a_nt, g_nt, c_nt, t_nt, n_nt)
# or more efficient
from collections import Counter
counts = Counter(seq)
for letter in 'AGCTN':
print(counts[letter], end=' ')
Output:
11 11 10 7 0
11 11 10 7 0
I suggest using collections.Counter
from collections import Counter
possible_nucleotides = ["A", "G", "C", "N", "T"]
seq = "TGCCTTGGGCACCATGCAGTACCAAACGGAACGATAGTG"
seq_counts = Counter(seq)
missing_nucleotides = {x: 0 for x in set(possible_nucleotides) - set(seq_counts.keys())}
seq_counts.update(missing_nucleotides)
then seq_counts will look like this:
Counter({'G': 11, 'A': 11, 'C': 10, 'T': 7, 'N': 0})
Keep in mind that updating Counter is purely optional as trying to access specific key will return 0 if not present

How to sort dictionary values from Highest to lowest?

My question would be how I withdraw winner based on highest score?
since u cant sort in dictionaries
i tried this with lists, but then name wouldnt appear, only the score...
a = {'name_a':0}
b = {'name_b':0}
c = {'name_c':0}
d = {'name_d':0}
e = {'name_e':0}
print("Each time someone scores a point, the letter of his name is typed in lowercase. If someone loses a point, the letter of his name is typed in uppercase")
score = input('Enter series of charachters indicating who scored a poitn: ')
for i in score:
if i == 'a':
a['name_a'] += 1
if i == 'A':
a['name_a'] -= 1
if i == 'b':
b['name_b'] += 1
if i == 'B':
b['name_b'] -= 1
if i == 'c':
c['name_c'] += 1
if i == 'C':
c['name_c'] -= 1
if i == 'd':
d['name_d'] += 1
if i == 'D':
d['name_d'] -= 1
if i == 'e':
e['name_e'] += 1
if i == 'E':
e['name_e'] -= 1
print(a,b,c,d,e)
print('Winner is: ', )
This will work:
max((i, name) for d in (a,b,c,d,e) for name, i in d.items())[1]
you probably want to use a single dict, instead of one for each, like such:
scores = {
'a': 0,
'b': 0,
'c': 0,
'd': 0,
'e': 0,
}
And then you can keep track of the highest scoring player as points are calculated:
point_scored = input('Enter series of charachters indicating who scored a point: ')
for i in point_scored:
if not scores.get(i) is None:
scores[i] += 1
elif not scores.get(i.lower()) is None:
scores[i.lower()] -= 1
else:
print(str(i) + ' is not a valid player...')
winner = max(scores, key=scores.get)
print(scores)
print('Winner is ' + winner)
max_key = ""
max_val = 0
for key, value in d.items():
if (value > max_val):
max_val = value
max_key = key
Is this what you mean?
i found the answer
winner = (sorted(d.items(), key = lambda x: int(x[1]), reverse = True))

Change money with python dynamic programming

Here are two programs for change money problem. The first one is only a recursion program that get all combinations and the second one is using dynamic programming. HOWEVER, i get into trouble when I am working on second one. It is supposed to be faster than the first one, but my program runs FOREVER to do it. I am pretty sure that I am using the dynamic programming, but i don't know what's the problem in it?
Notes: Total is the money going to be changed, units is a list with different values and stored is a dictionary to store the value of a step.
First:
def changeMoney(total, units):
if ( total == 0 ):
return [{}]
elif ( total < 0 ):
return []
else:
n = len(units)
ret = []
for i in range(0,n):
sols = changeMoney(total-units[i],units[i:n])
for sol in sols:
if ( units[i] in sol ):
sol[units[i]] += 1
else:
sol[units[i]] = 1
ret.append(sol)
return ret
print(dpChangeMoney(300,[100,50,20,10,5,2,1],{}))
Second:
import copy
def dpChangeMoney(total, units, stored):
key = ".".join(map(str,[total] + units))
if key in stored:
return stored[key]
else:
if ( total == 0 ):
return [{}]
elif ( total < 0 ):
return []
else:
n = len(units)
for i in range(0,n):
sols = copy.deepcopy(dpChangeMoney(total-
units[i],units[i:n], stored))
for sol in sols:
if ( units[i] in sol ):
sol[units[i]] += 1
else:
sol[units[i]] = 1
if key in stored:
if sol not in stored[key]:
stored[key] += [sol]
else:
stored[key] = [sol]
return stored[key]
print(dpChangeMoney(300,[100,50,20,10,5,2,1],{}))
Here's a much faster way to do this:
def dpChangeMoney(total, units, stored, min_ix=0):
if total < 0:
return []
if total == 0:
return [{}]
if min_ix == len(units):
return []
key = (total, min_ix)
if key in stored:
return stored[key]
sol_list = []
u = units[min_ix]
for c in range(total // u + 1):
sols = dpChangeMoney(total - c*u, units, stored, min_ix + 1)
for sol in sols:
if c > 0:
sol2 = sol.copy()
sol2[u] = c
else:
sol2 = sol
sol_list.append(sol2)
stored[key] = sol_list
return sol_list
If invoked as follows, it prints the number of solutions for the specified case:
print(len(dpChangeMoney(300, [100,50,20,10,5,2,1], {})))
The result is:
466800
On my system this took well under a second to run. (Of course, you could print the actual solutions, but there are a lot!)
To see the actual solutions for a total of 10:
print(dpChangeMoney(10, [100,50,20,10,5,2,1], {}))
The result is:
[{1: 10}, {1: 8, 2: 1}, {1: 6, 2: 2}, {1: 4, 2: 3}, {1: 2, 2: 4}, {2: 5}, {1: 5, 5: 1}, {1: 3, 2: 1, 5: 1}, {1: 1, 2: 2, 5: 1}, {5: 2}, {10: 1}]
i just figure out what is the problem in my algorithm. I will update a much faster algorithm after the due date. Thanks for your suggestions and instructions. E

Recursive code to create small shift dictionary

I have the following attempt at a recursive function to create a shift table within a dictionary:
def createShiftTable(alphabet,T,shiftT):
if not T:
for char in alphabet:
shiftT[char] = len(T)+1
return shiftT
else:
return createShiftTable(alphabet,T[1:],shiftT)
shiftT[T[0]] = len(T)
al=['a','b','c','d']
T = "aaabbdddaaba"
print(createShiftTable(al,T,{}))
This is returning {'a': 1, 'c': 1, 'b': 1, 'd': 1}
I'd like it to return {'a': 1, 'c': 13, 'b': 2, 'd': 5}
Non-recursively the following works ok but how do I get the above recursive function working?
def createShiftTableX(alphabet,T):
shiftT={}
for char in al:
shiftT[char] = len(T)+1
for i in range(len(T)):
shiftT[T[i]] = len(T)-i
return shiftT
al=['a','b','c','d']
T = "aaabbdddaaba"
print(createShiftTableX(al,T))
How about this:
def createShiftTableX(alphabet, T):
l = len(T)
for c in alphabet:
i = T.find(c)
if i<0:
yield l
else:
yield i+1
al=['a','b','c','d']
T = "aaabbdddaaba"
print(list(createShiftTableX(al,T)))
You should run this in a debugger or put in some logging or print statements to see what it is actually doing.

Categories

Resources