I am able to iterate through two given strings of the same length.
I am supposed to output a green emoji if the letters in guess_word are are also contained and in the correct position of the secret_word. If a letter in the guess_word is in the secret_word but it's in the wrong position, then I should have an output of a yellow emoji.
This is where my issue is. The yellow emoji is not showing up in my output, only the green and white boxes. I have a picture below of what it should look like in the output.
I have to stick to two different functions because this is what my homework is asking me to do.
def contains_char(any_length: str, single_character: str) -> bool:
"""Loop iterates through each character in string to find matching character."""
assert len(single_character) == 1
if single_character in any_length:
return True
else:
return False
def emojified(guess_word: str, secret_word: str) -> str:
"""A way to match letters to its corresponding emoji color output. """
assert len(guess_word) == len(secret_word)
WHITE_BOX: str = "\U00002B1C"
GREEN_BOX: str = "\U0001F7E9"
YELLOW_BOX: str = "\U0001F7E8"
emoji_color: str = ""
i: int = 0
while i < len(secret_word):
i += 1
if guess_word[0] in secret_word[0]:
emoji_color += GREEN_BOX
i += 1
else:
emoji_color += WHITE_BOX
i += 1
if contains_char is True:
emoji_color += YELLOW_BOX
else:
emoji_color += WHITE_BOX
return emoji_color
Output:
Without changing too much, here's how I would write your while-loop:
while i < len(secret_word):
guess_char = guess_word[i]
secret_char = secret_word[i]
current_emoji = WHITE_BOX # By default, we display a white box for this position
if contains_char(secret_word, guess_char):
current_emoji = YELLOW_BOX # guess_char is in secret_word. guess_char may even be in the correct position, but we don't care about that yet.
if guess_char == secret_char:
current_emoji = GREEN_BOX # guess_char is in the correct position.
emoji_color += current_emoji
i += 1
return emoji_color
In order to properly process the "same-position" matches without interfering with the "different-position" matched, you need to check for same-positions first and fallback on diffrent-position matches otherwise.
You can do this by replacing characters in a comprehension that you join into the final result.
For example:
def emojified(guess,secret):
WHITE_BOX = "\U00002B1C"
GREEN_BOX = "\U0001F7E9"
YELLOW_BOX = "\U0001F7E8"
return "".join( GREEN_BOX if s==g # same-position
else YELLOW_BOX if g in secret # different-position
else WHITE_BOX # no match
for s,g in zip(secret,guess)) # character pairs
Output:
print(emojified("hello","world")) # ⬜️⬜️🟨🟩🟨
print(emojified("elloh","hello")) # 🟨🟨🟩🟨🟨
print(emojified("python","woohoo")) # ⬜️⬜️⬜️🟩🟩⬜️
print(emojified("python","python")) # 🟩🟩🟩🟩🟩🟩
print(emojified("yikyak","tiktok")) # ⬜️🟩🟩⬜️⬜️🟩
Related
I'm currently doing a leetcode question, and I feel as though my logic is fairly solid, but I am getting a KeyError: 'B' error on the line that says if window_frequency[lefty] == 1:
and cannot seem to figure it out. Does anyone have any ideas?
Also the purpose of the code is to find the minimum substring of string s that contains all the letters of the second inputted string (aka string t)
code:
def minWindow(s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
# dictionary of character frequencies
# everytime we move the right pointer, we check if the letter frequency is a subset of the
# window frequency dictionary, if it is, we set window_valid to true.
# when the window is no longer valid, we increase move it, editing the frequencies of the #window
letter_frequency = {}
window_frequency = {}
left = 0
current_result = ""
result = ""
# fill dictionary for letter frequency for t
for each in t:
if each not in letter_frequency:
letter_frequency[each] = 1
else:
letter_frequency[each] += 1
for right in range(len(s)):
letter = s[right]
# adding to frequency
if letter not in window_frequency:
window_frequency[letter] = 1
else:
window_frequency[letter] += 1
# setting the result value if the window is valid
window_valid = all(letter_frequency.get(key, None) == val for key, val in window_frequency.items())
while window_valid == True:
current_result = s[left:right]
if len(result) == 0:
result = current_result
elif (len(current_result) < len(result)):
result = current_result
# now we decrease the size of the window till it is no longer valid
lefty = s[left]
if window_frequency[lefty] == 1:
del window_frequency[lefty]
else:
window_frequency[lefty] -= 1
left += 1
return result
print(minWindow("ABAABANCHQR", "ABC"))
I am very beginner in Python.
aString = 'fruit list is: <carrot>, <orange>, <pineapple>, <grape>, <watermelon>, <mangosteen>'
From my aString, sometime I need a string 'carrot'; sometime I need a string 'watermelon'; sometime I need a string 'mangosteen'.
Does Python have a function to get string between two character with specific index?
I am very thankful if somebody can help to solve this problem.
you can get a substring between two indexes like this
aString[start: end]
where start and end are integers
It's too late but that's my own function:
def Between(first, second, position, string, direction='forward'):
# if you have the index of the second character you can use it but add direction = 'back' or anything except 'forward'
result = ""
pairs = 1
if direction == 'forward':
for i in string[position+1:]:
if i == first: pairs += 1
elif i == second: pairs -= 1
if pairs==0: break
result = result+i
else:
for i in (string[:position])[::-1]:
if i == second: pairs += 1
elif i == first: pairs -= 1
if pairs==0: break
result = i+result
return result
# for example:
string = "abc(defg)hijklmenop"
print(Between("(", ")", 3, string)) # direction = 'forward'
print(Between("(", ")", 8, string, direction='back'))
# Also it works in this case:
string = "abcd(efg(hij)klmno)pqrstuvwxyz"
print(Between("(", ")", 4, string)) # direction = 'forward'
print(Between("(", ")", 18, string, direction='back'))
I'd like write code to find specific instances of words in a long string of text, where the letters making up the word are not adjacent, but consecutive.
The string I use will be thousands of characters long, but a as a shorter example... If I want to find instances of the word "chair" within the following string, where each letter is no more than 10 characters from the previous.
djecskjwidhl;asdjakimcoperkldrlkadkj
To avoid the problem of finding many instances in a large string, I'd prefer to limit the distance between every two letters to 10. So the word chair in the string abcCabcabcHabcAabdIabcR would count. But the word chair in the string abcCabcabcabcabcabcabcabcabHjdkeAlcndInadhR would not count.
Can I do this with python code? If so I'd appreciate an example that I could work with.
Maybe paste the string of text or use an input file? Have it search for the word or words I want, and then identify if those words are there?
Thanks.
This code below will do what you want:
will_find = "aaaaaaaaaaaaaaaaaaaaaaaabcCabcabcHabcAabdIabcR"
wont_find = "abcCabcabcabcabcabcabcabcabHjdkeAlcndInadhR"
looking_for = "CHAIR"
max_look = 10
def find_word(characters, word):
i = characters.find(word[0])
if i == -1:
print("I couldnt find the first character ...")
return False
for symbol in word:
print(characters[i:i + max_look+1])
if symbol in characters[i:i + max_look+1]:
i += characters[i: i + max_look+1].find(symbol)
print("{} is in the range of {} [{}]".format(symbol, characters[i:i+ max_look], i))
continue
else:
print("Couldnt find {} in {}".format(symbol, characters[i: i + max_look]))
return False
return True
find_word(will_find, looking_for)
print("--------")
find_word(wont_find, looking_for)
An alternative, this may also work for you.
long_string = 'djecskjwidhl;asdjakimcoperkldrlkadkj'
check_word = 'chair'
def substringChecker(longString, substring):
starting_index = []
n , derived_word = 0, substring[0]
for i, char in enumerate(longString[:-11]):
if char == substring[n] and substring[n + 1] in longString[i : i + 11]:
n += 1
derived_word += substring[n]
starting_index.append(i)
if len(derived_word) == len(substring):
return derived_word == substring, starting_index[0]
return False
print(substringChecker(long_string, check_word))
(True, 3)
To check if the word is there:
string = "abccabcabchabcaabdiabcr"
word = "chair"
while string or word:
index = string[:10].find(word[0])
if index > -1:
string = string[index+1:]
word = word[1:]
continue
if not word:
print("found")
else:
break
I did an implementation on checking if whether a string has balanced parentheses or not using a STACK only. But I checked for balanced parentheses when the string has words. For example:
>>> is_paren_balanced("[{whoa (this is rough [how do I do this!])}]")
True
I was successful in doing that. However, I am not trying to check for a case if the string has NO parenthesis. And then i got this result:
>>> is_paren_balanced("Hi i love food.")
no parenthesis
True
>>> is_paren_balanced("[{whoa (this is rough [how do I do this!])}]")
no parenthesis
False
For the first result, I don't want the boolean result as thats kind of vague. I'm trying to show the user that the string has no parenthesis so it is neither True or False. I just want the print statement shown saying "no parentheses here" or whatever. For the second result, obviously just the boolean result and it shouldve returned True.
Any suggestions? I'm stumped.
Here is the code I'm practicing with:
from stack import Stack
def is_match(p1, p2):
if p1 == "(" and p2 == ")":
return True
elif p1 == "{" and p2 == "}":
return True
elif p1 == "[" and p2 == "]":
return True
else:
return False
def is_paren_balanced(paren_str):
s = Stack() #initialize a stack object
is_balanced = True #boolean flag: whether the str has balanced parenthesis or not
# then set to false if otherwise
index = 0 # keep track of where we are in the string
paren_str = paren_str.replace(" ", "") #accounts for possible spaces in the input
while index < len(paren_str) and is_balanced:
paren = paren_str[index]
if paren in "({[":
s.push(paren)
elif paren in ")}]":
if s.is_empty():
is_balanced = False
else:
top = s.pop()
if not is_match(top, paren):
is_balanced = False
else:
if paren not in "({[]})":
print("no parenthesis")
break
index += 1
if s.is_empty() and is_balanced:
return True
else:
return False
Sorry if it doesn't seem pythonic. I was just mostly exploring with this problem and will edit and improve later on.
You can use either regex or list comprehension to get the total amount of parenthesis first:
import re
def all_parenthesis(msg):
left = re.findall(r"[\[{(]",msg)
right = re.findall(r"[\]|})]",msg)
if not left and not right:
return "No parenthesis"
#or
def check_balance(msg):
d = {"[":"]",
"{":"}",
"(":")"}
left = [char for char in msg if char in d]
right = [char for char in reversed(msg) if char in d.values()]
#if not left not right...
But if you already constructed a list of parenthesis on both sides, why don't go ahead and compare them instead? Could be something like this:
def check_balance(msg):
d = {"[":"]",
"{":"}",
"(":")"}
left = [char for char in msg if char in d]
right = [char for char in reversed(msg) if char in d.values()]
if not left and not right:
return "No parenthesis"
elif len(left) != len(right):
return False
for a, b in zip(left,right):
if d.get(a) != b:
return False
return True
I thought that so long that the if statement is True, then run the line of code. Why is it wanting an integer in the conditional?
#function that accepts a string and calculates the number of upper case and lower case
def case_count(str):
total_cap_cases = 0
total_low_cases = 0
for words in str:
if str[words].isupper():
total_cap_cases += 1
elif words.islower():
total_low_cases += 1
else:
pass
print(total_cap_cases)
print(total_low_cases)
str = "How Many upper and LOWER case lettters are in THIS senTence?"
case_count(str)
When I run this code:
s = "abc"
for words in s:
print(words)
I get this output:
$ python test.py
a
b
c
This is because for variable in string: does not create an integer index. Rather, it assigns the individual characters of the string to variable, one at a time.
When you do for words in str:, you are actually processing the str one character at a time. You would do better to write:
for character in str:
if character.isupper():
tot_cap_cases += 1
elif character.islower():
tot_low_cases += 1
else:
tot_non_cases += 1
(Also, it's worth pointing out that in the world of unicode, you cannot simply assume that any character that is not upper case must be lower case. According to this Unicode FAQ page most scripts do not have case at all.)
There is an error in your code. You should just use words.isupper(): instead of str[words].isupper()
def case_count(str):
total_cap_cases = 0
total_low_cases = 0
for words in str:
if words.isupper():
total_cap_cases += 1
else:
total_low_cases += 1
print(total_cap_cases)
print(total_low_cases)
You're attempting to use a str to index, but it should be of type int.
To fix it, you can simply change:
if str[words].isupper():
to:
if words.isupper():
I also recommend using replace(' ', '') on your str, as the spaces might count when computing the values.
You can iterate string in python, but string isn't list.
it indices must be integers, not str
def case_count(string):
total_cap_cases = 0
total_low_cases = 0
for words in string:
if words.isupper():
total_cap_cases += 1
else:
total_low_cases += 1
print(total_cap_cases)
print(total_low_cases)
OR
def case_count(string):
total_cap_cases = 0
total_low_cases = 0
for idx in range(0, len(string)):
if string[idx].isupper():
total_cap_cases += 1
else:
total_low_cases += 1
print(total_cap_cases)
print(total_low_cases)
plus, do not use str as variable. it's python keyword.
str = "How Many upper and LOWER case lettters are in THIS senTence?"
def case_Counts(String):
print("Capital Letters: ", sum(1 for String in str if String.isupper()))
print("LowerCase Letters: ", sum(1 for String in str if String.islower()))
case_Counts(str)