How to get vowels, consonants and other characters from a text - python

I need a program that asks the user to enter any text and then display three strings, the first of which consists of all the vowels from the text, the second, of all consonants, and the third, of all other characters. I have it in a while loop right now, I was wondering how I can transfer that into a for-loop in Python.
text = input("Enter text: ")
# Loop counter
i = 0
# Accumulators
vows_string = ""
cons_string = ""
other_str = ""
while i < len(text):
char = text[i]
if char in "aioueAIOUE":
vows_string += char
elif char.isalpha():
cons_string += char
else:
other_str += char
i += 1
# Add pseudo-guillemets to make spaces "visible"
print(">>" + vows_string + "<<")
print(">>" + cons_string + "<<")
print(">>" + other_str + "<<")

Since strings are iterable, you can replace
while i < len(text):
char = text[i]
with
for char in text:
# no more need for 'i'
By the way, try if char.lower() in "aioue":

Now that the code is simple, let's make it potentially more efficient by using a set() for the vowels instead of a string:
# Vowels Set
vowels = set("aeiouAEIOU")
# Accumulators
vowels_string = ""
consonants_string = ""
other_string = ""
# User Input
text = input("Enter text: ")
# Process Text
for char in text:
if char.isalpha():
if char in vowels:
vowels_string += char
else:
consonants_string += char
else:
other_string += char
# Add pseudo-guillemets to make spaces "visible"
print("<<", vowels_string, ">>", sep="")
print("<<", consonants_string, ">>", sep="")
print("<<", other_string, ">>", sep="")

Related

How to replace all "&int-int" with the respective string slices in an input string?

I have a school project question (for Python) that goes like this:
Given a string_input such as "abcd&1-4efg", the function must remove the "&1-4" and insert the string slice from 1 to 4 where the "&1-4" was.
eg. if string_input = "abcd&1-4efg",
"&1-4" is removed.
The remaining characters are indexed as follows: a=0, b=1, c=2, d=3, e=4, f=5, g=6
The new string becomes:
"abcdbcdeefg"
I've managed to write a long chunk of code to do this, but I'm wondering if anyone has any more efficient solutions?
Things to note:
The instructions can include double digits (eg. &10-15)
If the index isn't found, the returned string should print "?" for every missing index
(eg. "abcd&5-10efgh" would return "abcdfgh???efgh")
Intructions can be back-to-back (eg. "&10-15abcdef&1-5&4-5pqrs")
The code I've written is:
def expand(text):
text += "|"
import string
digits_dash = string.digits + "-"
idx_ref_str = ""
replace_list = []
record_val = False
output_to_list = []
instruct = ""
and_idx_mark = 0
#builds replace_list & idx_ref_list
for idx in range(len(text)):
if text[idx] == "&" and record_val==True:
output_to_list.append(instruct)
output_to_list.append(and_idx_mark)
replace_list.append(output_to_list)
output_to_list, instruct, inst_idx, and_idx_mark = [],"",0,0
and_idx_mark = idx
continue
elif text[idx] == "&":
record_val = True
and_idx_mark = idx
continue
#executes if currently in instruction part
if record_val == True:
#adds to instruct
if text[idx] in digits_dash:
instruct += text[idx]
#take info, add to replace list
else:
output_to_list.append(instruct)
output_to_list.append(and_idx_mark)
replace_list.append(output_to_list)
output_to_list, instruct, inst_idx, and_idx_mark, record_val = [],"",0,0,False
#executes otherwise
if record_val == False:
idx_ref_str += text[idx]
idx_ref_str = idx_ref_str[:-1]
text = text[:-1]
#converts str to int indexes in replace list[x][2]
for item in replace_list:
start_idx = ""
end_idx = ""
#find start idx
for char in item[0]:
if char in string.digits:
start_idx += char
elif char == "-":
start_idx = int(start_idx)
break
#find end idx
for char in item[0][::-1]:
if char in string.digits:
end_idx = char + end_idx
elif char == "-":
end_idx = int(end_idx)
break
start_end_list = [start_idx,end_idx]
item+=start_end_list
#split text into parts in list
count = 0
text_block = ""
text_block_list = []
idx_replace = 0
for char in text:
if char == "&":
text_block_list.append(text_block)
text_block = ""
count += len(replace_list[idx_replace][0])
idx_replace +=1
elif count > 0:
count -= 1
else:
text_block += char
text_block_list.append(text_block)
#creates output str
output_str = ""
for idx in range(len(text_block_list)-1):
output_str += text_block_list[idx]
#creates to_add var to add to output_str
start_repl = replace_list[idx][1]
end_repl = replace_list[idx][1] + len(replace_list[idx][0])
find_start = replace_list[idx][2]
find_end = replace_list[idx][3]
if end_idx >= len(idx_ref_str):
gap = end_idx + 1 - len(idx_ref_str)
to_add = idx_ref_str[find_start:] + "?" * gap
else:
to_add = idx_ref_str[find_start:find_end+1]
output_str += to_add
output_str += text_block_list[-1]
return output_str
Here's how I would do it. Always open to criticism.
import re
s = 'abcd&1-4efg'
c = re.compile('&[0-9]+-[0-9]+')
if (m := c.search(s)):
a, b = m.span()
left = s[:a]
right = s[b:]
o = [int(x) for x in m.group(0)[1:].split('-')]
mid = (left+right)[o[0]:o[1]+1]
print(left + mid + right)

Best approach for converting lowerCamelCase to snake_case

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()

Replace a sequence of characters by another one

I have a sequence of characters '-------' and i want to replace each '-' in it by each letter in 'jaillir' in the correct range.
How do i do that ?
Here is my code
import random
with open ("lexique.txt", "r", encoding= "utf8") as a:
words = []
letters = []
tirets= []
for line in a:
ligne = line[:-1]
words.append(ligne)
choix = random.choice(words)
tiret = ('-'* len(choix))
print(tiret)
print(choix)
accompli = False
while not accompli:
lettre = input("Entrez une lettre du mot ")
for t in range(len(tiret)):
if lettre in choix:
tiret.replace(tiret[t], lettre[t])
print(tiret)
I think you need to fix your file reading code, even though it is not the question, as below:
with open('lexique.txt', r) as f:
text = f.read() # get file contents
Next to replace the ---- by a word, I am assuming that the dashes in your text will only ever be the same length as the word, so:
word = 'word' # any string e.g. word
dashes = '-' * len(word)
So now you can use python's string.replace method like so:
text = text.replace(dashes, word) # every time it finds the sequence of dashes it will be replaced by your word
With a for loop (gradual replacement):
word = 'word' # any word
length = len(word)
temp = ''
for i, letter in enumerate(text):
if letter == '-':
if i + len(tempword) < len(text):
characters = [True if l == '-' else False for l in text[i:i + len(tempword)]]
if not(False in characters):
new += tempword[0]
if len(tempword) > 1:
tempword = tempword[1:]
else:
tempword = word
else:
new += letter
else:
new += letter
print(new)

Replace all spaces in a string with underscores

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

How can I make this code shorter (less lines etc)

I am writing a code and want to make it as short as possible, is there any way i can?
text = raw_input("Give me some text > ")
list1 = []
for char in text:
num = ord(char)
if num in range(48,57):
print "ERROR 319: Number entered"
quit()
elif num in range(65,90) or num in range (97,122):
upper = char.upper()
list1.append(upper)
num1 = 0
vowelCount = 0
conCount = 0
for x in range(len(list1)):
if list1[num1] == "A" or list1[num1] == "E" or list1[num1] == "I" or list1[num1] == "O" or list1[num1] == "U":
vowelCount = vowelCount + 1
else:
conCount = conCount + 1
num1 = num1 + 1
print "Vowels: " +str(vowelCount) + " Consonants: " + str(conCount)
Instead of taking ord() of the character, you can use the string methods:
char.isdigit() # check if a char is a digit
char.isalpha() # check if char is letter
For checking the vowel counts, try:
vowel_count = len(filter(lambda c: c in "aeiou", list1))
cons_count = len(list1) - vowel_count
Building off of AmourK's answer, you could do something like this:
text = raw_input("Give me some text > ")
vowel_count = len(filter(lambda c: c in "aeiou", text))
cons_count = len(filter(lambda c: c not in "aeiou" and c.isalpha(), text))
print "Vowels: %d Consonants: %d" % (vowel_count, cons_count)

Categories