Sorting keys in a map - python

Program gets an input at the beginning. That inputed string can contain capital letters or any other ascii letters. We don't difference between them, so we just use lower() method. Also any letters other than letters from alphabet (numbers etc.) are used as spaces between strings. Function is supposed to analyse the input, sort it and count it.
Output:
{'idk': 2, 'idc': 1, 'idf': 1}
Input:
print(word_frequency("Idk, Idc, Idk, Idf"))
I tried this and It's sorting the input, but I can't find a way to separate strings. This is what I did:
def word_frequency(text):
f = {}
pendens = ""
for s in text:
if s.isalpha():
pendens += s
else:
pendens = pendens.lower()
if pendens != " ":
if f.get(pendens, -1) != -1:
f[pendens] += 1
else:
f[pendens] = 1
pendens = pendens.lower()
if pendens != " ":
if f.get(pendens, -1) != -1:
f[pendens] += 1
else:
f[pendens] = 1
return f
print(word_frequency("Idk, Idc, Idk, Idf"))
print(word_frequency("Idk,+Idc,Idk;;-;Idf"))
print(word_frequency("help me please"))
I'm trying to get better at coding so any form of help will be appreciated :)

The easiest solution would involve regex and Counter, which is a type of dictionary specifically tailored to counting occurrences of values like this:
>>> import re
>>> from collections import Counter
>>> words = 'Idk, Idc, Idk, Idf'
>>> re.findall('[a-z]+', words.lower())
['idk', 'idc', 'idk', 'idf']
>>> Counter(re.findall('[a-z]+', words.lower()))
Counter({'idk': 2, 'idc': 1, 'idf': 1})
If you cannot use Counter, then a plain dictionary would also work. We can use dict.get to handle words that both are and are not in the dict yet:
def count_words(words):
counts = {}
for word in re.findall('[a-z]+', words.lower()):
counts[word] = counts.get(word, 0) + 1
return counts
Results in:
>>> count_words('Idk, Idc, Idk, Idf')
{'idk': 2, 'idc': 1, 'idf': 1}
If you cannot use regex, then the problem becomes more complicated, but still doable. A generator like the following would work:
def split_words(words):
word = ''
for c in words.lower():
if 97 <= ord(c) <= 122: # ord('a') thru ord('z')
word += c
elif word:
yield word
word = ''
if word:
yield word
def count_words(words):
counts = {}
for word in split_words(words):
counts[word] = counts.get(word, 0) + 1
return counts
Results in:
>>> count_words('Idk, Idc, Idk, Idf')
{'idk': 2, 'idc': 1, 'idf': 1}

Related

Longest Common Prefix - getting runtime error

Question:
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string "".
Example 1:
Input: strs = ["flower","flow","flight"]
Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
Constraints:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] consists of only lowercase English letters.
My Code
def longestCommonPrefix(self, s: List[str]) -> str:
st=''
for i in range(len(s[0])):
ch = s[0][i]
match = True
for j in range(1,len(s)):
lj= len(s[j])
if lj<i or ch != s[j][i]:
match = False
break
if match == False:
break
else:
st+=ch
return st
Runtime Error for following Input :
Input
["ab", "a"]
Take the first element, iterate over subsequent elements and determine the longest prefix
def solution( strs):
if not strs:
return ""
res = strs[0]
i = 1
while i < len(strs):
while strs[i].find(res) != 0:
res = res[0:len(res) - 1]
i += 1
return res
# OUTPUT:
print(solution(["flower","flow","flight"])) # fl
print(solution(["dog","racecar","car"])) #
print(solution( ["ab", "a"])) # a
first, you can get all occurrences; add in dict & then can work upon that dict
You can try:
strs = ["flower","flow","flight"]
collect_dict = {}
for data in strs:
for d_index, d_data in enumerate(data):
# import pdb;pdb.set_trace()
inner_data = data[0:d_index + 1]
if inner_data not in collect_dict:
collect_dict[inner_data] = len([item for item in strs if item.startswith(inner_data)])
print(collect_dict)
keymax = max(zip(collect_dict.values(), collect_dict.keys()))[1]
print("max: " + keymax)
Output:
{'f': 3, 'fl': 3, 'flo': 2, 'flow': 2, 'flowe': 1, 'flower': 1, 'fli': 1, 'flig': 1, 'fligh': 1, 'flight': 1}
max: fl

How to iterate over string after using split function

Here is the string
ds = 'Java; Python; Ruby; SQL'
I have used slip function to split each language and found the count of one language.
if I want to find if any of 2 languages occur in a string it's returning zero.
example: in the above variable as both java and python are present it has to return count as one.
def language_both_jp(y):
count = 0
prog = (y.split(";"))
for i in range(0,len(prog)):
if(prog[i] == 'Java'):
for i in range(0,len(prog)):
if(prog[i] == 'Python'):
count += 1
return count
You could so something like this, instead use a dictionary to store the counts of each language:
ds = 'Java; Python; Ruby; SQL'
counts = {}
for chunk in ds.split(';'):
language = chunk.strip()
counts[language] = counts.get(language, 0) + 1
print(counts)
Output
{'Java': 1, 'SQL': 1, 'Python': 1, 'Ruby': 1}
A more pythonic approach will be to use collections.Counter:
from collections import Counter
ds = 'Java; Python; Ruby; SQL'
counts = Counter(language.strip() for language in ds.split(';'))
print(counts)
Output
Counter({'Java': 1, 'Ruby': 1, 'Python': 1, 'SQL': 1})
Once you have a mapping-like object with the counts of each language, iterate over the key, value pairs and output those with count above 1, for example:
from collections import Counter
ds = 'Java; Python; Ruby; SQL; Python'
counts = Counter(language.strip() for language in ds.split(';'))
for language, count in counts.items():
if count > 1:
print(language, count)
Output
Python 2
Note that the input string in the above example was slightly modified to include Python twice.
The problem is that you should be splitting by "; ", so you should have:
def language_both_jp(y):
count = 0
prog = (y.split("; "))
for i in range(0,len(prog)):
if(prog[i] == 'Java'):
for i in range(0,len(prog)):
if(prog[i] == 'Python'):
count += 1
return count
language_both_jp(ds)
#1
A simpler approach would be:
def language_both_jp(x, l):
return 1 if [i for i in ds.split("; ") if i in l] else 0
language_both_jp(ds, ['Python','Java'])
#1
your requirement is not clearly understandable...
however please try below solutions...
i. if you want to find the count of occurrence of a word just pass the string and the wordas argument..
try below code...
def language_both_jp(y, word):
count = 0
prog = (y.split(";"))
for i in range(0,len(prog)):
if(prog[i] == word):
count += 1
return count
string = 'java;python;java;python;c;python'
print(language_both_jp(string, 'java'))
it will print the count of occurrence of the word
ii. If you want to fine the occurrence of two words..
try below code..
def language_both_jp(y, word1,word2):
count1 = 0
count2 = 0
prog = (y.split(";"))
for i in range(0,len(prog)):
if(prog[i] == word1):
count1 += 1
if(prog[i] == word2):
count2 += 1
return 'occurrence of '+word1+'='+str(count1)+'\n'+'occurrence of '+word2+'='+str(count2)
args = 'java;python;java;python;c;python'
print(language_both_jp(args, 'java','python'))
iii. If you want to find the presence of any two words...
try below code
def language_both_jp(y, word1,word2):
count = ''
prog = (y.split(";"))
for i in range(0,len(prog)):
if(prog[i] == word1):
for i in range(0, len(prog)):
if(prog[i] == word2):
count = 'yes'
else:
count = 'no'
return count
args = 'java;python;java;python;c;python'
print(language_both_jp(args, 'java','python'))
please ask if you have any doubts...

Check the most frequent letter(s) in a word. Python

My task is:
To write a function that gets a string as an argument and returns the letter(s) with the maximum appearance in it.
Example 1:
s = 'Astana'
Output:
a
Example 2:
s = 'Kaskelen'
Output:
ke
So far, I've got this code(click to run):
a = input()
def most_used(w):
a = list(w)
indexes = []
g_count_max = a.count(a[0])
for letter in a:
count = 0
i = int()
for index in range(len(a)):
if letter == a[index] or letter == a[index].upper():
count += 1
i = index
if g_count_max <= count: //here is the problem.
g_count_max = count
if i not in indexes:
indexes.append(i)
letters = str()
for i in indexes:
letters = letters + a[i].lower()
return letters
print(most_used(a))
The problem is that it automatically adds first letter to the array because the sum of appearance of the first element is actually equal to the starter point of appearance(which is basically the first element).
Example 1:
s = 'hheee'
Output:
he
Example 2:
s = 'malaysia'
Output:
ma
I think what you're trying to can be much simplified by using the standard library's Counter object
from collections import Counter
def most_used(word):
# this has the form [(letter, count), ...] ordered from most to least common
most_common = Counter(word.lower()).most_common()
result = []
for letter, count in most_common:
if count == most_common[0][1]:
result.append(letter) # if equal largest -- add to result
else:
break # otherwise don't bother looping over the whole thing
return result # or ''.join(result) to return a string
You can use a dictionary comprehension with a list comprehension and max():
s = 'Kaskelen'
s_lower = s.lower() #convert string to lowercase
counts = {i: s_lower.count(i) for i in s_lower}
max_counts = max(counts.values()) #maximum count
most_common = ''.join(k for k,v in counts.items() if v == max_counts)
Yields:
'ke'
try this code using list comprehensions:
word = input('word=').lower()
letters = set(list(word))
max_w = max([word.count(item) for item in letters])
out = ''.join([item for item in letters if word.count(item)==max_w])
print(out)
Also you can import Counter lib:
from collections import Counter
a = "dagsdvwdsbd"
print(Counter(a).most_common(3)[0][0])
Then it returns:
d

using min with list properly

text = input("enter string:")
text.lower()
counta = text.count ("a")
counte = text.count ("e")
counti = text.count ("i")
counto = text.count ("o")
countu = text.count ("u")
if counta > 0:
print ("'a'",counta)
if counte > 0:
print ("'e'",counte)
if counti> 0:
print ("'i'",counti)
if counto > 0:
print ("'o'",counto)
if countu > 0:
print ("'u':",countu)
leastFreq = [counta,counte,counti,counto,countu]
leastFreq.sort()
while 0 in leastFreq: leastFreq.remove(0)
print (leastFreq)
task = count vowels in word, print least frequent vowels that occur. in this case, "potato" would print:
'a' = 1
'0' = 2
how do I make it so that it prints just 'a'? I could use min(leastFreq) but that would only return the value "1". how do I do it so that it prints using the format 'a' = 1 or if there is more than one vowel with the same number of occurences.
You could use min with an additional filter condition, testing whether the element is > 0:
>>> leastFreq = [4, 2, 1, 0, 3, 0]
>>> min(x for x in leastFreq if x > 0)
1
But this way, you lose the information what character this count belongs to. Instead of your five different variables, you could create a dictionary, mapping vowels to their respective counts:
>>> text = "potato"
>>> counts = {c: text.count(c) for c in "aeiou"}
>>> counts
{'a': 1, 'i': 0, 'e': 0, 'u': 0, 'o': 2}
>>> counts["o"]
2
And then again use min with a generator expression and a specific key function (to sort by the count, not by the vowel itself).
>>> min((c for c in counts if counts[c] > 0), key=counts.get)
'a'
If you are interested in the counts of all the letters, you could also use collections.Counter.
To minimally change your code:
leastFreq = [(counta, 'a'),(counte, 'e'),(counti, 'i'),(counto, 'o'),(countu, 'u')]
leastvowel = min(leastFreq)[1]
But you should use collections.Counter instead
from collections import Counter
text = input("Enter text: ")
c = Counter(character for character in text if character in 'aeiou') #get counts of vowels
least_frequent = c.most_common()[-1]
least_frequent will then be a tuple like ('a', 1)
EDIT: If you want all of the most frequent items you can use itertools.groupby
lestfreq=list(next(itertools.groupby(c.most_common()[::-1], key=lambda x:x[1]))[1])
This looks complicated, but all it's saying is take a list in sorted order and take all the tuples with the same second value and put them in a list.
A combination of Counter and operator might do the trick:
from collections import Counter
import operator
text = raw_input("enter string:")
freq = Counter(i for i in text if i in 'aeiou')
items = sorted(freq.items(),key=operator.itemgetter(1))
min = items[0][1]
for character,frequency in items:
if frequency == min:
print character,frequency

check if string is in abc order

So the function should count the number of times the letters in uppercase are out of abc order.
>>> abc('ABBZHDL')
2
Above, z and d are out of order.
>>> abc('ABCD')
0
>>> abc('DCBA')
4
My code:
def abc(check):
order=ABCDEFGHIJKLMNOPQRSTUVWXYZ
for c in check:
if check != order:
#then I get stuck here
Pointers?
The question is ill-defined. One solution to a nearby question would be using the builtin sorted():
def abc(s):
count = 0
s = ''.join(i for i in s if i.isupper())
l = sorted(s)
for i,c in enumerate(s):
if l[i] != c:
count += 1
return count
It counts all of the places where the alphabetized string does not match the original.
def abc(check):
last = ''
count = 0
for letter in check:
if not letter.isupper():
continue
if letter < last:
count += 1
last = letter
return count
import string
a = 'acbdefr'
b = 'abdcfe'
assert ''.join(sorted(b)) in string.ascii_letters
assert ''.join(sorted(a)) in string.ascii_letters #should fail
Its really simple everyone seems to be overcomplicating it somewhat?

Categories

Resources