How to uppercase even letter and lowercase odd letter in a string? - python

I am creating a function that takes in a string and returns a matching string where every even letter is uppercase and every odd letter is lowercase. The string only contains letters
I tried a for loop that loops through the length of the string with an if statement that checks if the index is even to return an upper letter of that index and if the index is odd to return a lowercase of that index.
def my_func(st):
for index in range(len(st)):
if index % 2 == 0:
return st.upper()
else:
return st.lower()
I expected to have even letters capitalize and odd letter lowercase but I only get uppercase for the whole string.

Some issues in your code:
Currently you are returning from the function on the first index itself, i.e index=0 when you do return st.lower(), so the function will stop executing after it encounters the first index and breaks out of the for loop
Doing st.lower() or st.upper() ends up uppercasing/lowercasing the whole string, instead you want to uppercase/lowercase individual characters
One approach will be to loop over the string, collect all modified characters in a list, convert that list to a string via str.join and then return the result at the end
You also want to refer to each individual characters via the index.
def my_func(st):
res = []
#Iterate over the character
for index in range(len(st)):
if index % 2 == 0:
#Refer to each character via index and append modified character to list
res.append(st[index].upper())
else:
res.append(st[index].lower())
#Join the list into a string and return
return ''.join(res)
You can also iterate over the indexes and character simultaneously using enumerate
def my_func(st):
res = []
#Iterate over the characters
for index, c in enumerate(st):
if index % 2 == 0:
#Refer to each character via index and append modified character to list
res.append(c.upper())
else:
res.append(c.lower())
#Join the list into a string and return
return ''.join(res)
print(my_func('helloworld'))
The output will be
HeLlOwOrLd

You can store your operations beforehand and use them in join with enumerate:
def my_func(st):
operations = (str.lower, str.upper)
return ''.join(operations[i%2](x) for i, x in enumerate(st))
print(my_func('austin'))
# aUsTiN

Tweaking your code a bit, You can use the 'enumerate' and keep appending to the string based on the condition evaluations( for me this was easier since I have been coding in java :))
def myfunc(st):
str=''
for index, l in enumerate(st):
if index % 2 == 0:
str+=l.upper()
else:
str+=l.lower()
return str

def myfunc(str):
rstr = ''
for i in range(len(str) ):
if i % 2 == 0 :
# str[i].upper()
rstr = rstr + str[i].upper()
else:
#str[i].lower()
rstr = rstr + str[i].lower()
return rstr

l = 'YourString'
li=[]
for index,i in enumerate(l):
if index % 2 == 0:
i=i.lower()
li.append(i)
elif index % 2 == 1:
i=i.upper()
li.append(i)
print(''.join(li))
Use this enumerate method to perform your operation

return will terminate your function, so there isn't much point of the loop
st is the whole string, so st.upper() will yield the whole string in upper case.

You can use a bitwise and (&) to check for odd positions. The enumerate function will give you both the positions and the characters so you can easily use it in a list comprehension:
def upLow(s):
return "".join(c.lower() if i&1 else c.upper() for i,c in enumerate(s))
upLow("HelloWorld") # HeLlOwOrLd

The below code should do what you are looking for.
def myfunc(name):
str=""
lc=1;
for character in name:
if(lc%2==0):
str+=character.upper()
else:
str+=character.lower()
lc+=1
return str

def myfunc(a):
newString = ''
for count, ele in enumerate(a, 0):
if count %2 == 0:
newString += (a[count].lower())
else:
newString += ((a[count].upper()))
return newString

You can deconstruct string into collection of characters, apply transformations and reconstruct string back from them
Logic:
First enumerate() over the string to generate key-value pairs of characters and their positions
Then use comprehensions to loop over them and use conditional statement to return odd position characters in lower() case and even position in upper()
Now you have the list ready. Just join() it with an empty string '' to convert the list into a string
Code:
str = 'testing'
''.join([y.upper() if x%2 ==0 else y.lower() for x,y in enumerate(str)])

Related

Python: iterate through string but need to know index of current character [duplicate]

This question already has answers here:
Accessing the index in 'for' loops
(26 answers)
Closed last year.
I'm iterating through a string and need to perform certain actions if the index number of a given character equals a certain value. However I'm not sure of the best way of keeping track of the current index number during the iteration. For example I need code that broadly does the following:
def myfunc(word):
for n in word:
if n[index] = 0:
do this
elif n[index] = 4:
do this
else:
do this
I just can't seem to find any inbuilt counter or function that allows me to keep track of the current iteration index. I could add a counter in as variable and just +1 after each loop but this seems clunky and I would have thought Python would know the current iteration number of "n" and could report it back?
def myfunc(word):
new_str = "" #null string
for i, c in enumerate(word): #creates a series of tuples, each on contains index# and current character
if i==0 or i==3:
new_str = new_str + c.upper() #add the character to new_str but make uppercase
else:
new_str = new_str + c #just add the existing lowercase character
return new_str
Two ways to do this. Iterate the index i between 0 and the len of the str:
for i in range(len(word)):
c = word[i]
Or use python's enumerate function to do both at once:
for i, c in enumerate(word):
...
Iterate through index and not the elements:
def myfunc(word):
for n in range(len(word)):
if word[n][index] = 0:
do this
elif word[n][index] = 4:
do this
else:
do this
In this way, the index that you want is n
def myfunc(word):
for index in range(len(word)):
if (index==0):
do this
elif (index==4):
do this
else:
do this

even and uneven letter, TypeError: not all arguments converted during string formatting

def ul(a):
if a %2 == 0:
print(a.upper())
else:
print(a.lower())
ul(input())
I get following error:
TypeError: not all arguments converted during string formatting
I want to write every even letter in uppercase and every uneven letter in lowercase
What I'm doing wrong?
What you are now doing with this function is check whether the input (a string) is divisible by 2. This is not really what you wanted to do and it raises an error because strings are not modulo divisible.
You should better loop through the indices of the input string to fill a second string with upper and lower case letters:
def ul(s):
outstring = ''
for i in range(len(s)): ## For each index of the string
if i%2==0:
outstring += s[i].upper() ## Even indices become upper case
else:
outstring += s[i].lower() ## Odd indices become lower case
print(outstring)
ul(input("Enter a string: "))
You are trying to get mode of string as I understand. You should use len(a).
def ul(a):
if len(a) %2 == 0:
print(a.upper())
else:
print(a.lower())
ul(input())
Try this
def ul(a):
a = a.lower()
if ord(a) %2 == 0:
print(a.upper())
else:
print(a.lower())
if you want user to enter only Alphabets, then try this
def ul(a):
if ord(a) >= 110 and ord(a) < 123:
a = a.lower()
if ord(a) %2 == 0:
print(a.upper())
else:
print(a.lower())
else:
print("Please enter Alphabets only")
Input will give you a string. You want to use the modulo operator %, which is exactly how you usually find the evenness of a number. So, you are on the right track!
What actually happens is that Python interprets your % as the format operator (probably has a fancy name).
number = 2
print("Number %d is this" % number)
>>> Number 2 is this
Strings in Python are immutable, so you can't just change the string that easily.
Try this Replacing every 2nd character in a string , where you construct a new string by adding all the individual characters together.
def ul(word):
new = []
for i in range(len(word)):
if i%2 == 0:
new += word[i].upper()
else:
new += word[i].lower()
print("".join(new))
This will go through the string character by character, transform the individual character based on if it is even or not, and then construct a list "new", that holds all the individual characters. In the end, just join it, so create a new string out of the list.
There are more pythonic ways to do this using list comprehension, but for now this is easier to read and understand.

Given a string S, remove consecutive duplicates from it recursively using python

i am adding str[1] that is causing one repeated element to be left but if donot do that string does not get printed. any solutions
def removeCD(str):
l = len(str)
if l == 0 or l == 1:
return str
if(str[0]==str[1]):
return str[1] + removeCD(str[2:])
else:
return str[0] + removeCD(str[1:])
string = input().strip()
print(removeCD(string))
When characters are equal, you again adding duplicate character. This should work:
def removeCD(str):
l = len(str)
if l == 0 or l == 1:
return str
if(str[0]==str[1]):
return removeCD(str[1:])
else:
return str[0] + removeCD(str[1:])
string = input().strip()
print(removeCD(string))
Here is the case analysis we need to perform -
If string length is less than two (base case), there is nothing to compare, simply return the string
Otherwise (by induction) the string is at least two characters long. If the first matches the second, drop the first letter and return the recursive result
Otherwise (by induction) the string is at least two characters long and the first two characters do not match. Return the first char combined with the recursive result.
This encodes to a python program in a straightforward way -
def remove_adjacent_dupes (s = ""):
if len(s) < 2:
return s
elif s[0] == s[1]:
return remove_adjacent_dupes(s[1:])
else:
return s[0] + remove_adjacent_dupes(s[1:])
print(remove_adjacent_dupes("bookkeeper"))
# bokeper
When the characters are equal, you should be recursing on everything but the first character:
if(str[0]==str[1]):
return removeCD(str[1:])
def remove(string):
l = len(string)
if l==0 or l==1:
return string
if string[0] == string[1]:
s = remove(string[1:])
return s
else:
s = remove(string[1:])
return string[0]+s
string = input().strip()
print(remove(string))

Iterate through each letter in the string with even index as uppercase and odd index as lowercase

My homework assignment requires me to iterate through each letter in the string with even index as uppercase and odd index as lowercase. It should leave any punctuation marks or numerals unchanged, and it should change the case of every letter at an even index. That means if the letter is initially uppercase, it should be should be converted to lower case.
For example: mock("Abcd. Efgh.. Ijkl!") would return "abCd. efGh.. IJkL!". The even-index letters (A, C, E, g, j, l) changed case, all other characters were unchanged.
I tried to swapcase it and tries to split them and rejoin the string back. But i couldn't get it work.
def mock(word):
index = 0
result = ''
swap = word.swapcase()
for letter in swap:
if index % 2 == 0:
result += letter.upper()
else:
result += letter.lower()
index += 1
return result
We tested your code with a_str = "Abcd. Efgh.. Ijkl!". We expected mock to return the str "abCd. efGh.. IJkL!". However, it returned the str "aBcD. eFgH.. IjKl!".
Your code currently makes it so letters with odd indexes would become lowercased and letters with even indexes would become uppercased.
If you only want letters on the even indexes to change from lowercase to uppercase or from uppercase to lowercase, you should use the following method:
def mock(word):
index = 0
result = ''
for letter in word:
if index % 2 == 0:
if letter.isupper():
result += letter.lower()
else:
result += letter.upper()
else:
result += letter
index += 1
return result
You increment the index after every character rather than every letter. This includes characters like punctuation, empty spaces, numbers.
You need to add a conditional statement before you increment the index using the isalpha() function:
If letter.isalpha()
Index += 1
Also, you need to add another conditional statement to check if the even letters are already uppercase so that you switch their case.

Python: list index out of range when trying to compare two strings at index?

I have this function to check if a string contains three or more lowercase letters.
def lowerCaseValid(word):
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
i = 0
flag = 0
while i <= len(word):
j = 0
while j <= len(lowCharList):
if lowCharList[j] == word[i]:
flag += 1
j = 0
else:
j += 1
i += 1
if flag >= 3:
return True
In simple terms, I pass in a string (word) and create a list of acceptable characters (lowCharList).
Then, I set up a nested while loop that checks word[i] at every index of lowCharList, until it finds a match.
Then it resets lowCharList counter and adds 1 to flag, and moves on to word[i+1].
If it doesn't find a match by the time it reaches z, then it moves onto word[i+1] anyways.
For some reason, why I try my sample input in my main function.
def main():
word = 'corRe!33'
print(lowerCaseValid(word))
I get this error:
in lowerCaseValid
if lowCharList[j] == word[i]:
IndexError: list index out of range
Why is it throwing this error? Thank you.
using python's in operator is easier...
def lowerCaseValid(word):
cnt = 0
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
chars = lowCharList.pop ()
for ch in word:
if ch in chars:
cnt += 1
return cnt >= 3
or with using sets just 2 lines of code
def lowerCaseValid(word):
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
return len(set(lowCharList.pop()) & set(word)) >=3
or one liner with map and lambda
def lowerCaseValid(word):
return len(list(map(lambda x: x.islower, list(word)))) >=3
Another alternative approach using a list comprehension and string.ascii_lowercase instead of redefining the lowercase letters:
from string import ascii_lowercase
def lowerCaseValid(word):
return sum[x in ascii_lowercase for x in word] >= 3
How this works is that the list comprehension goes through each letter in word. The x in ascii_lowercase will return a boolean value of either True (1) or False (0), then sum up the Trues
Change
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
to
lowCharList = list('abcdefghijklmnopqrstuvwxyz')
I believe this should help, since you have a list containing only 1 item, whereas this way, you create a list with 24 items (all different letters).
As heemayl pointed out in the comments, lowCharList is 1 element long! Now you have 2 options: make lowCharList an actual list (lowCharList = list ("abcd...")), or keep lowCharList a string, which will work just fine (remove the brackets in the definition.
Might I suggest another method: checking if str.islower count adds up to >=3. So:
lower_count = 0
for letter in word:
if letter.islower(): lower_count += 1
if lower_count >= 3: return True
Also, as suggested in the comments:
return len ([letter for letter in word if letter.islower()]) >= 3
would work (better than my answer, which is just the expanded form of it)

Categories