I came across below mentioned scenario:
Input:-
parselTongue
Expected Output:-
parsel_tongue
My code:-
empty_string = ""
word = input()
if word.islower() == 1:
empty_string = empty_string + word
print(empty_string)
else:
for char in word:
char = str(char)
if char.isupper() == 1:
x = char
y = word.find(x)
print(char.replace(char, word[0:y] + "_" + char.lower() + word[y:]))
My output:-
parsel_tTongue
Please advice where i am going wrong as my output is coming as "parsel_tTongue" and not "parsel_tongue"
The more elegant solution would be just to implement the logic using comprehension.
word = input()
output= ''.join(c if not c.isupper() else f'_{c.lower()}' for c in word)
#output: 'parsel_tongue'
I believe that this approach could be better.
It prevents from situations where word contains not only letters but also special characters or numbers.
word = "camelCaseWord"
res = "" # sanke case word
# handle 1st upper character
if word[0].isupper():
word = word[0].lower() + word[1:]
for w in word:
# Only letter can be upper
if w.isupper():
res += "_" + w.lower()
else:
res += w
print(res)
>>> camel_case_word
if word = "camelCase3Wor& - > >>> camel_case3_wor&
no need for loop use regex
import re
name = 'parselTongue'
name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
print(name) # camel_case_name
Adjust the slice on word
empty_string = ""
word = input()
if word.islower() == 1:
empty_string = empty_string + word
print(empty_string)
else:
for char in word:
char = str(char)
if char.isupper() == 1:
x = char
y = word.find(x)
print(char.replace(char, word[0:y] + "_" + char.lower()+ word[y+1:]))
prints the following for the input parselTongue
praselTongue
prasel_tongue
The best practice may be using regex:
fooBarBaz -> foo_bar_baz
re.sub(r'([A-Z])',lambda match:'_'+match.group(1).lower(),'fooBarBaz')
foo_bar_baz -> fooBarBaz
re.sub(r'_([a-z])',lambda match:match.group(1).upper(),'foo_bar_baz')
import re
camel_case = 'miaBau'
snake_case = re.sub(r'([A-Z])', r'_\1', camel_case).lower()
Related
I'm very new to python and I'm trying to make a hangman game. I currently have a line of code saying word = (random.choice(open("Level1py.txt").readline())).
I'm getting the error 'str' object does not support item assignment.
Here is the rest of my code (sorry for the mess):
import random
def checkLetter(letter, word, guess_word):
for c in word:
if c == letter:
guess_word[word.index(c)] = c
word[word.index(c)] = '*'
print(guess_word)
word = (random.choice(open("Level1py.txt").readline().split()))
guess_word = ['_' for x in word]
print(guess_word)
while '_' in guess_word:
guess = input('Letter: ')
print(checkLetter(guess, word, guess_word))
Strings are immutable in python. An easy workaround is to use lists, which are mutable:
st = "hello"
ls = list(st)
ls[3] = 'r'
st = ''.join(ls)
print(st)
Outputs
helro
Edit: here's how you would implement it in your own code
import random
def checkLetter(letter, word, guess_word):
for c in word:
if c == letter:
guess_word[word.index(c)] = c
word_list = list(word)
word_list[word.index(c)] = "*"
word = ''.join(word_list)
print(guess_word)
word = 'test'
guess_word = ['_' for x in word]
print(guess_word)
while '_' in guess_word:
guess = input('Letter: ')
print(checkLetter(guess, word, guess_word))
Note that there are still other issues that have nothing to do with this, like printing None and duplicate printing
You can also solve your problem using a dictionary:
word = "my string" #replace this with your random word
guess_word = {i: '_' for i in set(word)} # initially assign _ to all unique letters
guess_word[' '] = ' ' # exclude white space from the game
wrong_attempts = 0
while '_' in guess_word.values():
guess = input('Letter: ')
if guess in guess_word.keys():
guess_word[guess] = guess
else:
wrong_attempts += 1
if wrong_attempts > 11:
break
printable = [guess_word[i] for i in word]
print(' '.join(printable))
if '_' in guess_word.values():
print('you lost')
else:
print('congratulation, you won')
How would I replace the spaces in a string with underscores without using the replace function. I was told to also use a accumulation string with some type of loop
string = input("Enter a string")
i = 0
acc = ""
for char in string:
if char == " ":
acc = string + "_"
print(acc)
Try this,
string = input("Enter a string")
i = 0
acc = ""
newlist = [] #create a new list which will be the output
strlist = list(string) #create a list of each character in the input string
for char in strlist:
if char == " ":
newlist.append('_')
newlist.append(char)
acc = ''.join(newlist)
print(acc)
Your code should to be :
string = input("Enter a string")
i = 0
acc = ""
for char in string:
if char == " ":
acc += "_"
else:
acc += char
print(acc)
Try it if without replace.
string = input("Enter a string")
res = ''.join(["_" if i == " " else i for i in string])
print(res)
Another method:
string = input("Enter a string")
res = "_".join(string.split(" "))
print(res)
Your code isn't too far off. You can use an accumulation string like this:
string = input("Enter a string")
acc = ""
for char in string:
if char == " ":
char = "_"
acc += char
print(acc)
If you are allowed to use split, then
s = 'Your string with spaces'
s_ = ''
for word in s.split():
s_ += '_' + word
s_[1:] # 'Your_string_with_spaces'
Otherwise, instead of words, concatenate characters with '_' instead of ' ':
s_ = ''
for char in s:
if char == ' ':
s_ += '_'
else:
s_ += char
Is there another to have exception for capitalizing an entire sentence. I've heard of skipList method, but it didn't work for my code. See below:
string = input('Enter a string: ')
i = 0
tempString = ' '.join(s[0].upper() + s[1:] for s in string.split(' '))
result = ""
for word in tempString.split():
if i == 0:
result = result + word + " "
elif (len(word) <= 2):
result = result + word.lower() + " "
elif (word == "And" or word == "The" or word == "Not"):
result = result + word.lower() + " "
else:
result = result + word + " "
i = i + 1
print ("\n")
print (result)
Sure. Write a complete list of words that should not be title-cased ("and", "the", "or", "not", etc), and title-case everything else.
words = s.split(' ')
result = ' '.join([words[0]] + [w.title() for w in words[1:] if w not in skipwords])
of course this will still miss Mr. Not's last name, which should be capitalized, and some stranger things like "McFinnigan" will be wrong, but language is hard. If you want better than that, you'll probably have to look into NTLK.
You could rewrite this like this
skip_words = {w.capitalize(): w for w in 'a in of or to and for the'.split()}
words = string.title().split()
result = ' '.join(skip_words.get(w, w) for w in words).capitalize()
I have a problem when creating a function that's supposed to first return lowercase letters, "_" and "." and then uppercase letters, " " and "|" in that order. My version seems to return numbers and special characters like <># too which I don't want it to do, It's only supposed to read through the input string once and I don't know if that's achieved with my code.
My code is:
def split_iterative(n):
splitted_first = ""
splitted_second = ""
for i in n:
if i == i.lower() or i == "_" or i == ".":
splitted_first = splitted_first + i
elif i == i.upper() or i == " " or i == "|":
splitted_second = splitted_second + i
return splitted_first + splitted_second
if I do split_iterative("'lMiED)teD5E,_hLAe;Nm,0#Dli&Eg ,#4aI?rN#T§&e7#4E #<(S0A?<)NT8<0'")) it returns "'li)te5,_he;m,0#li&g ,#4a?r#§&e7#4 #<(0?<)8<0'MEDDELANDEINTESANT" which is incorrect as it should eliminate all those special characters and numbers. How do I fix this? It should return ('lite_hemligare', 'MEDDELANDE INTE SANT')
You could try this:
def f(input_string):
str1 = str2 = ""
for character in input_string:
if character.isalpha():
if character.islower():
str1 += character
else:
str2 += character
elif character in "_.":
str1 += character
elif character in " |":
str2 += character
return str1, str2
Output:
>>> input_string = "'lMiED)teD5E,_hLAe;Nm,0#Dli&Eg ,#4aI?rN#T§&e7#4E #<(S0A?<)NT8<0'"
>>>
>>> print f(input_string)
('lite_hemligare', 'MEDDELANDE INTE SANT')
>>>
This is because you are iterating through a string. The lowercase of the special characters is the same as the character. i.e.. '#'.lower() == '#'. hence it'll return '#' and all other special characters. you should explicitly check for alphabets using the isalpha() method on strings.
(i.isalpha() and i.lower() == i) or i == '_' or i == '.'
First, to make it return a list don't return the concatenated string but a list
Second, you are not checking or filtering out the characters, one way would be by checking if the character is a letter using isalpha() method
something like this:
def split_iterative(n):
splitted_first = ""
splitted_second = ""
for i in n:
if (i.isalpha() and i == i.lower()) or i == "_" or i == ".":
splitted_first = splitted_first + i
elif (i.isalpha() and i == i.upper()) or i == " " or i == "|":
splitted_second = splitted_second + i
#returns a list you can make it a variable if you need
return [splitted_first, splitted_second]
You can use ASCII values for the filtering of characters:
def split_iterative(n):
splitted_first = ""
splitted_second = ""
for i in n:
if ord(i) in range(97,122) or i == "_" or i == ".":
splitted_first = splitted_first + i
elif ord(i) in range(65,90) or i == " " or i == "|":
splitted_second = splitted_second + i
return (splitted_first , splitted_second)
You can make use of two lists while walking through characters of your text.
You can append lowercase, underscore, and stop characters to one list then uppercase, space and pipe characters to the other.
Finally return a tuple of each list joined as strings.
def splittext(txt):
slug, uppercase_letters = [], []
slug_symbols = {'_', '.'}
uppercase_symbols = {' ', '|'}
for letter in txt:
if letter.islower() or letter in slug_symbols:
slug.append(letter)
if letter.isupper() or letter in uppercase_symbols:
uppercase_letters.append(letter)
return ''.join(slug), ''.join(uppercase_letters)
txt="'lMiED)teD5E,_hLAe;Nm,0#Dli&Eg ,#4aI?rN#T§&e7#4E #<(S0A?<)NT8<0'"
assert splittext(txt) == ("lite_hemligare", "MEDDELANDE INTE SANT")
SO i have this assignment to translate multiple words into pig latin. assume that the user will always input lowercase and only letters and spaces.
#----------------global variables
sentence = input("What do you want to translate into piglattin? ")
sentence = list(sentence)
sentence.insert(0, ' ')
length = len(sentence)
sentence.append(' ')
pigLattin = sentence
false = 0
true = 1
consonant = []
a = 0
b = 0
c = 0
d = 0
e = 0
f = 0
j = 0
x = 0
y = 0
#----------------main functions
def testSpace(sentence, i):
if sentence[i] == ' ':
a = true
else:
a = false
return a
def testVowel(sentence, i):
if sentence[i] == 'a' or sentence[i] == 'e' or sentence[i] == 'i' or sentence[i] == 'o' or sentence[i] == 'u' or sentence[i] == 'y':
b = true
else:
b = false
return b
def testStartWord(sentence, i):
x = 0
if sentence[i].isalpha() and sentence[i-1] == ' ':
c = true
x = 1
if x == 1 and sentence[i] != 'a' and sentence[i] != 'e' and sentence[i] != 'i' and sentence[i] != 'o' and sentence[i] != 'u' and sentence[i] != 'y':
c = true
else:
c = false
return c
def testWordEnd(sentence, i):
if sentence[i].isalpha() and sentence[i+1] == ' ':
d = true
else:
d = false
return d
#----------------main loop
for i in range(1,length):
x = 0
space = testSpace(sentence, i)
vowel = testVowel(sentence, i)
word = testStartWord(sentence, i)
end = testWordEnd(sentence, i)
if vowel == false and space == false and word == true:
e = i
consonant.append(sentence[i])
pigLattin.pop(e)
f = f + 1
if end == true:
consonant.append('a')
consonant.append('y')
consLength = len(consonant)
for x in range(consLength):
y = i + j - f
pigLattin.insert(y,consonant[x])
j = j + 1
del consonant[:]
pigLength = len(pigLattin)
for b in range (pigLength):
print(pigLattin[b], end='')
this is what i have so far. it gets kinda messy when trying to remove items. im sort of stuck here and its not working.
OK i got it working now this is an updated version
sentence = input("Please enter a sentence: ")
vowels = ("a", "e", "i", "o", "u", "A", "E", "I", "O", "U")
words = sentence.split()
count = 0
def find_vowel(word):
for i in range(len(word)):
if word[i] in vowels:
return i
return -1
for word in words:
vowel = find_vowel(word)
if(vowel == -1):
print(word, ' ', end='')
elif(vowel == 0):
print(word + "ay", ' ', end='')
else:
print(word[vowel:] + word[:vowel] + "ay", ' ', end='')
Instead of using testSpace eliminate the spaces by using sentence = sentence.split(). This will split all your words into strings in a list. Then iterate through the words in your list.
Instead of using testStartWord, use an if statement:
for word in sentence:
if word[0] in ["a","e","i","o","u"]:
word[:(len(word)-1)] = word[0]
#More Code...
At the end, where you print the output, use print sentence.join()
Here's an alternate version. I use a regular expression to find words in the input string, pass them to a callback function, and substitute them back into the original string. This allows me to preserve numbers, spacing and punctuation:
import re
import sys
# Python 2/3 compatibility shim
inp = input if sys.hexversion >= 0x3000000 else raw_input
VOWELS = set('aeiouyAEIOUY')
YS = set('yY')
def pig_word(word):
"""
Given a word, convert it to Pig Latin
"""
if hasattr(word, 'group'):
# pull the text out of a regex match object
word = word.group()
# find the first vowel and what it is
vowel, where = None, None
for i,ch in enumerate(word):
if ch in VOWELS:
vowel, where = ch, i
break
if vowel is None:
# No vowels found
return word
elif where == 0 and vowel not in YS:
# Starts with a vowel - end in 'way'
# (leading y is treated as a consonant)
return word + 'way'
else:
# Starts with consonants - move to end and follow with 'ay'
# check capitalization
uppercase = word.isupper() and len(word) > 1
titlecase = word[:1].isupper() and not uppercase
# rearrange word
word = word[where:] + word[:where] + 'ay'
# repair capitalization
if uppercase:
word = word.upper()
elif titlecase:
# don't use str.title() because it screws up words with apostrophes
word = word[:1].upper() + word[1:].lower()
return word
def pig_latin(s, reg=re.compile('[a-z\']+', re.IGNORECASE)):
"""
Translate a sentence into Pig Latin
"""
# find each word in the sentence, pass it to pig_word, and insert the result back into the string
return reg.sub(pig_word, s)
def main():
while True:
s = inp('Enter a sentence to translate (or Enter to quit): ')
if s.strip():
print(pig_latin(s))
print('')
else:
break
if __name__=="__main__":
main()
then
Enter a sentence to translate (or Enter to quit):
>>> Hey, this is really COOL! Let's try it 3 or 4 times...
Eyhay, isthay isway eallyray OOLCAY! Et'slay ytray itway 3 orway 4 imestay...