How add "." before each letter in string - python

as title says i simply need to add a . before each letter in my string
while having vowels removed and making it lowercase
i got it working just cant add the .s there
here is my code
s = str(input())
vowels = ('a','e','o','u','i','A','E','O','U','I')
for letter in s:
if letter in vowels:
s = s.replace(letter,'').replace()
print(s)

Use:
s = input()
vowels = set('aeoui')
print(''.join([f'.{x}' for x in s.lower() if x not in vowels]))
Sample run:
Hello
.h.l.l

All other answers will insert a . in front of every character in the string, but you specified that you want letters only. So I am assuming that you only want a-z to be prepended with a . for which I suggest re.sub:
import re
s = "This is some test string. It contains some symbols also ()!!"
result = re.sub('[aeoui]', '', s.lower()) # remove vowels and make lowercase
result = re.sub("([a-z])", r".\1", result) # prepend '.' to every letter
print(result)
Outputs:
.t.h.s .s .s.m .t.s.t .s.t.r.n.g. .t .c.n.t.n.s .s.m .s.y.m.b.l.s .l.s ()!!

You can do it step by step:
Replace all the vowels in the string with ''
for i in s:
for j in vowels:
s=s.replace(j,'')
Convert the string into lowercase:
s=s.lower()
Adding '.' in between each letters:
s='.' + '.'.join(s)

Related

Python String adjust

Hello is use some method like .isupper() in a loop, or string[i+1] to find my lower char but i don't know how to do that
input in function -> "ThisIsMyChar"
expected -> "This is my char"
I´ve done it with regex, could be done with less code but my intention is readable
import re
def split_by_upper(input_string):
pattern = r'[A-Z][a-z]*'
matches = re.findall(pattern, input_string)
if (matches):
output = matches[0]
for word in matches[1:]:
output += ' ' + word[0].lower() + word[1:]
return output
else:
return input_string
print(split_by_upper("ThisIsMyChar"))
>> split_by_upper() -> "This is my char"
You could use re.findall and str.lower:
>>> import re
>>> s = 'ThisIsMyChar'
>>> ' '.join(w.lower() if i >= 1 else w for i, w in enumerate(re.findall('.[^A-Z]*', s)))
'This is my char'
You should first try by yourself. If you didn't get it done, you can do something like this:
# to parse input string
def parse(str):
result= "" + str[0];
for i in range(1, len(str)):
ch = str[i]
if ch.isupper():
result += " ";
result += ch.lower();
return result;
# input string
str = "ThisIsMyChar";
print(parse(str))
First you need to run a for loop and check for Uppercase words then when you find it just add a space at the starting, lower the word and increment it to your new string. Simple, more code is explained in comments in the code itself.
def AddSpaceInTitleCaseString(string):
NewStr = ""
# Check for Uppercase string in the input string char-by-char.
for i in string:
# If it found one, add it to the NewStr variable with a space and lowering it's case.
if i.isupper(): NewStr += f" {i.lower()}"
# Else just add it as usual.
else: NewStr += i
# Before returning the NewStr, remove all the leading and trailing spaces from it.
# And as shown in your question I'm assuming that you want the first letter or your new sentence,
# to be in uppercase so just use 'capitalize' function for it.
return NewStr.strip().capitalize()
# Test.
MyStr = AddSpaceInTitleCaseString("ThisIsMyChar")
print(MyStr)
# Output: "This is my char"
Hope it helped :)
Here is a concise regex solution:
import re
capital_letter_pattern = re.compile(r'(?!^)[A-Z]')
def add_spaces(string):
return capital_letter_pattern.sub(lambda match: ' ' + match[0].lower(), string)
if __name__ == '__main__':
print(add_spaces('ThisIsMyChar'))
The pattern searches for capital letters ([A-Z]), and the (?!^) is negative lookahead that excludes the first character of the input ((?!foo) means "don't match foo, ^ is "start of line", so (?!^) is "don't match start of line").
The .sub(...) method of a pattern is usually used like pattern.sub('new text', 'my input string that I want changed'). You can also use a function in place of 'new text', in which case the function is called with the match object as an argument, and the value returned by the function is used as the replacement string.
The expression capital_letter_pattern.sub(lambda match: ' ' + match[0].lower(), string) replaces all matches (all capital letters except at the start of the line) using a lambda function to add a space before and make the letter lowercase. match[0] means "the entirety of the matched text", which in this case is the captial letter.
You can split it via Regex using r"(?<!^)(?=[A-Z])" pattern:
import re
txt = 'ThisIsMyChar'
c = re.compile(r"(?<!^)(?=[A-Z])")
first, *rest = map(str.lower, c.split(txt))
print(f'{first.title()} {" ".join(rest)}')
Pattern explanation:
(?<!^) checks to see if it is not at the beginning.
(?=[A-Z]) checks to see there a capital letter after it.
note These are non-capturing groups.

How do I send a character from a string that is NOT a letter or a number to the end of the string?

I am doing a Pig Latin code in which the following words are supposed to return the following responses:
"computer" == "omputercay"
"think" == "inkthay"
"algorithm" == "algorithmway"
"office" == "officeway"
"Computer" == "Omputercay"
"Science!" == "Iencescay!"
However, for the last word, my code does not push the '!' to the end of the string. What is the code that will make this happen?
All of them return the correct word apart from the last which returns "Ience!Scay!"
def pigLatin(word):
vowel = ("a","e","i","o","u")
first_letter = word[0]
if first_letter in vowel:
return word +'way'
else:
l = len(word)
i = 0
while i < l:
i = i + 1
if word[i] in vowel:
x = i
new_word = word[i:] + word[:i] + "ay"
if word[0].isupper():
new_word = new_word.title()
return new_word
For simplicity, how about you check if the word contains an exlamation point ! at the end and if it does just remove it and when you are done add it back. So instead of returning just check place ! at the end (if you discovered it does at the beggining).
def pigLatin(word):
vowel = ("a","e","i","o","u")
first_letter = word[0]
if first_letter in vowel:
return word +'way'
else:
hasExlamation = False
if word[-1] == '!':
word = word[:-1] # removes last letter
hasExlamation = True
l = len(word)
i = 0
while i < l:
i = i + 1
if word[i] in vowel:
x = i
new_word = word[i:] + word[:i] + "ay"
if word[0].isupper():
new_word = new_word.title()
break # do not return just break out of the `while` loop
if hasExlamation:
new_word += "!" # same as new_word = new_word + "!"
return new_word
That way it does not treat ! as a normal letter and the output is Iencescay!. You can of course do this with any other character similarly
specialCharacters = ["!"] # define this outside the function
def pigLatin():
# all of the code above
if word in specialCharacters:
hasSpecialCharacter = True
# then you can continue the same way
Regular expressions to the rescue. A regex pattern with word boundaries will make your life much easier in this case. A word boundary is exactly what it sounds like - it indicates the start- or end of a word, and is represented in the pattern with \b. In your case, the ! would be such a word boundary. The "word" itself consists of any character in the set a-z, A-Z, 0-9 or underscore, and is represented by \w in the pattern. The + means, one or more \w characters.
So, if the pattern is r"\b\w+\b", this will match any word (consisting of any of a-zA-Z0-9_), with leading or succeeding word boundaries.
import re
pattern = r"\b\w+\b"
sentence = "computer think algorithm office Computer Science!"
print(re.findall(pattern, sentence))
Output:
['computer', 'think', 'algorithm', 'office', 'Computer', 'Science']
>>>
Here, we're using re.findall to get a list of all substrings that matched the pattern. Notice, no whitespace or punctuation is included.
Let's introduce re.sub, which takes a pattern to look for, a string to look through, and another string with which to replace any match it finds. Instead of a replacement-string, you can instead pass in a function. This function must take a match object as a parameter, and must return a string with which to replace the current match.
import re
pattern = r"\b\w+\b"
sentence = "computer think algorithm office Computer Science!"
def replace(match):
return "*" * len(match.group())
print(re.sub(pattern, replace, sentence))
Output:
******** ***** ********* ****** ******** *******!
>>>
That's just for demonstration purposes.
Let's change gears for a second:
from string import ascii_letters as alphabet
print(alphabet)
Output:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
>>>
That's handy for creating a string containing only consonants:
from string import ascii_letters as alphabet
consonants = "".join(set(alphabet) ^ set("aeiouAEIOU"))
print(consonants)
Output:
nptDPbHvsxKNWdYyrTqVQRlBCZShzgGjfkJMLmFXwc
>>>
We've taken the difference between the set of all alpha-characters and the set of only vowels. This yields the set of only consonants. Notice, that the order of the characters it not preserved in a set, but it doesn't matter in our case, since we'll be effectively treating this string as a set - testing for membership (if a character is in this string, it must be a consonant. The order does not matter).
Let's take advantage of this, and modify our pattern from earlier. Let's add two capturing groups - the first will capture any leading consonants (if they exist), the second will capture all remaining alpha characters (consonants or vowels) before the terminating word boundary:
import re
from string import ascii_letters as alphabet
consonants = "".join(set(alphabet) ^ set("aeiouAEIOU"))
pattern = fr"\b([{consonants}]*)(\w+)\b"
word = "computer"
match = re.match(pattern, word)
if match is not None:
print(f"Group one is \"{match.group(1)}\"")
print(f"Group two is \"{match.group(2)}\"")
Output:
Group one is "c"
Group two is "omputer"
>>>
As you can see, the first group captured c, and the second group captured omputer. Separating the match into two groups will be useful later when we construct the pig-latin translation. We can get even cuter by naming our capturing groups. This isn't required, but it will make things a bit easier to read later on:
pattern = fr"\b(?P<prefix>[{consonants}]*)(?P<rest>\w+)\b"
Now, the first capturing group is named prefix, and can be accessed via match.group("prefix"), rather than match.group(1). The second capturing group is named rest, and can be accessed via match.group("rest") instead of match.group(2).
Putting it all together:
import re
from string import ascii_letters as alphabet
consonants = "".join(set(alphabet) ^ set("aeiouAEIOU"))
pattern = fr"\b(?P<prefix>[{consonants}]*)(?P<rest>\w+)\b"
sentence = "computer think algorithm office Computer Science!"
def to_pig_latin(match):
rest = match.group("rest")
prefix = match.group("prefix")
result = rest + prefix
if len(prefix) == 0:
# if the 'prefix' capturing group was empty
# the word must have started with a vowel
# so, the suffix is 'way'
result += "way"
# that also means we need to check if the first character...
# ... (which must be in 'rest') was upper-case.
if rest[0].isupper():
result = result.title()
else:
result += "ay"
if prefix[0].isupper():
result = result.title()
return result
print(re.sub(pattern, to_pig_latin, sentence))
Output:
omputercay inkthay algorithmway officeway Omputercay Iencescay!
>>>
That was the verbose version. The definition of to_pig_latin can be shortened to:
def to_pig_latin(match):
rest = match.group("rest")
prefix = match.group("prefix")
return (str, str.title)[(prefix or rest)[0].isupper()](rest + prefix + "way"[bool(prefix):])

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

Python: String manipulation difficulty

I have a function here which should change every letter in the string, apart from the first letter of each word, to an underscore. However, it does not seem to work.
def nameManipulate(title):
positions = []
for letter in range(len(title)):
if title[letter] == " ":
positions.append(letter+1)
positions.insert(0, 0)
print(positions) # Positions of first word of each letter in the string
for letter in range(len(title)):
if letter not in positions: # If the letter is not in the list
new_title = title.replace(str(title[letter]), "_") # Replace the letter with an underscore
return new_title
displayTitle = str(nameManipulate(title))
(the title variable has already been declared and works fine)
The code however doesn't seem to work. It creates an array of positions of all the letters which are at the beginning of the word and changes all those not in that list to an underscore, or should, in theory.
However, when I run the code, this is the output.
(The title in this case was "Jonny B Good")
[0, 6, 8]
Jonny B Goo_
Any help would be greatly appreciated, thank you.
Just use regex.
import re
print( re.sub(r"((?<!\b)\w+)", lambda m: len(m.group(1))*"_", "Johnny B Goode") )
(?<!\b)\w+ (negative lookbehind) matches one or more characters \w+ that is not preceded by an \b (word boundary), m in lambda m: ... is re.Match
object which contains groups we matched with () (capturing group), we return "_" repeated len(m.group(1)) times, and substitute.
You're only actually replacing the last letter. That's because of your final loop and return statement:
for letter in range(len(title)):
if letter not in positions: # If the letter is not in the list
new_title = title.replace(str(title[letter]), "_") # Replace the letter with an underscore
return new_title
You clearly intend new_title to collect all the changes in the loop - but you're actually assigning it to the result of replace on title, which is the original string. As a result, the only change you ever see in the final value is the last one.
The solution is simple: just assign the value in the title variable to new_title before the loop starts, and use that string's replace method. That way, new_title will accumulate all the changes:
new_title = title
for letter in range(len(title)):
if letter not in positions: # If the letter is not in the list
new_title = new_title.replace(str(new_title[letter]), "_") # Replace the letter with an underscore
return new_title
This actually still won't work as intended in all cases, because replace replaces the first occurrence of the given letter, not necessarily the one at the particular position you intend. I'll leave you to solve that yourself, but hopefully this helps you over that first hurdle.
Managed to fix it, it was a problem with the loop.
Rather than:
for letter in range(len(title)):
if letter not in positions: # If the letter is not in the list
new_title = title.replace(str(title[letter]), "_") # Replace the letter with an underscore
You should declare the new_title variable first, and have it in all instances of the .replace method.
def nameManipulate(title):
positions = []
new_title = title
for letter in range(len(title)):
if title[letter] == " ":
positions.append(letter+1)
positions.insert(0, 0)
print(positions) # Positions of first word of each letter in the string
for letter in range(len(title)):
if letter not in positions: # If the letter is not in the list
if title[letter] != " ":
new_title = new_title.replace(str(title[letter]), "_") # Replace the letter with an underscore
return new_title
I would just use regex for this
import re
title = "Johnny B Goode."
print(re.sub("([a-zA-Z])([a-zA-Z]+)",lambda m:m.group(1)+"_"*len(m.group(2)),title))
Your algorithm does not work correctly, if the one replaced character is also a starting character.
def nameManipulate(title):
result = []
replace = False
for character in title:
if character == " ":
replace = False
elif not replace:
replace = True
else:
character = "_"
result.append(character)
return "".join(result)

How did I go off-by-one when prepending to a string in a loop?

I am trying to write a program to take a string; find and remove vowel in string, change capital letter to small letter and added "." before each letter. Here's the code:
input_string = "aBAcAba"
vowel = ["a","e","i","o","u"]
list = list(input_string.lower())
for letter in list:
if letter in vowel:
list.remove(letter)
result = ".".join(list)
print (result)
When I run this, I get:
b.c.b
But the desired result is:
.b.c.b
Why isn't . added before the first letter, and how can I fix it?
Instead of removing in place, use a list comprehension to create a new list:
input_string = "aBAcAba"
vowel = {"a","e","i","o","u"}
new_string = ''.join(["."+i.lower() for i in input_string if i.lower() not in vowel])
Output:
'.b.c.b'
Also, changing vowel from a list to a set improves the overall lookup time.
more simply
input_string = "aBAcAba"
vowel = ["a","e","i","o","u"]
list = list(input_string.lower())
for letter in list:
if letter in vowel:
list.remove(letter)
result = "."+".".join(list)
print (result)
result = ".".join(list)
will not add "." before each letter, but will result like you are getting.
if you want "." in starting also you can add extra "."
result="."+".".join(list)
If you just neeed to print it, you can add the '.' on the fly when printing it like this:
print ('', *L, sep=".") # L being the list of remaining non-vowels
This will not create a string though as print() does not return the printed string. The other answers cover how to get the string already. I would still go for a list comprehension to create the partial list:
input_string = "aBAcAba"
vowel = ["a","e","i","o","u"]
L = [c.lower() for c in input_string if c not in vowel]
print ('', *L, sep=".") # *L unpacks it to: print('','b','c','b', sep =".") for your data
The *L will unpack the list, the '' before will add an empty string before it. By declaring a sep="." print will seperate each thing it prints by a '.'
Output:
.b.c.b
inp = 'aBAcAba'
vowels = ['a', 'e', 'i', 'o', 'u']
'.'+'.'.join([c for c in inp.lower() if c not in vowels])
Basically the last line does the trick, it converts input to lower case, check character by character if it's a vowel, finally joins the list to output a string. additional '.' is added at the beginning of the string.
You can also use regular expressions to do that.
Code:
import re
input_string = "aBAcAba"
consonants = re.sub(r'[aeoiu]', '', input_string.lower())
result = f".{'.'.join(consonants)}"
I formatted the result using a Python 3.6+ feature called Literal String Interpolation. I encourage you to find out more about it.
Output:
>>> result
'.b.c.b.'
r'[aeoiuy]' is a pattern that matches one of the vowels within the square brackets.
You can read more about regular expressions here and use this site to test if they match the string.

Categories