I have the number 444333113333 and I want to count every different digit in this number.
4 is 3 times
3 is 3 times
1 is 2 times
3 is 4 times
What I am trying to do is make a script that translates phone keypad taps to letters
like in this photo https://www.dcode.fr/tools/phone-keypad/images/keypad.png
if I press 3 times number 2, then the letter is 'C'
I want to make a script with it in python,but I cannot...
Using regex
import re
pattern = r"(\d)\1*"
text = '444333113333'
matcher = re.compile(pattern)
tokens = [match.group() for match in matcher.finditer(text)] #['444', '333', '11', '3333']
for token in tokens:
print(token[0]+' is '+str(len(token))+' times')
Output
4 is 3 times
3 is 3 times
1 is 2 times
3 is 4 times
You can use itertools.groupby
num = 444333113333
numstr = str(num)
import itertools
for c, cgroup in itertools.groupby(numstr):
print(f"{c} count = {len(list(cgroup))}")
Output:
4 count = 3
3 count = 3
1 count = 2
3 count = 4
Will this do the trick?
the function returns a 2d list with each number and the amount it found. Then you can cycle through the list and to get each all of the values
def count_digits(num):
#making sure num is a string
#adding an extra space so that the code below doesn't skip the last digit
#there is a better way of doing it but I can't seem to figure out it on spot
#essemtially it ignores the last set of char so I am just adding a space
#which will be ignored
num = str(num) + " "
quantity = []
prev_char = num[0]
count = 0
for i in num:
if i != prev_char:
quantity.append([prev_char,count])
count = 1
prev_char = i
elif i.rfind(i) == ([len(num)-1]):
quantity.append([prev_char,count])
count = 1
prev_char = i
else:
count = count + 1
return quantity
num = 444333113333
quantity = count_digits(num)
for i in quantity:
print(str(i[0]) + " is " + str(i[1]) + " times" )
Output:
4 is 3 times
3 is 3 times
1 is 2 times
3 is 4 times
Related
So I am trying to make something that subtracts a certain amount from a string to make the 2 strings equal in length the problem is when I try to find the length of the element 1 which is stored as 0000 0000 it returns 1. Also, the code is grabbing from a file but the only relevant element is 1. Here is the code in question:
import re
insSpec2 = {}
z = 0
bool(z)
TestString = "0100 0001"
while z == 0:
f = open("Specifier", 'r')
for word in f:
i = 0
insSpec2[i] = re.split('r|a', word)
print(insSpec2[i])
insLength = len(insSpec2[i])
testLength = len(TestString)
if testLength > insLength:
diff = testLength-insLength
else:
diff = insLength-testLength
print(insLength)#returns 1
print(testLength, insLength) #returns 9 1
print(diff)#returns 8
print(insSpec2[0].__len__()) #returns 1
if insLength < testLength:
changeVar = 8 - insLength
while TestString != insSpec2:
#print(testLength)
newStr = TestString[:-diff]
#print(newStr)
elif insSpec2[i] == TestString:
print("Found Match", insSpec2[i])
z = 1
break
i += 1
That is because re.split returns a list not a string, insSpec[i] = ['0000 0000']. It has length 1
This question already has answers here:
Create nice column output in python
(22 answers)
Closed 3 years ago.
I have a list of a random word as a string and I need to count the frequency of it.
a = ['a','ccc','bb','ccc','a','ccc','bb','bb','a','bb']
I want to make it into a loop. So the output will be
1 a 3
2 bb 4
3 ccc 3
with the number is aligned in the right with 4 spaces or character in the left, elements on the list are aligned in the left with 5 characters in the left and the frequency aligned in the right like above.
I know how to count the frequency but I don't know how to arrange them
total_word = {}
for word in clear_word:
if word not in total_word:
total_word[word] = 0
total_word[word] += 1
Sorry to interrupt
There are at least two efficient ways:
from collections import Counter, defaultdict
a = ['a','ccc','bb','ccc','a','ccc','bb','bb','a','bb']
# method 1:
d = defaultdict(int)
for elem in a:
d[elem] += 1
for ctr, k in enumerate(sorted(d), start = 1):
print(ctr,k,'\t',d[k])
# method 2:
d = Counter(a)
for ctr, k in enumerate(sorted(d), start = 1):
print(ctr,k,'\t',d[k])
Output:
1 a 3
2 bb 4
3 ccc 3
EDIT:
Here you go:
a = ['a','ccc','bb','ccc','a','ccc','bb','bb','a','bb']
unique = sorted(set(a))
for ctr, i in enumerate(unique,start=1):
print(ctr,i,'\t',a.count(i))
Try this, using collections.Counter
>>> from collections import Counter
>>> i=1
>>> for k, v in Counter(a).items():
print(f"{i:<3} {k:<10} {v}")
i+=1
Output:
1 a 3
2 ccc 3
3 bb 4
If you like me occasionally have to work on python less then 2.6 you could use oldscool string-formatting like:
print "%3s %-10s %s" % (i, the_word, count)
Here:
%3s will occupy 3 characters and get you left aligned text
%-10s will occupy 10 characters and be right (the minus sign) aligned
This formatting will work in any python-version.
If it is only about string formatting, you can prepare string similarly to:
arr = ['a', 'bb', 'ccc']
for i in range(len(arr)):
print('{} {:4} {}'.format(i, arr[i], i+5))
I am using this site as a resource for string formatting https://pyformat.info/#string_pad_align
I guess this is what your want:
Try this:
clear_word = ['a','ccc','bb','ccc','a','ccc','bb','bb','a','bb','bb','bb','bb','bb','bb','bb','bb','bb','bb']
total_word = {}
for word in clear_word:
if word not in total_word:
total_word[word] = 0
total_word[word] += 1
for i, k in enumerate(total_word):
print(" {0:2} {1:3} {2:5}".format(i, k, total_word[k]))
That is output:
align output
Hi based on your code this loop display your results
for a in total_word.keys():
print(a ,'\t', total_word[a])
This my output
a 3
bb 4
ccc 3
You can align your columns using f-strings (see here to understand the :>{padding}):
padding = max(len(word) for word in total_word.keys()) + 1
for word, count in total_word.items():
print(f"{word:<{padding}}{count:>3}")
if you wanted the index as well then add in enumerate:
for idx, (word, count) in enumerate(total_word.items()):
print(f"{idx:<3}{word:<{padding}}{count:>3}")
Putting it all together:
clear_word = ['a'] * 3 + ['ccc'] * 4 + ['bb'] * 10
total_word = {}
for word in clear_word:
if word not in total_word:
total_word[word] = 0
total_word[word] += 1
padding = max(len(word) for word in total_word.keys()) + 1
for idx, (word, count) in enumerate(total_word.items()):
print(f"{idx:<3}{word:<{padding}}{count:>3}")
your output is
0 a 3
1 ccc 4
2 bb 10
I need to write a code that counts the amount of closed area's en the amount of ends within a word (so B has 2 closed area's) but when 1 character sits 2 times within 1 question it only counts 1 time.
I tried something that should count the amount of characters but that just gived me more errorzs
G = 0
Chosen_word = str(input("Choose a word of max 60 character(only uppercase)"))
if "A" in Chosen_word:
U = U + 2
G = G + 1
if you type AA it should print 4 ends en 2 closed area's but it prints 2 ends en 1 closed area
You're only going through this code once - for the first letter. To go through each letter, you need to use a loop (a for loop that goes through every character would be best here):
for letter in chosen_word:
if letter == 'A':
U = U + 2
G = G + 1
elif letter == 'B':
...
G = 0
U=0
Chosen_word = str(input("Choose a word of max 60 character(only uppercase)"))
n = Chosen_word.count("A")
U = n * 2
G = n
print (U)
print (G)
OUTPUT:
Choose a word of max 60 character(only uppercase)SADDSAAAA
10
5
Trying to simulate 20 dice throws randomly, the code needs to enclose with parenthesis a value that is the same, the parenthesis appear, but I am missing something on my formula, any advise can greatly help, eg:
1 ( 4 1 ) 2 3 6 1 4 3 2 6 6 6 5 6 2 1 3 5 3 # incorrect
1 4 1 2 3 6 1 4 3 2 ( 6 6 6 ) 5 6 2 1 3 5 3 # this is a correct example
def main():
exampleList = [ ]
for i in range(20):
exampleList.append(randint(1, 6))
print(exampleList)
print(list(range(0,20)))
max_count = 0
run_count = 0
matched = False #inRun = False
# find max run
for rollValue in exampleList:
#print(rollValue)
if run_count == 19:
print()
else:
print("-------")
print("Roll Value %s" % exampleList[run_count])
print("Position %s" % run_count)
print("Next Roll value %s" % exampleList[run_count + 1])
if exampleList[run_count] == exampleList[run_count + 1]:
matched = True
print("------->>>matched")
else:
matched = False#inRun = False
run_count += 1
if rollValue < 19:
if exampleList[rollValue] == exampleList[rollValue + 1]:
run_count += 1
if matched == False:
matched == True
run_count = rollValue
else:
matched = False
if run_count > max_count:
run_count = 1
# print sequence
for rollValue in range(20):
if rollValue == run_count:
print("(", exampleList[rollValue], end = " ")
elif rollValue == run_count + max_count + 1:
print(exampleList[rollValue], ")", end = " ")
else:
print(exampleList[rollValue], end = " ")
main()
Here is a solution using regex. This creates a string out of the dice rolls, then finds repeating digits and uses re.sub to add parenthesis.
import re
import random
rolls = ''.join(map(str, [random.choice(range(1, 7)) for _ in range(20)]))
rolls = ' '.join(re.sub(r'(\d)(\1+)', r'(\1\2)', rolls))
print(rolls)
A couple sample runs:
4 1 4 3 4 6 5 2 3 ( 5 5 ) 1 6 4 3 5 2 5 ( 4 4 )
2 ( 1 1 ) 4 1 ( 5 5 ) ( 3 3 ) 6 2 ( 1 1 ) 5 1 4 3 4 ( 5 5 )
Regex explanation:
( // start of matching group 1
\d // matches a single digit
) // end of matching group 1
( // start of matching group 2
\1+ // matches group 1, 1 or more times
) // end of matching group 2
This adds the parenthesis as part of the list:
#!/usr/bin/python
import sys
from random import randint
# add parenthesis as part of the list
def main():
exampleList = [ ]
previous = -1
opened = False
for i in range(20):
roll = randint(1, 6)
if roll == previous:
if not opened:
exampleList.insert(-1, '(')
opened = True
else:
if opened:
exampleList.append(')')
opened = False
exampleList.append(roll)
previous = roll
if opened:
exampleList.append(')')
for item in exampleList:
sys.stdout.write('{0} '.format(item))
sys.stdout.write('\n')
if __name__ == '__main__':
main()
Examples:
( 2 2 ) 4 5 1 2 1 ( 6 6 ) 1 6 1 4 1 ( 6 6 ) 1 6 2 4
2 ( 6 6 ) ( 1 1 ) 3 2 1 ( 4 4 ) 1 2 5 4 1 5 3 ( 5 5 5 )
There are a number of issues with your code, so it was just quicker to rewrite the whole thing.
def main():
example_list = []
for _ in range(20):
example_list.append(random.randint(1, 6))
inside = False
for index in range(len(example_list)):
try:
if inside:
if example_list[index] != example_list[index + 1]:
print("%d )" % example_list[index], end=" ")
inside = False
else:
print(example_list[index], end=" ")
else:
if example_list[index] == example_list[index + 1]:
print("( %d" % example_list[index], end=" ")
inside = True
else:
print(example_list[index], end=" ")
except IndexError:
print("%d" % example_list[index], end=" ")
if inside:
print(")")
else:
print()
As you can see I keep track of whether I'm inside a parenthesis by using a variable. I look to the next number to guess if I should add a closing parenthesis.
The last case is handled by a try-except.
You could also handle each number by looking forward and backward but that'd require you to add some extra condition for the try-except part so this was just
There are various ways to do this, but this is the most similar to what you were doing already. Basically just iterate over the index of your list of rolls. Each number we examine it to see if it is the same as the one before, if yes, then we increment the count and move on. If not then we add however many of that number were in the count to the output. If there was one, we write it out by itself, if more, in parenthesis.
exampleList = [randint(1, 6) for i in range(20)]
# the current number that could be a potential sequence
current = exampleList[0]
# count for the number of occurences in a sequence (often 1)
count = 1
# The string to outpu
output = ''
# Iterate over the rolls, ignoring the first one
for i in range(1, len(exampleList)):
if exampleList[i] == current:
count += 1
else:
if count > 1:
output += ('(' + count * str(current) + ')')
else:
output += str(current)
current = exampleList[i]
count = 1
# Handle final addition
if count > 1:
output += ('(' + count * str(current) + ')')
else:
output += str(current)
print(output)
Output:
64(66)15253(66)2143454(22)
The logical error is that you're confusing "the index where the run starts" with "the length of the (last) run".
You need a variable like max_run_start_index.
Look at the code:
if rollValue == run_count:
print("(", exampleList[rollValue], end = " ")
Read it back to yourself 'if the index of the next output is equal to the length of the last run, output open bracket before it'.
So if the length of the last run is 3 the longest run starts at index 3?
Surely not...
I'm not a Python coder, so you'll need to fix it yourself...
s = "bobobobobobsdfsdfbob"
count = 0
for x in s :
if x == "bob" :
count += 1
print count
i want to count how many bobs in string s, the result if this gives me 17
what's wrong with my code i'm newbie python.
When you are looping overt the string, the throwaway variable will hold the characters, so in your loop x is never equal with bob.
If you want to count the non-overlaping strings you can simply use str.count:
In [52]: s.count('bob')
Out[52]: 4
For overlapping sub-strings you can use lookaround in regex:
In [57]: import re
In [59]: len(re.findall(r'(?=bob)', s))
Out[59]: 6
you can use string.count
for example:
s = "bobobobobobsdfsdfbob"
count = s.count("bob")
print(count)
I'm not giving the best solution, just trying to correct your code.
Understanding what for each (a.k.a range for) does in your case
for c in "Hello":
print c
Outputs:
H
e
l
l
o
In each iteration you are comparing a character to a string which results in a wrong answer.
Try something like
(For no overlapping, i.e no span)
s = "bobobobobobsdfsdfbob"
w = "bob"
count = 0
i = 0
while i <= len(s) - len(w):
if s[i:i+len(w)] == w:
count += 1
i += len(w)
else:
i += 1
print (count)
Output:
Count = 4
Overlapping
s = "bobobobobobsdfsdfbob"
w = "bob"
count = 0
for i in range(len(s) - len(w) + 1):
if s[i:i+len(w)] == w:
count += 1
print (count)
Output:
Count = 6