My code doesn't allow 2 times a character (how to fix) - python

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

Related

Counting number of binary substrings of length 3+ with one unique element

Essentially, I'm given two lines of input. The first line is an integer length of the substring presented in the second line of input, consisting of only Gs and Hs, similar to 0s and 1s.
N = int(input())
chars = list(input())
lonely = 0
for i in range(3, N + 1):
for j in range(N - i + 1):
if ((chars[j:j + i].count('G') == 1) or (chars[j:j + i].count('H') == 1)):
lonely += 1
print(lonely)
An example input is:
5
GHGHG
for which the answer is 3: the answer is the number of the original string's substrings of length 3 or greater that only have one G or one H (this G or H is 'lonely'), and for the above sample, the substrings that meet this criterion are chars[0:3], chars[1:4], and chars[2:5]. While I think this is technically correct, there are no constraints on N so I am timing out for test cases where N = 5000 and such (I have a time limit of 4 seconds per test case).
How do I work around this?
Thank you!
You could split the string on "G" and analyse the size of the left and right streak of H on each side of the splits. This will let you use compute the number of substrings with that lonely G in them. The number of substrings for a given G split will be formed of 3 parts: The n Hs on the left will form n-1 substrings that end with the G. The m Hs on the right will form m-1 substrings starting with the G. And the product of the left and right (n x m) will form substrings with the G in between Hs.
def count3(chars):
count = 0
for lonely in "GH": # count for G, then H
streaks = map(len,chars.split(lonely))
left = next(streaks) # first left side
for right in streaks: # get right sides
count += max(0,left-1) # HH...G
count += max(0,right-1) # G...HH
count += left*right # H...G...H
left = right # track new left side
return count
Output:
for testCase in ("G","GH","GHH","HG","HGH","HGHH","HHG","HHGH","HHGHH",
"GG","HHHGHHH","GGHGG","GGH"):
print(testCase,count3(testCase))
G 0
GH 0
GHH 1
HG 0
HGH 1
HGHH 3
HHG 1
HHGH 3
HHGHH 6
GG 0
HHHGHHH 13
GGHGG 6
GGH 1

Reading from Lists in Python

I want to access the scores associated with each letter of the alphabet which are stored in a text file (stores.txt). Each line is an index and I just want to retrieve the number for each letter and print it when I enter a certain letter into a function. How would I split the item in order to get the number and return it.
Scores.txt is shown like this:
A 1
B 3
C 5
D 3
E 1
F 5
G 4
H 3
I 1
J 10
K 8
L 3
M 5
N 3
O 2
P 5
Q 20
R 3
S 3
T 2
U 1
V 10
W 12
X 16
Y 8
Z 20
This is the code ive used up to now, however this would result in displaying the whole line
(['A','1']) when i passed A to the function and I would like just 1 to be passed.
def getLetterScore(user_Input):
scoreFileT1 = open('D:/DELL/Desktop/Programming Assignment/scores.txt')
score = []
for line in scoreFileT1:
line = line.strip(' ')
line = line.split()
score.append(line)
scoreFileT1.close()
if user_Input =='a' or user_Input == 'A':
print(score[0])
Here is the code I came up with.
In this, if you give any letter as input, the corresponding number for the letter will be printed.
def getLetterScore(user_Input):
scoreFileT1 = open('C://Users//Naveendran//Desktop//scores.txt')
score = []
for line in scoreFileT1:
line = line.strip(' ')
line = line.split()
score.append(line)
scoreFileT1.close()
for i in range(len(score)):
if user_Input.upper() == score[i][0]:
print(score[i][1])
b = input("Enter a letter:")
getLetterScore(b)
I suggest you going with this code
rfile=open("score.txt") #add your path here
file=rfile.read()
filesplit=file.split("\n")
letter=input("enter The number").capitalize()
for i in filesplit:
if(i[0]==letter):
for j in range(2,len(i)):
print(i[j],end="")

Count number's digits following by line

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

Python: Count Frequency in List and aligned the result [duplicate]

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

Random Simulation of 20 Die Throws

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...

Categories

Resources