Python 3: finding a set of letters in a string using loops - python

i'm using python 3 and i would like to know how to count the amount of times a set of 3 letters comes up in a sentence:
con = ""
count = 0
for i in mystery_string:
if i == "c":
con = "c"
if i == "a" and con == "c":
con = "ca"
if i == "t" and con == "ca":
con = "cat"
if con == "cat":
count +=1
con = ""
print (count)
this is the code i have so far, however it doesn't seem to work for every case
can someone help me
the thing i also need to explain is that i cannot use the builtin function count()

just do the following
mystery_string.count('cat')

you can use slicing:
word='cat'
count = 0
for i in range(len(mystery_string)-len(word)+1):
if mystery_string[i:i+len(word)]==word:
count +=1
print (count)

mystery_string = "my cat your cat"
count = 0
current_search_letter = "c"
if letter == "c":
current_search_letter = "a"
elif letter == "a" and current_search_letter == "a":
current_search_letter = "t"
elif letter == "t" and current_search_letter == "t":
count += 1
current_search_letter = "c"
else:
current_search_letter = "c"
print(count)

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.

I am trying to make a functions that counts the occurrence of letter diagonally top left to bottom right of a matrix

This is the main question
Write a function named find_longest_string(legoString,n) that finds and returns the longest
diagonal string from the upper-right triangle of the matrix representation of the brick placement.
The longest diagonal string is defined as a string that contains the maximum occurrences of a
letter on the same diagonal. In case there are multiple solutions i.e. diagonal strings of the
same maximum lengths, you can return any of the valid solutions. Fig 5 shows a computation
of a valid solution. This function must have two parameters, legoString - a string returned from
the function named “place_random_bricks”, and n - the number of columns on the baseplate.
In this example the letter G would be occurring the most
def find_longest_string(legoString, n):
list2 = []
countr = ""
countb = ""
countg = ""
county = ""
countc = ""
for i in range(len(legoString)):
list = []
if i % n == 0: #guarantees that row will only have required amount of columns(no more no less)
sub = legoString[i: i + n] #i starts at 0 and so add number of columns for first row and continue
#list = [] #create empty list each time a row is created
for j in sub:
list.append(j)
list2.append(j)
answer = ''.join(''.join(tup) for tup in list)
answer2 = ''.join(''.join(tup) for tup in list)
print(answer) # prints list before it is reset
for index in range(len(answer)):
if answer2[index] == answer[index-1]:
if answer2[index] == "R":
countr = countr + "R"
elif answer2[index] == "B":
countb = countb + "B"
elif answer2[index] == "G":
countg = countg + "G"
elif answer2[index] == "Y":
county = county + "Y"
elif answer2[index] == "C":
countc = countc + "C"
print(countr, countc, county, countb, countg)
if len(countr) >= len(countb) and len(countg) and len(county) and len(countc):
return countr
elif len(countb) >= len(countr) and len(countg) and len(county) and len(countc):
return countb
elif len(countg) >= len(countr) and len(countb) and len(county) and len(countc):
return countg
elif len(countc) >= len(countr) and len(countg) and len(county) and len(countb):
return countc
elif len(county) >= len(countr) and len(countg) and len(countb) and len(countc):
return county

How do i get these output?

How do i get these output?
def pair(str):
count = 0
for ch in str:
if ch == 'HLL':
return "Alice"
if ch == 'EO':
return "Bob"
if ch == "WORL":
return "Alice"
if ch == "D":
return "Bob"
else:
return "Hello World"
print(count)
return is executed before print, which means this method ends before print. print is not reachable in your code.
I don't know that you want to get data type of these output.
So, I guess 2 data types and write them here.
String
def pair(str):
count = 0
result = ''
for ch in str:
count += 1
if ch == 'HLL':
result += "Alice"
if ch == 'EO':
result += "Bob"
if ch == "WORL":
result += "Alice"
if ch == "D":
result += "Bob"
else:
result += "Hello World"
print(count)
return result
List
def pair(str):
count = 0
result = list()
for ch in str:
count += 1
if ch == 'HLL':
result.append("Alice")
if ch == 'EO':
result.append("Bob")
if ch == "WORL":
result.append("Alice")
if ch == "D":
result.append("Bob")
else:
result.append("Hello World")
print(count)
return result
Since return is the code that ends the function(def), for loop is executed only once in your code
For reference, if the input is a string(str), only one letter is entered in 'ch' in the for loop, so nothing other than D will be identified.

Easier way to check for four in row/column/diagonal in connect four game?

I am making a connect four game with X's and O's. The code for checking for four in a row/column/diagonal works but I have a lot of if statements in my code. The game fully works right now but I'm wondering if there is an easier solution to the checking. Below, I have included all my code for context.
I have tried using coordinates. It seems kind of inefficient though. The function for checking is called check.
namex = input("Player X, enter your name. ") #asks for player 1 name
nameo = input("Player O, enter your name. ") #asks for player 2 name
game = [[".", ".", ".", ".", ".", "."], #gameboard
[".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", "."]]
loop = True
def output(matrix):
str1 = ""
str2 = ""
str3 = ""
str4 = ""
str5 = ""
str6 = ""
print("0 1 2 3 4 5 6 ") #print labels for columns in gameboard
for a in matrix:
row = 0
for b in a: #"a" is a column and "b" is a ./x/o
row += 1
if row == 1:
str1 += b
str1 += " "
if row == 2:
str2 += b
str2 += " "
if row == 3:
str3 += b
str3 += " "
if row == 4:
str4 += b
str4 += " "
if row == 5:
str5 += b
str5 += " "
if row == 6:
str6 += b
str6 += " "
print(str1) #print string for row 1
print(str2) #print string for row 2
print(str3) #print string for row 3
print(str4) #print string for row 4
print(str5) #print string for row 5
print(str6) #print string for row 6
def check(matrix): #function to check for four in row/column/diagonal to win
positionx = []
positiono = []
x = 0
for a in matrix:
y = 5
for b in a:
if b == "X":
positionx.append([x, y])
if b == "O":
positiono.append([x, y])
y -= 1
x += 1
for c1 in positionx:
'''check four in row/column/diagonal for x'''
for c2 in positionx:
for c3 in positionx:
for c4 in positionx:
if c4[0]-c3[0] == 1:#check for four in row
if c3[0]-c2[0] == 1:
if c2[0]-c1[0] == 1:
return "xwin"
if c4[1]-c3[1] == 1: #check for four in column
if c3[1]-c2[1] == 1:
if c2[1]-c1[1] == 1:
return "xwin"
if c4[0]-c3[0] == 1: #check four in diagonal
if c4[1]-c3[1] == 1:
if c3[0]-c2[0] == 1:
if c3[1]-c2[1] == 1:
if c2[0]-c1[0] == 1:
if c2[1]-c1[1] == 1:
return "xwin"
for d1 in positiono:
'''check four in row/column/diagonal for o'''
for d2 in positiono:
for d3 in positiono:
for d4 in positiono:
if d4[0]-d3[0] == 1: #check for four in row
if d3[0]-d2[0] == 1:
if d2[0]-d1[0] == 1:
return "owin"
if d4[1]-d3[1] == 1: #check for four in column
if d3[1]-d2[1] == 1:
if d2[1]-d1[1] == 1:
return "owin"
if d4[0]-d3[0] == 1: #check four in diagonal
if d4[1]-d3[1] == 1:
if d3[0]-d2[0] == 1:
if d3[1]-d2[1] == 1:
if d2[0]-d1[0] == 1:
if d2[1]-d1[1] == 1:
return "owin"
while loop == True:
xinput = input(namex + ", you're X. What column do you want to play in? Please enter a number 0-6 ")
xcolumn = int(xinput)
xrow = 5
occupied1 = False
while occupied1 == False:
if game[xcolumn][xrow] == ".": #if there is a "." change to "X"
game[xcolumn][xrow] = "X"
output(game)
occupied1 = True
xrow -= 1
if check(game) == "xwin":
loop = False
print(namex + " wins!")
break
if check(game) == "owin":
loop = False
print(nameo + " wins!")
break
oinput = input(nameo + ", you're O. What column do you want to play in? Please enter number 0-6 ")
ocolumn = int(oinput)
orow = 5
occupied2 = False
while occupied2 == False:
if game[ocolumn][orow] == ".": #if there is a "." change to "O"
game[ocolumn][orow] = "O"
output(game)
occupied2 = True
orow -= 1
if check(game) == "xwin":
loop = False
print(namex + " wins!")
break
if check(game) == "owin":
loop = False
print(nameo + " wins!")
break
I'm also open to any other suggestions to make my code for this game better. Thanks!
I had some spare time, so I rewrote your program. It's much more efficient now. Read the comments to understand how it works
cols = [[] for x in range(6)]
# I opted to have a matrix of COLUMNS rather than rows because you can easily
# append items to the end of the list to simulate a real tile being placed there
# it's more intuitive and saves us time, as you'll see
def checkWin(cols):
for i in range(6): # Each column
for j in range(6): # Each row
try: #check if the element at these coordinates exists yet
cols[i][j]
except IndexError:
break
# go back to next i - impossible that there's anything with a higher
# j because if a list is n items long, and we go to j (which is one
# higher than n and doesn't exist) then there can't be an element at
# index j + someNumber.
ret = False
try: #vertical: j is the index in each column, so this goes up the column
if cols[i][j] == cols[i][j+1] == cols[i][j+2] == cols[i][j+3] is not None:
ret = True
except IndexError: #one of the elements of the comparison doesn't exist
pass #We can't be sure that none of the other trials will return True
try: #horizontal
if cols[i][j] == cols[i+1][j] == cols[i+2][j] == cols[i+3][j] is not None:
ret = True
except IndexError:
pass
try: #diagonal
if cols[i][j] == cols[i+1][j+1] == cols[i+2][j+2] == cols[i+3][j+3] is not None:
ret = True
except IndexError:
pass
try: #other diagonal
if cols[i][j] == cols[i-1][j+1] == cols[i-2][j+2] == cols[i-3][j+3] is not None:
ret = True
except IndexError:
pass
if ret:
return cols[i][j]
return None # We've gone through every single possible element and there are NO matches
def printBoard(cols):
# Pretty intuitive function IMO - we swap i and j to go through rows.
returnstr = '\n1 2 3 4 5 6\n'
for i in range(6):
for j in range(6):
try:
cols[j][5-i]
except IndexError:
returnstr += '_ '
continue
returnstr += cols[j][5-i]+' '
returnstr += '\n'
print(returnstr)
playerX = input('Player X, input your name: ')
playerO = input('Player O, input your name: ')
if playerX == playerO:
print("Cannot have the same name!")
exit()
count = 0
while not checkWin(cols):
printBoard(cols)
i = input('{}, input your column (1-6): '.format(playerO if count else playerX))
try:
target = cols[int(i)-1]
if len(target) == 6:
print("Column {} is already full! Please pick another.".format(i))
continue
target.append('O' if count else 'X')
except ValueError:
print("'{}' is not a number! Try again.".format(i))
continue
except IndexError:
print("{} is not a valid column number! Please pick another.".format(i))
continue
count = (count+1) % 2
printBoard(cols)
if checkWin(cols) == 'X':
print('{} (Player X), you win!'.format(playerX))
else:
print('{} (Player O), you win!'.format(playerO))
A good start would be to write a generalized function that checks for a diagonal at an arbitrary location:
def diagonal(grid, x, y, piece):
'''
Return True if grid contains a four-in-a-row diagonal starting at coordinates
(x, y) and traveling downwards and to the right. Otherwise return False.
'''
for i in range(x, x+4):
# if this square does not contain the desired piece, return False
if grid[x+i][y+i] != piece
return False
# if we got all the way through the loop, this must be a diagonal
return True
Then you would call this function for every possible starting coordinate of a four square diagonal, for each player X and O.
To improve this function, you could add a way to check for diagonals that travel the other direction (up and to the right).

Why does this substitution cipher script keep throwing an error?

I'm very new to python so bear with me. I'm putting together a little crypto puzzle and part of it requires a substitution cipher. In this case each letter is replaced with three random letters. Every time I run this code it throws an error when I try to encrypt something:
Traceback (most recent call last):
File "/home/pi/Desktop/expansion cipher.py", line 159, in <module>
crypt()
File "/home/pi/Desktop/expansion cipher.py", line 142, in crypt
print encrypt(txt)
File "/home/pi/Desktop/expansion cipher.py", line 127, in encrypt
ctxt = ctxt + exp_ciph(ptxt[counter])
File "/home/pi/Desktop/expansion cipher.py", line 121, in exp_ciph
return cur_exp
UnboundLocalError: local variable 'cur_exp' referenced before assignment
Here is my code:
def rev_ciph(char):
if char == "gps":
cur_rev = "_"
if char == "evl":
cur_rev = "."
if char == "jkb":
cur_rev = "e"
if char == "bhj":
cur_rev = "t"
if char == "szk":
cur_rev = "a"
if char == "nwu":
cur_rev = "o"
if char == "dpl":
cur_rev = "i"
if char == "sbg":
cur_rev = "n"
if char == "dsl":
cur_rev = "s"
if char == "yhq":
cur_rev = "p"
if char == "sav":
cur_rev = "h"
if char == "gfs":
cur_rev = ","
if char == "rtg":
cur_rev = "d"
if char == "fqu":
cur_rev = "l"
if char == "rjt":
cur_rev = "u"
if char == "sbv":
cur_rev = "c"
if char == "yqm":
cur_rev = "m"
if char == "ywh":
cur_rev = "f"
if char == "drt":
cur_rev = "y"
if char == "zfd":
cur_rev = "w"
if char == "asn":
cur_rev = "g"
if char == "fzj":
cur_rev = "p"
if char == "rka":
cur_rev = "b"
if char == "kzv":
cur_rev = "v"
if char == "lah":
cur_rev = "k"
if char == "rma":
cur_rev = "x"
if char == "fqn":
cur_rev = "q"
if char == "vrq":
cur_rev = "j"
if char == "tfv":
cur_rev = "z"
return cur_rev
def exp_ciph(char):
if char == "_":
cur_exp = "gps"
if char == ".":
cur_exp = "evl"
if char == "e":
cur_exp = "jkb"
if char == "t":
cur_exp = "bhj"
if char == "a":
cur_exp = "szk"
if char == "o":
cur_exp = "nwu"
if char == "i":
cur_exp = "dpl"
if char == "n":
cur_exp = "sbg"
if char == "s":
cur_exp = "dsl"
if char == "p":
cur_exp = "yhq"
if char == "h":
cur_exp = "sav"
if char == ",":
cur_exp = "gfs"
if char == "d":
cur_exp = "rtg"
if char == "l":
cur_exp = "fqu"
if char == "u":
cur_exp = "rjt"
if char == "c":
cur_exp = "sbv"
if char == "m":
cur_exp = "yqm"
if char == "f":
cur_exp = "ywh"
if char == "y":
cur_exp = "drt"
if char == "w":
cur_exp = "zfd"
if char == "g":
cur_exp = "asn"
if char == "p":
cur_exp = "fzj"
if char == "b":
cur_exp = "rka"
if char == "v":
cur_exp = "kzv"
if char == "k":
cur_exp = "lah"
if char == "x":
cur_exp = "rma"
if char == "q":
cur_exp = "fqn"
if char == "j":
cur_exp = "vrq"
if char == "z":
cur_exp = "tfv"
return cur_exp
def encrypt(ptxt):
ctxt = "Ciphertext: "
counter = 0
while counter <= len(ptxt):
ctxt = ctxt + exp_ciph(ptxt[counter])
counter += 1
return ctxt
def decrypt(ctxt):
ptxt = "Plaintext: "
counter = 0
while counter <= len(ctxt):
ptxt = ptxt + rev_ciph(ctxt[counter])
counter += 1
return ptxt
def crypt():
print
txt = raw_input("Plaintext: ")
print encrypt(txt)
print
def ucrypt():
print
txt = raw_input("Ciphertext: ")
print decrypt(txt)
print
ex_code = False
while ex_code == False:
print "(1) Encrypt"
print "(2) Decript"
print "(3) Exit"
print
mchoc = raw_input("What would you like to do(1,2,3?): ")
if mchoc == "1":
crypt()
if mchoc == "2":
ucrypt()
if mchoc == "3":
ex_code = True
print
You have two problems. The first is that you aren't handling all possible inputs. Having just copied and tested you code, I see that you get UnboundLocalError: local variable 'cur_exp' referenced before assignment if and only if you try to encrypt something that includes a character that isn't handled by exp_ciph(char) (or rev_ciph(char) for that matter). Neither of these functions handles capital letters, for instance. Python is ALWAYS case sensitive, and regards capital and lower case letters as entirely different characters. Your functions also don't handle other characters, such as "," and ";". If you give the program a string to encrypt that includes a character not handled by your first two functions, then, when that character comes up, all of the conditions for the if statements in these functions are false, and thus cur_exp is never created and assigned a value. When one of these functions then tries to return cur_exp, it finds that cur_exp doesn't exist. That is the source of the error you describe above.
If you input a string consisting ONLY of lower case letters and possibly "_", the you get an entirely different error, namely:
IndexError: string index out of range
This is because the function encrypt(ptxt) always goes looking for one more character than a string has. In Python (and, I think, every programming language) the elements in an iterable such as a string or a list are indexed by their OFFSET from the first item; that is, how many items are in front of it. So, if you have a string foo with 4 charachters:
foo = "abcd"
then:
foo[0] == "a"
foo[1] == "b"
foo[2] == "c"
foo[3] == "d"
There is no foo[4]. Calling foo[4] will raise exactly the above error. The len(object) function returns the number of items in an iterable. So, keeping with the above example,
len(foo) == 4
and thus calling
foo[len(foo)]
will raise IndexError:. This is EXACTLY what always happens in your encrypt(ptxt) function here
counter = 0
while counter <= len(ptxt):
ctxt = ctxt + exp_ciph(ptxt[counter])
counter += 1
You will want to do this instead:
counter = 0
while counter <= len(ptxt) - 1:
ctxt = ctxt + exp_ciph(ptxt[counter])
counter += 1
Those are the first two problem I encounter running this. I won't guarantee there are no more. Hopefully this gets you farther down the path though.

Categories

Resources