I am creating a function
Takes input as a string.
Returns a string.
The return string will have the same number of words as the input string, and the same letters as the input string, but the individual words can be of different length. i.e.
perm_lets("try this") == "ist thry"
is a valid return-value. By "number of words" in a string X, we mean the length of the list X.split(' '), i.e. one more than the number of blank spaces in the string. A "word" means a string of letters with no spaces. Lastly,
Every vowel must be isolated, i.e. immediately beside vowels you have at most spaces and/or consonants.
My function can only shuffle the letters of the input string. I would like to know how to isolate the vowel
import random as rd
def perm_lets(input_string):
nS = ''.join(rd.sample(input_string,len(input_string)))
print(nS)
I expect the output of perm_lets("this is a loop") to be something like "si olo pit ahs" but the actual output is " ph siioaos lt" (spaces in the wrong place and vowels are not isolated).
Brute force randomization with disqualifying tests:
import re
import random
import time
def perm_lets(s):
s = list(s)
start = time.perf_counter()
while True:
random.shuffle(s)
p = ''.join(s)
if ' ' in p: continue # no spaces together
if p.startswith(' ') or p.endswith(' '): continue # don't start or end with space
if re.search(r'[aeiou]{2}',p): continue # no vowels together
elapsed = time.perf_counter() - start
return p,elapsed
print(perm_lets('this is a loop'))
print(perm_lets('i bid you adieu'))
Output (4 runs):
('sopihats o i l', 0.0009378000000026532)
('ade udo ibiyi u', 0.07766600000000068)
('i o ha tpsislo', 0.00026450000000011187)
('o adebudu iyi i', 0.00632540000000148)
('o la sstipi ho', 5.2900000000022374e-05)
('udobida eyi i u', 0.3843909999999937) # 1/3 of a second for a tough sentence
('ipa hts o soli', 0.00028810000000589753)
('idida e obu uyi', 0.18083439999999484)
Note: "adieu louie" has no solution.
Here is one way to attempt what you are after. Separates vowels from consonants, shuffles them for randomness, zips vowels and consonants in a poor attempt to isolate the vowels (but this will fail if there are too many more vowels than consonants), randomly selects word length ensuring minimum of one character per word and that the number of output words is the same as the number of input words.
You could probably do a better job isolating vowels by generating more single vowel words when necessary. However, depending on the vowel to consonant ratio and the number of words, there will always be scenarios where you can't both isolate vowels and output the desired number of words.
from itertools import chain, zip_longest
from random import randint, random, shuffle
s = 'this is a loop'
vowels = []
consonants = []
for char in s.replace(' ', ''):
if char in 'aeiouAEIOU':
vowels.append(char)
else:
consonants.append(char)
shuffle(vowels)
shuffle(consonants)
if len(vowels) > len(consonants) or random() > 0.5:
a, b = vowels, consonants
else:
a, b = consonants, vowels
letters = ''.join([c for c in chain.from_iterable(zip_longest(a, b)) if c])
words = []
for i in range(s.count(' '), -1, -1):
x = randint(1, len(letters) - i)
words.append(letters[:x])
letters = letters[x:]
s = ' '.join(words)
print(s)
# EXAMPLE RANDOM OUTPUT:
# si hipa lo tos
you can do it like this also
separate vowels and consonant using regex
combine each vowels to consonant
shuffle the result until result not starts/ends with space and don't have two spaces together
import random
import re
def perm_lets(st):
ls = re.findall(r"([aeiouAEIOU])|(.)", st)
vs, cs = [c for c,_ in ls if len(c)>0], [v for _,v in ls if len(v)>0]
positions = list(range(len(cs)))
result = ""
for v in vs:
if len(positions)==0:
cs.append(" "+v)
else:
p = random.choice(positions)
positions.remove(p)
cs[p//2] += v
while True:
random.shuffle(cs)
result = "".join(cs)
if not (result.startswith(" ") or result.endswith(" ") or " " in result):
break
return result
print(perm_lets("this is a loop"))
print(perm_lets("teis iou")) # more vowels than consonants
Output
tp so hal osii
si u tei o
Related
I greet you all I need help I have this code here
how can i achieve this if I want letters to be added between the letters
example
input
east
output
aeast
eaast
eaast
easat
easta
aeast
beast
ebast
eabst
easbt
eastb
ect...
leters = 'abcdefghijklmnopqrstuvwxyz'
words = ('east')
for letersinput in leters:
for rang in range(1):
print(letersinput+""+str(words)+"")
I'm looking for the exact opposite of this, how to do it?
def missing_char(word, n):
n = abs(n)
front = word[:n]
back = word[n+1:]
return front + back
Iterate through the words and letters, and for each position, slice the word at the position and insert the letter:
letters = 'abcdefghijklmnopqrstuvwxyz'
words = ['east']
for word in words:
for letter in letters:
for i in range(len(word)+1):
print(word[:i] + letter + word[i:])
print()
Output:
aeast
eaast
eaast
easat
easta
beast
ebast
eabst
easbt
eastb
...
zeast
ezast
eazst
easzt
eastz
Here is what I have so far:
def reversestring(thestring):
words = thestring.split(' ')
rev = ' '.join(reversed(words))
return rev
stringing = input('enter string: ')
print(reversestring(stringing))
I know I'm missing something because I need the punctuation to also follow the logic.
So let's say the user puts in Do or do not, there is no try.. The result should be coming out as .try no is there , not do or Do, but I only get try. no is there not, do or Do. I use a straightforward implementation which reverse all the characters in the string, then do something where it checks all the words and reverses the characters again but only to the ones with ASCII values of letters.
Try this (explanation in comments of code):
s = "Do or do not, there is no try."
o = []
for w in s.split(" "):
puncts = [".", ",", "!"] # change according to needs
for c in puncts:
# if a punctuation mark is in the word, take the punctuation and add it to the rest of the word, in the beginning
if c in w:
w = c + w[:-1] # w[:-1] gets everthing before the last char
o.append(w)
o = reversed(o) # reversing list to reverse sentence
print(" ".join(o)) # printing it as sentence
#output: .try no is there ,not do or Do
Your code does exactly what it should, splitting on space doesn't separator a dot ro comma from a word.
I'd suggest you use re.findall to get all words, and all punctation that interest you
import re
def reversestring(thestring):
words = re.findall(r"\w+|[.,]", thestring)
rev = ' '.join(reversed(words))
return rev
reversestring("Do or do not, there is no try.") # ". try no is there , not do or Do"
You can use regular expressions to parse the sentence into a list of words and a list of separators, then reverse the word list and combine them together to form the desired string. A solution to your problem would look something like this:
import re
def reverse_it(s):
t = "" # result, empty string
words = re.findall(r'(\w+)', s) # just the words
not_s = re.findall(r'(\W+)', s) # everything else
j = len(words)
k = len(not_s)
words.reverse() # reverse the order of word list
if re.match(r'(\w+)', s): # begins with a word
for i in range(k):
t += words[i] + not_s[i]
if j > k: # and ends with a word
t += words[k]
else: # begins with punctuation
for i in range(j):
t += not_s[i] + words[i]
if k > j: # ends with punctuation
t += not_s[j]
return t #result
def check_reverse(p):
q = reverse_it(p)
print("\"%s\", \"%s\"" % (p, q) )
check_reverse('Do or do not, there is no try.')
Output
"Do or do not, there is no try.", "try no is there, not do or Do."
It is not a very elegant solution but sure does work!
This is my homework assignment:
Write function vowelCount() that takes a string as input and counts
and prints the number of occurrences of vowels in the string.
vowelCount ( ’ Le Tour de France ’ ) a, e, i, o, and u appear,
respectively, 1, 3, 0, 1, 1 times.
This is what I've done so far and it's not working! What do I do?
def vowelCount(sentence):
sentence = sentence.lower()
vowels = "aeiou"
count = 0
if vowels in sentence:
count = +1
print("a, e, i, o, u, appear, respectively," count "times.")
I'm so bad with Python that I can never do my homework on my own. I might as well just give up trying to learn.
You are doing wrong initialization.
vowels = "aeiou"
You should declare it as list or dictionary.
Now the problem with your solution is that you are checking if "vowels" which you have initialized as "aeiou" is present in incoming string or not
if vowels in sentence:
So here you are checking that "aeiou", the whole string is present in the incoming sentence or not. You are not checking for individual vowel and individual character.
The solution will we like iterating all over the sentence from 0 to n-1 where n is its length and check each character.
def count(string):
#we use hashmap to make lookup operation cheap
mp = {'a':1,'e':1,'i':1,'o':1,'u':1}
n = len(s)
count = 0
for i in range(n): #iterating for every element in string
if s[i] in mp: #checking if it is vowel or not
count += 1
return count
So, I want to be able to scramble words in a sentence, but:
Word order in the sentence(s) is left the same.
If the word started with a capital letter, the jumbled word must also start with a capital letter
(i.e., the first letter gets capitalised).
Punctuation marks . , ; ! and ? need to be preserved.
For instance, for the sentence "Tom and I watched Star Wars in the cinema, it was
fun!" a jumbled version would be "Mto nad I wachtde Tars Rswa ni het amecin, ti wsa
fnu!".
from random import shuffle
def shuffle_word(word):
word = list(word)
if word.title():
???? #then keep first capital letter in same position in word?
elif char == '!' or '.' or ',' or '?':
???? #then keep their position?
else:
shuffle(word)
return''.join(word)
L = input('try enter a sentence:').split()
print([shuffle_word(word) for word in L])
I am ok for understanding how to jumble each word in the sentence but... struggling with the if statement to apply specifics? please help!
Here is my code. Little different from your logic. Feel free to optimize the code.
import random
def shuffle_word(words):
words_new = words.split(" ")
out=''
for word in words_new:
l = list(word)
if word.istitle():
result = ''.join(random.sample(word, len(word)))
out = out + ' ' + result.title()
elif any(i in word for i in ('!','.',',')):
result = ''.join(random.sample(word[:-1], len(word)-1))
out = out + ' ' + result+word[-1]
else:
result = ''.join(random.sample(word, len(word)))
out = out +' ' + result
return (out[1:])
L = "Tom and I watched Star Wars in the cinema, it was fun!"
print(shuffle_word(L))
Output of above code execution:
Mto nda I whaecdt Atsr Swra in hte ienamc, ti wsa nfu!
Hope it helps. Cheers!
Glad to see you've figured out most of the logic.
To maintain the capitalization of the first letter, you can check it beforehand and capitalize the "new" first letter later.
first_letter_is_cap = word[0].isupper()
shuffle(word)
if first_letter_is_cap:
# Re-capitalize first letter
word[0] = word[0].upper()
To maintain the position of a trailing punctuation, strip it first and add it back afterwards:
last_char = word[-1]
if last_char in ".,;!?":
# Strip the punctuation
word = word[:-1]
shuffle(word)
if last_char in ".,;!?":
# Add it back
word.append(last_char)
Since this is a string processing algorithm I would consider using regular expressions. Regex gives you more flexibility, cleaner code and you can get rid of the conditions for edge cases. For example this code handles apostrophes, numbers, quote marks and special phrases like date and time, without any additional code and you can control these just by changing the pattern of regular expression.
from random import shuffle
import re
# Characters considered part of words
pattern = r"[A-Za-z']+"
# shuffle and lowercase word characters
def shuffle_word(word):
w = list(word)
shuffle(w)
return ''.join(w).lower()
# fucntion to shuffle word used in replace
def replace_func(match):
return shuffle_word(match.group())
def shuffle_str(str):
# replace words with their shuffled version
shuffled_str = re.sub(pattern, replace_func, str)
# find original uppercase letters
uppercase_letters = re.finditer(r"[A-Z]", str)
# make new characters in uppercase positions uppercase
char_list = list(shuffled_str)
for match in uppercase_letters:
uppercase_index = match.start()
char_list[uppercase_index] = char_list[uppercase_index].upper()
return ''.join(char_list)
print(shuffle_str('''Tom and I watched "Star Wars" in the cinema's new 3D theater yesterday at 8:00pm, it was fun!'''))
This works with any sentence, even if was "special" characters in a row, preserving all the punctuaction marks:
from random import sample
def shuffle_word(sentence):
new_sentence=""
word=""
for i,char in enumerate(sentence+' '):
if char.isalpha():
word+=char
else:
if word:
if len(word)==1:
new_sentence+=word
else:
new_word=''.join(sample(word,len(word)))
if word==word.title():
new_sentence+=new_word.title()
else:
new_sentence+=new_word
word=""
new_sentence+=char
return new_sentence
text="Tom and I watched Star Wars in the cinema, it was... fun!"
print(shuffle_word(text))
Output:
Mto nda I hctawed Rast Aswr in the animec, ti asw... fnu!
I have this code that is supposed to print out the least occurring vowel when a word is entered, but it doesn't print out a vowel and the least value. Here is my code:
#Program to count the least occurring vowels
# take input from the user
w = input("Enter a word or sentence: ")
# string of vowels
vowel = 'aeiouAEIOU'
min_vowel = w[0]
min = w.count(w[0])
# make it suitable for caseless comparisions
w = w.casefold()
count = 0
# count the vowels
for char in w:
if vowel in w:
if w.count(vowel) < min:
min_vowel = w[0]
min = w.count(w)
print ("The least occuring vowel is",min_vowel,"with",min,"occurences.")
Please can anyone tell me where am going wrong?
If you want to be able to identify multiple vowels with the least occurences, I suggest using a different approach:
from collections import Counter
w = input("Enter a word or sentence: ")
vowel = "aeiouy"
# Count occurences of all vowels.
w = Counter(c for c in w.lower() if c in vowel)
# Get vowels with lowest occurences.
min_values = {k: w[k] for k in w if w[k] == min(w.values())}
# Print vowels.
print("The least occuring vowel is:")
for m in min_values:
print("{vowel} with {occ} occurences.".format(vowel=m, occ=min_values[m]))
Example:
>>> (...)
>>> Enter a word or sentence: Bananas are YUMMY!
The least occuring vowel is:
e with 1 occurences.
u with 1 occurences.