Replacing Odd and Even-indexed characters in a string - python

How can I replace even and odd-indexed letters in my strings? I'd like to replace odd-indexed characters with uppercased letters and even-indexed characters with lowercased ones.
x=input("Enter String: ")
How can I modify the inputted string?

This sounds a little like a "do my homework for me" post, but I'll help you out, as I need the training myself.
You can do this by breaking down the problem. (As I am quite new with python syntax, I'm gonna assume that the user has already given an input to string x)
Make a loop, or otherwise iterate through the characters of your string
Make sure you have an index number for each character, which increments for each one
Check if the number is even, by using modulus of 2 (%2). This returns the remainder of a number when divided by 2. In the case of even numbers, that will be 0.
If %2 == 0 set letter to lower case, else set letter to upper case.
append letter to new String, which you defined before the loop. You cannot directly alter a single character in a String, because they are immutable. This means that you cannot change the String itself, but you can assign a new String to the variable.
Done. Print and see if it worked.
Code:
x = "seMi Long StRing WiTH COMPLetely RaNDOM CasINg"
result_string = ""
index = 0;
for c in x:
if(index%2 == 0):
result_string += c.lower()
else:
result_string += c.upper()
index+=1
print(result_string)

s=input()
l=[]
s=s.lower()
l=[i.upper() if s.index(i)%2==0 else i for i in s ]
print("".join(l))

x = 'myname'
for item in range(len(x)):
if item%2==0:
print(x[item].upper())
else:
print(x[item].lower())
this is the for loop i was referring to. but the thing with this line of code is that it is specific to the value you have assigned to the variable x where as the function i provided above can take any string value without us having to repeat the code each time.

def myfunc(string):
result=''
for x in range(len(string)):
if x%2==0:
result=result+string[x].upper()
else:
result=result+string[x].lower()
return result
The above is a function for the question you asked.
A non-function for loop might be easier to grasp right now (like you I am very new to Python as well. So for me it was easier to understand the for loop before I got into functions. Look at my next post for the same.

Related

Palindrome Coding issue

Writing a program:
Input string from the user
print out whether this string is a palindrome or not
Also, I found a few other codes online but want to work with this code only.m Please let me know the error
i = str(input())
for item in i:
print(item)
if int(i[item]) == int(i[-item]):
print('yes')
else:
print('no')
Use a String slice (The i[::-1] will reverse the string):
i = input()
if i == i[::-1]:
print("Yes")
else:
print("No")
This will take the input from the user and compare it against the same input in reverse.
try this:
word="TOT"
i=word[::-1]
if i==word:
print("palandrom")
Although for item in i: loops through every character in the string, there are several problems with your code line if int(i[item]) == int(i[-item]):. First of all, item is going to be a character from your string. So if the user types "hello", then i[item] first looks for i['h']. Since 'h' is a character and not a number, this makes Python think that i is a dictionary and not a string, and thus tells Python to look for a dictionary named i and return the value where the key is h. That won't work since i is your original string, not a dictionary.
It looks like what you meant to do here is compare i[0] (the first character in the string) to i[-1] (the last character in the string), then i[1] to i[-2], and so on. But even you if looped through the position numbers, i[-item] doesn't mathematically give you what you want.
Yet another issue here is that you're checking each character one at a time and returning "yes" or "no". What you ultimately want though is to output one simple answer: whether your string is a palindrome or not.
Also, there's no need to put str() around input(), since input returns a string anyway, even if the user enters only numerals. By the way, even though you're using i as your string variable, the usual convention in programming is to use i to denote some sort of integer, such as one you're iterating through in a for loop. But that's OK for now.
As some of the other answers have shown, i[::-1] is a quick way to return the reverse of a string itself. So if you're OK with seeing the output return True if the string is a palindrome and False if it isn't, then here's an extremely simple way to do it:
i = input()
print(i == i[::-1])
If the string i is identical to itself reversed, then i == i[::-1] returns True. If not, it returns False. The print statement then prints whichever the answer is.
However, if you really do want to do it the long way, testing character by character in a loop, then here's one way to do it. You could make a function that takes in a string and does the work:
def is_palindrome(mystring):
# The "//2" here divides by 2 and ignores the remainder. So if
# there are an even number of letters, we'll test each pair. If
# It's an odd number, then we don't care about the middle character
# anyway. Compare [0] to [-1], then [1] to [-2], [2] to [-3], and so on.
for position in range(0, len(mystring)//2):
# If we've found a mismatched pair of letters, then we can
# stop looking; we know it's not a palindrome.
if mystring[position] != mystring[(-1 * position) - 1]:
print("This is NOT a palindrome")
return # This breaks you out of the entire function.
# If we've gotten this far, then the word must be a palindrome.
print("This is a palindrome")
# Here's where we run the command to input the string, and run the function
mystring = input("Enter your string: ")
is_palindrome(mystring)

Error:string index out of range, defining a function

I'm practicing coding on codingbat.com since I'm a complete beginner in python, and here is one of the exercises:
Given a string, return a new string made of every other char starting with the first, so "Hello" yields "Hlo".
Here is my attempt at defining the function string_bits(str):
def string_bits(str):
char = 0
first = str[char]
for char in range(len(str)):
char += 2
every_other = str[char]
return (first + every_other)
Running the code gives an error. What's wrong with my code?
A different approach, with an explanation:
If you need to handle a sentence, where spaces would be included, you can do this using slicing. On a string slicing works as:
[start_of_string:end_of_string:jump_this_many_char_in_string]
So, you want to jump only every second letter, so you do:
[::2]
The first two are empty, because you just want to step every second character.
So, you can do this in one line, like this:
>>> " ".join(i[::2] for i in "Hello World".split())
'Hlo Wrd'
What just happened above, is we take our string, use split to make it a list. The split by default will split on a space, so we will have:
["Hello", "World"]
Then, what we will do from there, is using a comprehension, iterate through each item of the list, which will give us a word at a time, and from there we will perform the desired string manipulation per i[::2].
The comprehension is: (documentation)
i[::2] for i in "Hello World".split()
Finally, we call "".join (doc), which will now change our list back to a string, to finally give us the output:
"Hlo Wrd"
Check out the slicing section from the docs: https://docs.python.org/3/tutorial/introduction.html
The problem is that the char += 2 returns a value greater than len(str) as len(str)-1 (the range) + 2 is longer than the string. You could do:
def string_bits(string):
if len(string) == 2:
return string[0]
result = ''
for char in range(0,len(string),2):#range created value sin increments of two
result += string[char]
return result
A more succinct method would be:
def string_bits(string):
return string[::2]
You should avoid using 'str' as a variable name as it is a reserved word by Python.
Ok, for me:
You should not use str as a variable name as it is a python built-in function (replace str by my_str for example)
For example, 'Hello' length is 5, so 0 <= index <= 4. Here you are trying to access index 3+2=5 (when char = 3) in your for loop.
You can achieve what you want with the following code:
def string_bits(my_str):
result = ""
for char in range(0, len(my_str), 2):
result += my_str[char]
return result
The error you are getting means that you are trying to get the nth letter of a string that has less than n characters.
As another suggestion, strings are Sequence-types in Python, which means they have a lot of built-in functionalities for doing exactly what you're trying to do here. See Built-in Types - Python for more information, but know that sequence types support slicing - that is, selection of elements from the sequence.
So, you could slice your string like this:
def string_bits(input_string):
return input_string[::2]
Meaning "take my input_string from the start (:) to the end (:) and select every second (2) element"

Write a program that determines how many vowels and consonants in a string python

Write a program with a function that accepts a string as an argument and returns the number of vowels that the string contains. The application should have another function that accepts a string as an argument and returns the number of consonants that the string contains. The application should let the user enter a string and should display the number of vowels and the number of consonants it contains.
Here is my code I have so far:
def main():
mystr = input('Please enter a string: ')
mystr.lower()
index = 0
vowelSet = set(['a','e','i','o','u'])
vowels = 0
consonants = 0
def runVowels(mystr):
while index < len(mystr):
if mystr[index] in vowels:
vowels += 1
index += 1
print('This string consists of ' + mystr(vowels) + 'vowels')
def runConsonants(mystr):
while index < len(mystr):
if mystr[index] != vowels:
consonants += 1
index += 1
print('This string consists of ' + mystr(consonants) + 'consonants')
main()
Where did I go wrong at and am i on the right track?
You've got multiple problems here.
While you define functions named myVowels and myConsonants, you never call them. You probably want to do that at the end of your main function.
Inside main, mystr.lower() doesn't do anything useful. That function returns a new string, the all-lowercase equivalent to mystr, but you don't store that anywhere. Store it somewhere (whether back to mystr, or into a new variable) so you can use it.
Inside runVowels, the index += 1 comes inside the if statement. So, as soon as you find a consonant, you're going to pass over the if, miss incrementing index, and just loop over the same consonant over and over. Dedent that line. (You have this same bug again in runConsonants, and the same is true for all of the following bugs.)
Inside runVowels, the print call comes inside the while statement, so it's going to print the running total once for each letter, instead of just printing the total at the end. Again, dedent one line.
You create variables named index, vowels and vowelsSet in main, which means they're local to that function. You then access variables with those names in runVowels, where they don't exist. Each function has its own local namespace. Move those assignments from main to runVowels—or pass them into runVowels, the same way you do with mystr.
You create variables named vowels and vowelsSet, but then you try to access them as if they were both called vowels. Keep things straight, use the right names for the right values.
I'm not sure what mystr(vowels) is supposed to do. You can't call a string like a function. I think you wanted the builtin str function here. (However, you may want to look at string formatting, or just look at what happens when you pass multiple arguments to print; you rarely need to concatenate strings the way you're doing.)
I won't guarantee that fixing all of these problems will make your code do what you want—it's certainly necessary, but may not be sufficient.
However, hopefully understanding what's wrong with each of these should help you learn how to spot similar problems yourself (not how to avoid them—unless you're the greatest genius in history, you'll be writing bugs like this until the day you die, you'll just get better at testing, debugging, and fixing them).
The code below was tested on python 2.7.3.
You need to study about variable scoping, you cannot define a variable in one method and use it in another method.
Study a bit about whats the best way to take input from user, sys is a really good library for that
Always, Always initialize your variables before you use them, Have provided comments inline.
def main():
mystr = raw_input("Enter your String:")
mystr.lower()
#index = 0, index is useless here
vowelSet = set(['a','e','i','o','u'])
#vowels = 0, vowels is useless here
#consonants = 0, consonants is useless here
#Either pass vowelSet as argument or define them explicitly in the methods
runVowels(mystr, vowelSet)
runConsonants(mystr, vowelSet)
def runVowels(mystr, vowelSet):
#index, vowels needs to be defined and assigned a default value here
index = 0
vowels = 0
while index < len(mystr):
if mystr[index] in vowelSet:
vowels += 1
# You need to increment index outside of the condition
index += 1
print 'This string consists of ', vowels , 'vowels'
def runConsonants(mystr, vowelSet):
#index, consonants needs to be defined and assigned a default value here
index = 0
consonants = 0
while index < len(mystr):
if mystr[index] not in vowelSet:
consonants += 1
# You need to increment index outside of the condition
index += 1
print 'This string consists of ' , consonants , 'consonants'
main()
Sample Run:
$ python vow.py
Enter your String:aeeiithy
This string consists of 5 vowels
This string consists of 3 consonants
Again, this program only prints number of vowels. If you need number of 'distinct' vowels, it would be a bit different.
Hope this helps !
You're getting closer. You still have the mysterious mystr.lower() inside your loops. You should take it out of the loops, and you need to save the result it returns (the lower-case version of mystr) somewhere,
eg mystr = mystr.lower().
I suggest you do that in main() and then pass the lower-case version to your counting functions.
Once you do that, runVowels() will be almost perfect. runConsonants() still needs a little more work. If a character isn't a vowel doesn't mean that it's necessarily a consonant - it could be a number, a punctuation mark, or a space.
It would be more Pythonic if the loops in your functions looped over the string itself, you don't need the index stuff. Check this out in the interpreter:
mystr = "This is a TEST string"
for letter in mystr:
print(letter)
Also, the question specifies that each of your counting functions should return a number. So runVowels() and runConsonants() should return their counts to main() and let it take care of the printing.
Don't turn this example into your class ;-)
Checking it out might help you get yours working.
def charCounts(mystr):
mystr = mystr.strip().lower()
vowels = 0
cons = 0
for c in mystr:
if c in 'aeiou':
vowels += 1
elif c >= 'a' and c <= 'z':
cons += 1
return vowels, cons
if __name__ == '__main__':
mystr = input('Please enter a string: ')
vowels, cons = charCounts(mystr)
print('This string consists of {0} vowels and {1} consonants'.format(vowels, cons))

Display the number of lower case letters in a string

This is what I have so far:
count=0
mystring=input("enter")
for ch in mystring:
if mystring.lower():
count+=1
print(count)
I figured out how to make a program that displays the number of lower case letters in a string, but it requires that I list each letter individually: if ch=='a' or ch=='b' or ch=='c', etc. I am trying to figure out how to use a command to do so.
This sounds like homework! Anway, this is a fun way of doing it:
#the operator module contains functions that can be used like
#their operator counter parts. The eq function works like the
#'=' operator; it takes two arguments and test them for equality.
from operator import eq
#I want to give a warning about the input function. In python2
#the equivalent function is called raw_input. python2's input
#function is very different, and in this case would require you
#to add quotes around strings. I mention this in case you have
#been manually adding quotes if you are testing in both 2 and 3.
mystring = input('enter')
#So what this line below does is a little different in python 2 vs 3,
#but comes to the same result in each.
#First, map is a function that takes a function as its first argument,
#and applies that to each element of the rest of the arguments, which
#are all sequences. Since eq is a function of two arguments, you can
#use map to apply it to the corresponding elements in two sequences.
#in python2, map returns a list of the elements. In python3, map
#returns a map object, which uses a 'lazy' evaluation of the function
#you give on the sequence elements. This means that the function isn't
#actually used until each item of the result is needed. The 'sum' function
#takes a sequence of values and adds them up. The results of eq are all
#True or False, which are really just special names for 1 and 0 respectively.
#Adding them up is the same as adding up a sequence of 1s and 0s.
#so, map is using eq to check each element of two strings (i.e. each letter)
#for equality. mystring.lower() is a copy of mystring with all the letters
#lowercase. sum adds up all the Trues to get the answer you want.
sum(map(eq, mystring, mystring.lower()))
or the one-liner:
#What I am doing here is using a generator expression.
#I think reading it is the best way to understand what is happening.
#For every letter in the input string, check if it is lower, and pass
#that result to sum. sum sees this like any other sequence, but this sequence
#is also 'lazy,' each element is generated as you need it, and it isn't
#stored anywhere. The results are just given to sum.
sum(c.islower() for c in input('enter: '))
You have a typo in your code. Instead of:
if my.string.lower():
It should be:
if ch.islower():
If you have any questions ask below. Good luck!
I'm not sure if this will handle UTF or special characters very nicely but should work for at least ASCII in Python3, using the islower() function.
count=0
mystring=input("enter:")
for ch in mystring:
if ch.islower():
count+=1
print(count)
The correct version of your code would be:
count=0
mystring=input("enter")
for ch in mystring:
if ch.islower():
count += 1
print(count)
The method lower converts a string/char to lowercase. Here you want to know if it IS lowercase (you want a boolean), so you need islower.
Tip: With a bit of wizardry you can even write this:
mystring= input("enter")
count = sum(map(lambda x: x.islower(), mystring))
or
count = sum([x.islower() for x in mystring])
(True is automatically converted to 1 and False to 0)
:)
I think you can use following method:
mystring=input("enter:")
[char.lower() for char in mystring].count( True ) )

Count occurrences of a given character in a string using recursion

I have to make a function called countLetterString(char, str) where
I need to use recursion to find the amount of times the given character appears in the string.
My code so far looks like this.
def countLetterString(char, str):
if not str:
return 0
else:
return 1 + countLetterString(char, str[1:])
All this does is count how many characters are in the string but I can't seem to figure out how to split the string then see whether the character is the character split.
The first step is to break this problem into pieces:
1. How do I determine if a character is in a string?
If you are doing this recursively you need to check if the first character of the string.
2. How do I compare two characters?
Python has a == operator that determines whether or not two things are equivalent
3. What do I do after I know whether or not the first character of the string matches or not?
You need to move on to the remainder of the string, yet somehow maintain a count of the characters you have seen so far. This is normally very easy with a for-loop because you can just declare a variable outside of it, but recursively you have to pass the state of the program to each new function call.
Here is an example where I compute the length of a string recursively:
def length(s):
if not s: # test if there are no more characters in the string
return 0
else: # maintain a count by adding 1 each time you return
# get all but the first character using a slice
return 1 + length( s[1:] )
from this example, see if you can complete your problem. Yours will have a single additional step.
4. When do I stop recursing?
This is always a question when dealing with recursion, when do I need to stop recalling myself. See if you can figure this one out.
EDIT:
not s will test if s is empty, because in Python the empty string "" evaluates to False; and not False == True
First of all, you shouldn't use str as a variable name as it will mask the built-in str type. Use something like s or text instead.
The if str == 0: line will not do what you expect, the correct way to check if a string is empty is with if not str: or if len(str) == 0: (the first method is preferred). See this answer for more info.
So now you have the base case of the recursion figured out, so what is the "step". You will either want to return 1 + countLetterString(...) or 0 + countLetterString(...) where you are calling countLetterString() with one less character. You will use the 1 if the character you remove matches char, or 0 otherwise. For example you could check to see if the first character from s matches char using s[0] == char.
To remove a single character in the string you can use slicing, so for the string s you can get all characters but the first using s[1:], or all characters but the last using s[:-1]. Hope that is enough to get you started!
Reasoning about recursion requires breaking the problem into "regular" and "special" cases. What are the special cases here? Well, if the string is empty, then char certainly isn't in the string. Return 0 in that case.
Are there other special cases? Not really! If the string isn't empty, you can break it into its first character (the_string[0]) and all the rest (the_string[1:]). Then you can recursively count the number of character occurrences in the rest, and add 1 if the first character equals the char you're looking for.
I assume this is an assignment, so I won't write the code for you. It's not hard. Note that your if str == 0: won't work: that's testing whether str is the integer 0. if len(str) == 0: is a way that will work, and if str == "": is another. There are shorter ways, but at this point those are probably clearest.
First of all you I would suggest not using char or str. Str is a built function/type and while I don't believe char would give you any problems, it's a reserved word in many other languages. Second you can achieve the same functionality using count, as in :
letterstring="This is a string!"
letterstring.count("i")
which would give you the number of occurrences of i in the given string, in this case 3.
If you need to do it purely for speculation, the thing to remember with recursion is carrying some condition or counter over which each call and placing some kind of conditional within the code that will change it. For example:
def countToZero(count):
print(str(count))
if count > 0:
countToZero(count-1)
Keep it mind this is a very quick example, but as you can see on each call I print the current value and then the function calls itself again while decrementing the count. Once the count is no longer greater than 0 the function will end.
Knowing this you will want to keep track of you count, the index you are comparing in the string, the character you are searching for, and the string itself given your example. Without doing the code for you, I think that should at least give you a start.
You have to decide a base case first. The point where the recursion unwinds and returns.
In this case the the base case would be the point where there are no (further) instances of a particular character, say X, in the string. (if string.find(X) == -1: return count) and the function makes no further calls to itself and returns with the number of instances it found, while trusting its previous caller information.
Recursion means a function calling itself from within, therefore creating a stack(at least in Python) of calls and every call is an individual and has a specified purpose with no knowledge whatsoever of what happened before it was called, unless provided, to which it adds its own result and returns(not strictly speaking). And this information has to be supplied by its invoker, its parent, or can be done using global variables which is not advisable.
So in this case that information is how many instances of that particular character were found by the parent function in the first fraction of the string. The initial function call, made by us, also needs to be supplied that information, since we are the root of all function calls and have no idea(as we haven't treaded the string) of how many Xs are there we can safely tell the initial call that since I haven't gone through the string and haven't found any or zero/0 X therefore here's the string entire string and could you please tread the rest of it and find out how many X are in there. This 0 as a convenience could be the default argument of the function, or you have to supply the 0 every time you make the call.
When will the function call another function?
Recursion is breaking down the task into the most granular level(strictly speaking, maybe) and leave the rest to the (grand)child(ren). The most granular break down of this task would be finding a single instance of X and passing the rest of the string from the point, exclusive(point + 1) at which it occurred to the next call, and adding 1 to the count which its parent function supplied it with.
if not string.find(X) == -1:
string = string[string.find(X) + 1:]
return countLetterString(char, string, count = count + 1)`
Counting X in file through iteration/loop.
It would involve opening the file(TextFILE), then text = read(TextFile)ing it, text is a string. Then looping over each character (for char in text:) , remember granularity, and each time char (equals) == X, increment count by +=1. Before you run the loop specify that you never went through the string and therefore your count for the number X (in text) was = 0. (Sounds familiar?)
return count.
#This function will print the count using recursion.
def countrec(s, c, cnt = 0):
if len(s) == 0:
print(cnt)
return 0
if s[-1] == c:
countrec(s[0:-1], c, cnt+1)
else:
countrec(s[0:-1], c, cnt)
#Function call
countrec('foobar', 'o')
With an extra parameter, the same function can be implemented.
Woking function code:
def countLetterString(char, str, count = 0):
if len(str) == 0:
return count
if str[-1] == char:
return countLetterString(char, str[0:-1], count+1)
else:
return countLetterString(char, str[0:-1], count)
The below function signature accepts 1 more parameter - count.
(P.S : I was presented this question where the function signature was pre-defined; just had to complete the logic.)
Hereby, the code :
def count_occurrences(s, substr, count=0):
''' s - indicates the string,
output : Returns the count of occurrences of substr found in s
'''
len_s = len(s)
len_substr = len(substr)
if len_s == 0:
return count
if len_s < len_substr:
return count
if substr == s[0:len_substr]:
count += 1
count = count_occurrences(s[1:], substr, count) ## RECURSIVE CALL
return count
output behavior :
count_occurences("hishiihisha", "hi", 0) => 3
count_occurences("xxAbx", "xx") => 1 (not mandatory to pass the count , since it's a positional arg.)

Categories