Acronym input text and reverse it - python

My task is to turn the input text to acronym and reverse it. The word should be more than 3 characters long and do not contain symbols such as ,!'?. For example if I have this sentence "That was quite easy?" the function should return EQT
I have done so far:
def acr(message):
words = message.split()
if check_length(words) is False:
return "the input long!"
else:
first_letters = []
for word in words:
first_letters.append(word[0])
result = "".join(first_letters)
return reverse(result.upper())
def check(word):
if len(word) > 3:
return False
def check_length(words):
if len(words) > 50:
return False
def rev(message):
reversed_message = message[::-1]
return reversed_message
I have problems with check function. How to correctly control the length of words and symbols?

A bit hacky in the sense that a comma is technically a special character (but you want the 'e' from easy), but this works perfectly for your example. Set up the "if" statement in the "for word in words" section.
def acronymize(message):
"""Turn the input text into the acronym and reverse it, if the text is not too long."""
words = message.split()
if check_message_length(words) is False:
return "Sorry, the input's just too long!"
else:
first_letters = []
for word in words:
if len(word) > 3 and word.isalnum()== True or (len(word) > 4 and ',' in word): #satisfies all conditions. Allows commas, but no other special characters.
first_letters.append(word[0])
result = "".join(first_letters)
return reverse(result.upper())
Basically the 'if' condition became if you have word of length > 3 characters AND the word is alphanumeric (then that satisfies all conditions) OTHERWISE (OR) if there is a comma next to the word (there will be len(word)+1 characters) and it will have a comma (,), that still satisfies the previous conditions, then populate the first_letters list.
Otherwise, ignore the word.
This way you don't even have to set up a check_word function.
This spits out the answer
'EQT'
A couple more examples from my code:
Input: Holy cow, does this really work??
Output: 'RTDH'
** Note that it did NOT include the word 'cow' because it did not have more than 3 letters.
Input: Holy cows, this DOES work!!
Output: 'DTCH'
** Note, now the term 'cows' gets counted because it has more than 3 letters.
You can similarly add any exceptions that you want (!, ? and .) using the 'or' format:
Ex: or (len(word) > 4 and '!' in word) or (len(word) > 4 and '?' in word)
The only assumption made for this is that the sentence is grammatically correct (as in, it won't have exclamation marks followed by commas).
It can be further cleaned up by making a list of the special characters that you would allow and passing that list into the or clause.
Hope that helps!

re.findall(r'(\w)\w{3,}', sentence) finds first letter of every at least four letter word
''.join(reversed(re.findall(r'(\w)\w{3,}', sentence))).upper()
re docs
If you want to ignore words preceding non-word characters, use (\w)\w{3,},?(?:$|\s) – this also allows a comma explicitly.
''.join(reversed(re.findall(r'(\w)\w{3,},?(?:$|\s)', sentence))).upper()

Related

How to get the position of a character in Python and store it in a variable?

I am looking for a way to store the position integer of a character into a variable, but now I'm using a way I used in Delphi 2010, which is not right, according to Jupyter Notebook
This is my code I have this far:
def animal_crackers(text):
for index in text:
if index==' ':
if text[0] == text[pos(index)+1]:
return True
else:
return False
else:
pass
The aim, is to get two words (word + space + word) and if the beginning letters, of both words, match, then it has to show True, otherwise it shows False
For getting the index of a letter in a string (as the title asks), just use str.index(), or str.find() if you don't want an error to be raised if the letter/substring could not be found:
>>> text = 'seal sheep'
>>> text.index(' ')
4
However for your program, you do not need to use str.index if you want to identify the first and second word. Instead, use str.split() to break up a given text into a list of substrings:
>>> words = text.split() # With no arguments, splits words by whitespace
>>> words
['seal', 'sheep']
Then, you can take the letter of the first word and check if the second word begins with the same letter:
# For readability, you can assign the two words into their own variables
>>> first_word, second_word = words[0], words[1]
>>> first_word[0] == second_word[0]
True
Combined into a function, it may look like this:
def animal_crackers(text):
words = text.split()
first_word, second_word = words[0], words[1]
return first_word[0] == second_word[0]
Assuming that text is a single line containing two words:
def animal_crackers(text):
words = text.split()
if len(words)== 1:
break # we only have one word!
# here, the .lower() is only necessary is the program is NOT case-sensitive
# if you do care about the case of the letter, remove them
if word[0].lower() == words[1][0].lower():
return True
else:
return false

Append last letter in a string to another string

I am constructing a chatbot that rhymes in Python. Is it possible to identify the last vowel (and all the letters after that vowel) in a random word and then append those letters to another string without having to go through all the possible letters one by one (like in the following example)
lastLetters = '' # String we want to append the letters to
if user_answer.endswith("a")
lastLetters.append("a")
else if user_answer.endswith("b")
lastLetters.append("b")
Like if the word was right we’d want to get ”ight”
You need to find the last index of a vowel, for that you could do something like this (a bit fancy):
s = input("Enter the word: ") # You can do this to get user input
last_index = len(s) - next((i for i, e in enumerate(reversed(s), 1) if e in "aeiou"), -1)
result = s[last_index:]
print(result)
Output
ight
An alternative using regex:
import re
s = "right"
last_index = -1
match = re.search("[aeiou][^aeiou]*$", s)
if match:
last_index = match.start()
result = s[last_index:]
print(result)
The pattern [aeiou][^aeiou]*$ means match a vowel followed by possibly several characters that are not a vowel ([^aeiou] means not a vowel, the sign ^ inside brackets means negation in regex) until the end of the string. So basically match the last vowel. Notice this assumes a string compose only of consonants and vowels.

How can I get the index of a recurring character from a string?

I'm working with a hangman like project whereas if the user inputs a letter and matches with the solution, it replaces a specific asterisk that corresponds to the position of the letter in the solution. I'm trying to do this by getting the index of the instance of that letter in the solution then replacing the the matching index in the asterisk.
The thing here is that I only get the first instance of a recurring character when I used var.index(character) whereas I also have to replace the other instance of that letter. Here's the code:
word = 'turtlet'
astk = '******'
for i in word:
if i == t:
astk[word.index('i')] = i
Here it just replaces the first instance of 't' every time. How can I possibly solve this?
index() gives you only the index of the first occurrence of the character (technically, substring) in a string. You should take advantage of using enumerate(). Also, instead of a string, your guess (hidden word) should be a list, since strings are immutable and do not support item assignment, which means you cannot reveal the character if the user's guess was correct. You can then join() it when you want to display it. Here is a very simplified version of the game so you can see it in action:
word = 'turtlet'
guess = ['*'] * len(word)
while '*' in guess:
print(''.join(guess))
char = input('Enter char: ')
for i, x in enumerate(word):
if x == char:
guess[i] = char
print(''.join(guess))
print('Finished!')
Note the the find method of the string type has an optional parameter that tells where to start the search. So if you are sure that the string word has at least two ts, you can use
firstindex = word.find('t')
secondindex = word.find('t', firstindex + 1)
I'm sure you can see how to adapt that to other uses.
I believe there's a better way to do your specific task.
Simply keep the word (or phrase) itself and, when you need to display the masked phrase, calculate it at that point. The following snippet shows how you can do this:
>>> import re
>>> phrase = 'My hovercraft is full of eels'
>>> letters = ' mefl'
>>> display = re.sub("[^"+letters+"]", '*', phrase, flags=re.IGNORECASE)
>>> display
'M* ***e****f* ** f*ll *f eel*'
Note that letters should start with the characters you want displayed regardless (space in my case but may include punctuation as well). As each letter is guessed, add it to letters and recalculate/redisplay the masked phrase.
The regular expression substitution replaces all characters that are not in letters, with an asterisk.
for i in range(len(word)):
if word[i] == "t":
astk = astk[:i] + word[i] + astk[i + 1:]

Pig Latin Function Sentence

THe rules for the pig latin sentences are:
1.for words beginning with consonants, all letters before the first vowel are moved to the end of the word, and is further appended by 'ay'
2.for words that begin with vowels, the word is appended by 'hay'
3.for words that do not contain a vowel, the first letter is moved to the end of the word and is appended with 'way'
4. all non characters (i.e., numbers, symbols) are ignored
The main part of the code executes an infinite loop that takes a string input from the user, invokes the pigLatin function and prints the result returned. The pigLatin function receives a list of words as its input and converts them to pig latin using the rules above. The main part exits when the user input "Quit this program" as the input sentence for conversion. Verify your program for all cases (including invalid inputs) and save your program.
I find it very difficult to solve rule 3. As I test the code, the out put isn't correct...
I struggle it for the whole night and couldn't sleep....Please help
Here is my code:
enter code here
sentence=input('input:')
VOWELS=['a','e','i','o','u']
CONSONANTS=['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z']
def pigLatin():
t=-1
for word in newsentence:
if word[0] in CONSONANTS:
if 'a'and'e'and'i'and'o'and'u' not in word[1:]:
print(word[1:]+word[0]+'way',end=' ')
for u in word:
t +=1
if u in VOWELS:
print (word[t:]+word[0:t]+'ay',end=' ')
break
elif word[0] in VOWELS:
print (word[0:]+'hay',end=' ')
else:
print (word[0:])
while sentence!=('Quit the program'):
newsentence=sentence.split()
pigLatin()
sentence=input('input:')
As Willem Van Onsem said, this line doesn't do what you think:
if 'a'and'e'and'i'and'o'and'u' not in word[1:]:
You should try experimenting with the interpreter.
'a' and 'e' not in "bar"
# returns True
This is happening because and is a logical operator which looks at what comes before and after it. It is doing this:
'a' and ('e' not in "bar")
which evaluates to
'a' and True
which evaluates to True, because non-empty strings get assigned the boolean True.
Here is something that will work. It uses the all function, which only returns True if all of its elements are true, and a feature of Python called comprehension which allows you to do tidy loops:
vowels = "aeiou"
all(char not in vowels for char in word)

Ignore punctuation and case when comparing two strings in Python

I have a two dimensional array called "beats" with a bunch of data. In the second column of the array, there is a list of words in alphabetical order.
I also have a sentence called "words" which was originally a string, which I've turned into an array.
I need to check if one of the words in "words" matches any of the words in the second column of the array "beats". If a match has been found, the program changes the matched word in the sentence "words" to "match" and then return the words in a string. This is the code I'm using:
i = 0
while i < len(words):
n = 0
while n < len(beats):
if words[i] == beats[n][1]:
words[i] = "match"
n = n + 1
i = i + 1
mystring = ' '.join(words)
return mystring
So if I have the sentence:
"Money is the last money."
And "money" is in the second column of the array "beats", the result would be:
"match is the last match."
But since there's a period behind "match", it doesn't consider it a match.
Is there a way to ignore punctuation when comparing the two strings? I don't want to strip the sentence of punctuation because I want the punctuation to be in tact when I return the string once my program's done replacing the matches.
You can create a new string that has the properties you want, and then compare with the new string(s). This will strip everything but numbers, letters, and spaces while making all letters lowercase.
''.join([letter.lower() for letter in ' '.join(words) if letter.isalnum() or letter == ' '])
To strip everything but letters from a string you can do something like:
from string import ascii_letters
''.join([letter for letter in word if letter in ascii_letters])
You could use a regex:
import re
st="Money is the last money."
words=st.split()
beats=['money','nonsense']
for i,word in enumerate(words):
if word=='match': continue
for tgt in beats:
word=re.sub(r'\b{}\b'.format(tgt),'match',word,flags=re.I)
words[i]=word
print print ' '.join(words)
prints
match is the last match.
If it is only the fullstop that you are worried about, then you can add another if case to match that too. Or similar you can add custom handling if your cases are limited. or otherwise regex is the way to go.
words="Money is the last money. This money is another money."
words = words.split()
i = 0
while i < len(words):
if (words[i].lower() == "money".lower()):
words[i] = "match"
if (words[i].lower() == "money".lower() + '.'):
words[i] = "match."
i = i + 1
mystring = ' '.join(words)
print mystring
Output:
match is the last match. This match is another match.

Categories

Resources