Not converting letters to uppercase and lowercase in python - python

I'm trying to make a program that will convert any text into a different form. That means that a text such as 'hi there' becomes 'hI tHeRe'.
list = []
word = input('Enter in a word or a sentence! ')
for num in range(len(word)):
list.clear()
list.append('i')
letter = word[num]
for x in range(len(list)):
if x % 2 == 0:
i = word.index(letter)
place = letter.lower()
word = word.replace(word[i], place)
if not x % 2 == 0:
i = word.index(letter)
place = letter.upper()
word = word.replace(word[i], place)
print(word)
However, when I run the code it just prints the same string as normal.

When using replace, you have to assign the result to your variable:
word = word.replace(word[i], place)
However, replace is actually not what you want here. replace replaces all instances of a certain pattern with a new string. In your current code, every instance of whatever letter word[i] represents will be replaced with the result of .lower() or .upper().
You also don't want to use the word list, since doing so will shadow the Python built-in list class.
If you want to keep most of your original logic, you can follow #khelwood's suggestion in the comments and end up with the following:
word = input('Enter in a word or a sentence! ')
wordList = list(word)
for i in range(len(word)):
if i % 2 == 0:
wordList[i] = word[i].lower()
else:
wordList[i] = word[i].upper()
print(''.join(wordList))

Here is one of my previous codes, you can change all the variable names to whatever you see fit.
s = input('Enter in a word or string.')
ret = ""
i = True # capitalize
for char in s:
if i:
ret += char.upper()
else:
ret += char.lower()
if char != ' ':
i = not i
print(ret)
I hope it works for you.

Try this one liner -
a = 'hi there'
''.join([i[1].lower() if i[0]%2==0 else i[1].upper() for i in enumerate(a)])
'hI ThErE'
If you care about each word starting from lowercase then this nested list comprehension works -
' '.join([''.join([j[1].lower() if j[0]%2==0 else j[1].upper() for j in enumerate(i)]) for i in a.split()])
'hI tHeRe'

The problem is with list.clear in the beginning of the for loop.
Each iteration you clear the list so the second for iteration run on the first item only.
Remove list.clear and it should scan the input word

Related

Changing capitalization with for loops and list comprehension

I have a assignment where I need to
sometimes it might be useful to convert text from lowerCamelCase to snake_case. The main trick is to find the correct place where to insert an underscore. Let's make a rule that it's right before a capital letter of the next word. If the first letter is capitalized, convert it to lowercase and don't forget to insert an underscore before it.
I wrote my code and for some reason it doesn't return anything, it's completely empty, my ide says I have no errors
word = input()
new_word = ''
for char in word:
if char.isupper():
new_word.join('_' + char.lower())
else:
new_word.join(char)
print(new_word)
The assignment runs multiple tests with different words, and here they are
Sample Input 1:
python
Sample Output 1:
python
Sample Input 2:
parselTongue
Sample Output 2:
parsel_tongue
I legitimately don't see any reason why it's not printing, any ideas why
It's because the 1st test case is all lower case.
new_word will be empty because loop's inner condition won't execute at all.
Here's the correct and cleaner code I wrote
word = input()
counter = 0
new_word = ""
for char in word:
if not(char.islower()) and counter > 0:
new_word = new_word + '_' + char.lower()
else:
new_word = new_word + char.lower()
counter += 1
print(new_word)
You are almost there. You have to concatenate the characters to new_word and not join.
This is Concatenation. char gets appended to new_word:
new_word += char
join() will just concatenate and return the strings passed to it. But it is not saved to new_word.
Use concatenation instead of join in your code.
word = input('Input: ')
new_word = ''
for char in word:
if char.isupper():
new_word += '_' + char.lower()
else:
new_word += char
print(f'Output: {new_word}')
Input: python
Output: python
Input: parselTongue
Output: parsel_tongue
As your title says "list comprehension", here is an approach that utilizes a comprehension:
snake_word = ''.join(f'_{c.lower()}' if c.isupper() else c for c in word)

Python iterations mischaracterizes string value

For this problem, I am given strings ThatAreLikeThis where there are no spaces between words and the 1st letter of each word is capitalized. My task is to lowercase each capital letter and add spaces between words. The following is my code. What I'm doing there is using a while loop nested inside a for-loop. I've turned the string into a list and check if the capital letter is the 1st letter or not. If so, all I do is make the letter lowercase and if it isn't the first letter, I do the same thing but insert a space before it.
def amendTheSentence(s):
s_list = list(s)
for i in range(len(s_list)):
while(s_list[i].isupper()):
if (i == 0):
s_list[i].lower()
else:
s_list.insert(i-1, " ")
s_list[i].lower()
return ''.join(s_list)
However, for the test case, this is the behavior:
Input: s: "CodesignalIsAwesome"
Output: undefined
Expected Output: "codesignal is awesome"
Console Output: Empty
You can use re.sub for this:
re.sub(r'(?<!\b)([A-Z])', ' \\1', s)
Code:
import re
def amendTheSentence(s):
return re.sub(r'(?<!\b)([A-Z])', ' \\1', s).lower()
On run:
>>> amendTheSentence('GoForPhone')
go for phone
Try this:
def amendTheSentence(s):
start = 0
string = ""
for i in range(1, len(s)):
if s[i].isupper():
string += (s[start:i] + " ")
start = i
string += s[start:]
return string.lower()
print(amendTheSentence("CodesignalIsAwesome"))
print(amendTheSentence("ThatAreLikeThis"))
Output:
codesignal is awesome
that are like this
def amendTheSentence(s):
new_sentence=''
for char in s:
if char.isupper():
new_sentence=new_sentence + ' ' + char.lower()
else:
new_sentence=new_sentence + char
return new_sentence
new_sentence=amendTheSentence("CodesignalIsAwesome")
print (new_sentence)
result is codesignal is awesome

Create a function that contains only the first occurrence of a letter from the original phrase

The function needs to behave as follow:
The first letter occurrence can be upper or lower case (newPhrase).
Non-alpha characters - are left unchanged.
So far I thought of :
def keepFirstLetter(phrase):
'''Returns a new string that contains only the first occurrence of a
letter from the original phrase.
letterSeenSoFar = ''
newPhrase = ''
if (letterSeenSoFar == '' or letterSeenSoFar[-1] != letterSeenSoFar):
letterSeenSoFar += c
for letter in letterSeenSoFar:
if letter.isalpha:
newPhrase += char
else:
newPhrase += letter
return newPhrase
You seem to be on the right track. If you want to improve you efficiency, you can store the seen letters as a set. Searching a set is O(1).
def unique_first(s):
letters = set()
out = ''
for x in s:
if not x.isalpha():
out += x
continue
if not x.lower() in letters:
out += x
letters.add(x.lower())
return out
The most straightforward, sure-to-have-learned solution is probably:
def keepFirstLetter(phrase):
output = ''
for letter in phrase:
if (letter.lower() not in output.lower()) or (not letter.isalpha()):
output += letter
return output
print(keepFirstLetter('Amy says, "Me?"')) # Amy s, "e?"
(the parens around the two if clauses are optional)
James's solution still gets my vote though.
My name was in the question so let me take a try.
I learned set.add() from James for the first time. (Thank you, James.) James' code is shorter and runs faster (3.48us vs. 3.76us on my PC).
def keepFirstLetter(phrase):
phrase = list(phrase)
'''Returns a new string that contains only the first occurrence of a
letter from the original phrase.'''
letterSeenSoFar = []
newPhrase = ''
for char in phrase:
# if char is not an alphabet, add char to the newPhrase as is
if not char.isalpha():
newPhrase += char
# if char is an alphabet and not seen so far, add char to the newPhrase and append it to letterSeenSoFar
elif char.lower() not in letterSeenSoFar:
letterSeenSoFar.append(char.lower())
newPhrase += char
return newPhrase
print(keepFirstLetter('Amy says, " Me?"'))
This outputs:
Amy s, " e?"

How can I capitalize a character with an odd-numbered index in a string?

So I was doing our exercise when I came across capitalizing characters in odd indices. I tried this:
for i in word:
if i % 2 != 0:
word[i] = word[i].capitalize()
else:
word[i] = word[i]
However, it ends up showing an error saying that not all strings can be converted. Can you help me debug this code snippet?
The problem is strings in python are immutable and you cannot change individual characters. Apart fro that when you iterate through a string you iterate over the characters and not the indices. So you need to use a different approach
A work around is
(using enumerate)
for i,v in enumerate(word):
if i % 2 != 0:
word2+= v.upper()
# Can be word2+=v.capitalize() in your case
# only as your text is only one character long.
else:
word2+= v
Using lists
wordlist = list(word)
for i,v in enumerate(wordlist):
if i % 2 != 0:
wordlist[i]= v.upper()
# Can be wordlist[i]=v.capitalize() in your case
# only as your text is only one character long.
word2 = "".join(wordlist)
A short note on capitalize and upper.
From the docs capitalize
Return a copy of the string with its first character capitalized and the rest lowercased.
So you need to use upper instead.
Return a copy of the string with all the cased characters converted to uppercase.
But in your case both work accurately. Or as Padraic puts it across "there is pretty much no difference in this example efficiency or output wise"
You need enumerate and capitalise any character at any odd i where i is the index of each char in the word:
word = "foobar"
print("".join( ch.upper() if i % 2 else ch for i, ch in enumerate(word)))
fOoBaR
ch.upper() if i % 2 else ch is a conditional expression where we change the char if the condition is True or else leave as is.
You cannot i % 2 when i is the actual character from the string, you would need to use range in your code or use enumerate and concatenate the changed characters to an output string or make words a list.
Using a list you can use assignment:
word = "foobar"
word = list(word)
for i, ele in enumerate(word):
if i % 2:
word[i] = ele.upper()
print("".join(word))
Using an output string:
word = "foobar"
out = ""
for i, ele in enumerate(word):
if i % 2:
out += ele.upper()
else:
out += ele
if i % 2: is the same as writing if i % 2 != 0.
This is how I would change word letters in a word or a sentence to uppercase
word = "tester"
letter_count = 1
new_word = []
for ch in word:
if not letter_count % 2 == 0:
new_word.append(ch.upper())
else:
new_word.append(ch)
letter_count += 1
print "".join(new_word)
if I wanted to change odd words in a sentence to uppercase I would do this
sentence = "this is a how we change odd words to uppercase"
sentence_count = 1
new_sentence = []
for word in sentence.split():
if not sentence_count % 2 == 0:
new_sentence.append(word.title() + " ")
else:
new_sentence.append(word + " ")
sentence_count += 1
print "".join(new_sentence)
I think it will help...
s = input("enter a string : ")
for i in range(0,len(s)):
if(i%2!=0):
s = s.replace(s[i],s[i].upper())
print(s)

How Do I Fix This String Issue in Python?

I am trying to add text with vowels in certain words (that are not consecutive vowels like ie or ei), for example:
Word: 'weird'
Text to add before vowel: 'ib'
Result: 'wibeird'
Thus the text 'ib' was added before the vowel 'e'. Notice how it didn't replace 'i' with 'ib' because when the vowel is consecutive I don't want it to add text.
However, when I do this:
Word: 'dog'
Text to add before vowel: 'ob'
Result: 'doboog'
Correct Result Should Be: 'dobog'
I've been trying to debug my program but I can't seem to figure out the logic in order to make sure it prints 'wibeird' and 'dobog' correctly.
Here is my code, substitute first_syl with 'ob' and word with 'dog' after you run it first with 'weird.
first_syl = 'ib'
word = 'weird'
vowels = "aeiouAEIOU"
diction = "bcdfghjklmnpqrstvwxyz"
empty_str = ""
word_str = ""
ch_str = ""
first_vowel_count = True
for ch in word:
if ch in diction:
word_str += ch
if ch in vowels and first_vowel_count == True:
empty_str += word_str + first_syl + ch
word_str = ""
first_vowel_count = False
if ch in vowels and first_vowel_count == False:
ch_str = ch
if word[-1] not in vowels:
final_str = empty_str + ch_str + word_str
print (final_str)
I am using Python 3.2.3. Also I don't want to use any imported modules, trying to do this to understand the basics of strings and loops in python.
Have you considered regular expressions?
import re
print (re.sub(r'(?<![aeiou])[aeiou]', r'ib\g<0>', 'weird')) #wibeird
print (re.sub(r'(?<![aeiou])[aeiou]', r'ob\g<0>', 'dog')) #dobog
Never use regex when you don't have to. There's a famous quote that goes
Some people, when confronted with a problem, think
“I know, I'll use regular expressions.” Now they have two problems.
This can easily be solved with basic if-then statements. Here's a commented version explaining the logic being used:
first_syl = 'ib' # the characters to be added
word = 'dOg' # the input word
vowels = "aeiou" # instead of a long list of possibilities, we'll use the
# <string>.lower() func. It returns the lowercase equivalent of a
# string object.
first_vowel_count = True # This will tell us if the iterator is at the first vowel
final_str = "" # The output.
for ch in word:
if ch.lower() not in vowels: # If we're at a consonant,
first_vowel_count = True # the next vowel to appear must be the first in
# the series.
elif first_vowel_count: # So the previous "if" statement was false. We're
# at a vowel. This is also the first vowel in the
# series. This means that before appending the vowel
# to output,
final_str += first_syl # we need to first append the vowel-
# predecessor string, or 'ib' in this case.
first_vowel_count = False # Additionally, any vowels following this one cannot
# be the first in the series.
final_str += ch # Finally, we'll append the input character to the
# output.
print(final_str) # "dibOg"

Categories