I have been studying Python for a couple of weeks now, and just after easter, will be having a controlled assesment that will count towards my GCSE grade, for which I will be also marked for the criteria of something like the lentgh of my code.
The question was: Write a Python program that asks the user for a word, then calculates the prints the vowel value of the word entered.
What I want to know:
Is there anyway of shortening down this code?
And also:
How can the program be executed without printing out the "word" variable?
Above I have been given a rubric that I used in the code (in the control flow part).
score = 0
word = str(input("Input a word: "))
c = 0
for letter in word:
print(word[c])
c = c + 1
if letter == "a":
score = score + 5
if letter == "e":
score = score + 4
if letter == "i":
score = score + 3
if letter == "o":
score = score + 2
if letter == "u":
score = score + 1
print("\nThe score for your word is: " + score)
You can use sum and a dict, storing vowels as keys and the associated value as the values:
word = input("Input a word: ")
values = {"a":5,"e":4,"i":3,"o":2,"u":1}
print(sum(values.get(ch,0) for ch in word))
values.get(ch,0) will return 0 as a default value if the ch which is each char in the word is not a vowel therefore not in our dict.
sum(values.get(ch,0) for ch in word) is a generator expression where the variables are evaluated lazily when the next() method is called for generator object
In relation to your own code you should use if/elif's. A character can only have one value, if's are always evaluated but elif's are only evaluated if the previous statement evaluates to False:
score = 0
# already a str in python3 use raw_input in python2
word = input("Input a word: ")
for letter in word:
if letter == "a":
score += 5 # augmented assignment same as score = score + 5
elif letter == "e":
score += 4
elif letter == "i":
score += 3
elif letter == "o":
score += 2
elif letter == "u":
score += 1
Here's the working code:
word = input("Input a word: ")
values = {"a":5,"e":4,"i":3,"o":2,"u":1}
score = sum(values[let] for let in word if let in values)
print("\nThe score for your word is: " + score)
Related
So I'm making a hanging man game and I have run into a problem regarding indexes. Basically, I want to find the index of a letter inside a secret word, the problem is that if the secret word includes two letters that are the same, for instance, "guacamole", where the letter a has the index of 2 and 4 but when I want to find the index of a, it only prints "2" and not "4". Is there a way around this? Thanks in advance!
Part of code where problem occurs:
for letter in secret_word:
if user_guess == letter:
current_word_index = secret_word.find(letter)
print(current_word_index) #Not in full program, only to test errors.
Full code:
#Hanging man
import string
space = "\v"
dbl_space = "\n"
secret_word = str(input("Enter a secret word: "))
guess_low = list(string.ascii_lowercase)
used_letters = []
user_errors = 0
user_errors_max = 1
secret_word_index = int(len(secret_word))
secret_word_placeholder = list(range(secret_word_index))
while user_errors != user_errors_max:
user_guess = str(input("Enter a letter: "))
if len(user_guess) != 1:
print("You have to pick one letter")
if user_guess in guess_low:
guess_low.remove(user_guess)
used_letters.extend(user_guess)
print(used_letters)
for letter in secret_word:
if user_guess == letter:
current_word_index = secret_word.find(letter)
if user_errors == user_errors_max:
print("You lost the game, the secret word was: " + secret_word)
This is an example of what you are trying to achieve. use list comprehension.
string='hello'
letter='l'
[idx for idx,ch in enumerate(string) if ch==letter]
Python's string find accepts a start parameter that tells it where to start searching:
>>> "guacamole".find('a')
2
>>> "guacamole".find('a', 3)
4
Use a loop, and use the index of the last hit you found + 1 as the start parameter for the next call.
Another more verbose solution might be:
str1 = "ooottat"
def find_all_indices(text, letter):
indices_of_letter = []
for i, ch in enumerate(text):
if ch == letter:
indices_of_letter.append(i)
return indices_of_letter
print(find_all_indices(str1, 'o'))
Side note:
Indexes is the nontechnical plural of index. the right technical plural for index is indices
Yes, if you instantiate a new_variable to be the secret_word variable before the for loop, the in the line current_word_index = secret_word.find(letter) change secret_word.find(letter) to new_variable .find(letter) then below the if statement write new_variable = new_variable [1:] which will remove the letter just found.
so your code would look something like:
new_variable = secret_word
for i in secret_word
if user_guess == letter:
current_word_index = new_variable.find(letter)
#I would do print(current_word_index) this will show the index
#Or current_word_index = current_word_index + ',' + new_variable.find(letter)
new_variable= new_variable[1:] #this will take away your letter.
Basically my plan was to return text with random-sized letters in words i.e. "upper" or "lower". The script is working, though it seems raw (I am a Beginner and I'd appreciate some corrections from You).
The problem is:
It is not consistent. With that said, it can print word 'about' even if it should be 'About' or something similar.
I want to be sure that the maximum of UPPER or lower letters in a row do not exceed 3 letters. and I don't know how to do it.
Thank you in advance.
#!/usr/bin/env python3
import random
message = input()
stop = ''
def mocking(message):
result = ''
for word in message:
for letter in word:
word = random.choice(random.choice(letter.upper()) + random.choice(letter.lower()))
result += word
return result
while stop != 'n':
print(mocking(message))
stop = input("Wanna more? y/n ").lower()
if stop == 'n':
break
else:
message = input()
You need to split the input into words, decide how many positions inside the word you want to change (minimum 3 or less if the word is shorter).
Then generate 3 unique positions inside the word (via random.sample) to change, check if upper then make lower else make upper. Add to resultlist and join words back together.
import random
message = "Some text to randomize"
def mocking(message):
result = []
for word in message.split():
len_word = len(word)
# get max 3 random positions
p = random.sample(range(len_word),k = min(len_word,3))
for position in p:
l = word[position]
if l.isupper():
word = word[:position] + l.lower() + word[position+1:]
else:
word = word[:position] + l.upper() + word[position+1:]
result.append(word)
return ' '.join(result)
while True:
print(mocking(message))
stop = input("Wanna more? y/n ").lower()
if stop == 'n':
break
else:
message = input()
See Understanding slice notation for slicing
At most 3 modifications? I would go with something like this.
def mocking(message):
result = ''
randomCount = 0
for word in message:
for letter in word:
newLetter = random.choice( letter.upper() + letter.lower() )
if randomCount < 3 and newLetter != letter:
randomCount += 1
result += newLetter
else:
result += letter
randomCount = 0
return result
If the random choice has modified the letter then count it.
The main confusion I am having with my code is that I am aiming to find all the words in the dictionary.txt of a particular length containing just a single vowel (defined as a, e, i, o and u) that does not have a particular letter in it. However, it does not work correctly. For example, if I am looking for all the words of length 9 containing just a single vowel that does not have letter ‘t’ in it, the
program below tells me “There are no words that fit this criteria”. But there should be two
words in the file satisfying the above criteria: “lynchings”, and “lynchpins”.
My dictionary is located at https://filebin.net/96k7kso4i6nxcd2n/dictionary.txt?t=x9ujn62v
def onevowel(file):
length = int(input("Please enter the word length you are looking for: "))
letter = input("Please enter the letter you'd like to exclude: ")
wordnum = 0
for word in file:
word = word.strip()
if len(word) == length:
count = 0
for char in word:
if (char=='a' and char=='e' and char=='i' and char=='o' and char=='u'):
count += 1
if count == 1:
flag = 1
word_str = ""
for char in word:
if char == letter:
flag = 0
else:
word_str += char
if flag == 1:
print (word_str)
wordnum += 1
if wordnum == 0:
print ("There are no words that fit this criteria.")
if __name__ == "__main__":
my_file = open("dictionary.txt","r")
onevowel(my_file)
my_file.close()
Replace char=='a' and char=='e' and char=='i' and char=='o' and char=='u' (which is never true) with char in "aeoui".
Because you want only a single vowel, use the or condition rather than and in this line:
if (char=='a' and char=='e' and char=='i' and char=='o' and char=='u'):
Just starting python and finally got to -while- loops
*went to if-else's, functions, and for/while loops only
How do you get this to print only itself?
def hangman(secret):
tries = 5
word = ''
while tries > 0:
guess = raw_input("Guess a letter: ")
for index in secret:
common = 0
for char in guess:
if char in index:
common = 1 """checks whether they have something in
commmon"""
if common == 1 or index in " .?!": """checks if the secret_word
has the 4 characters"""
word = word + index """word is now the common letters"""
else:
word = word + '-' """letters not in common are a dash"""
tries -= 1
print 'You have', tries, 'tries left.'
print word
>>> hangman('hello')
Guess a letter: h
You have 4 tries left.
h----
Guess a letter: e
You have 3 tries left.
h-----e---
Guess a letter: l
You have 2 tries left.
h-----e-----ll-
Guess a letter: o
You have 1 tries left.
h-----e-----ll-----o
Guess a letter: a
You have 0 tries left.
h-----e-----ll-----o-----
p.s I'm not sure if I even did the code correctly all I know is that it runs.
return ends the loop
Remove the else condition which includes the'-'
I have been trying to find a single word in a sentence and show its position. with the following:
sentence= input("Write a sentence with two words the same: ")
findme = input("Type a word that appears twice: ")
words = sentence.split()
print (list(enumerate(words)))
print ("The length of sentnce in chracters is",len(sentence))
t = words
print("third word in sentence is:", t[2])
if sentence.find(findme)!=-1:
print("found word")
else:
print("word not found")
print (sentence.find(findme))
numberofwords = len(t)
print("The amount of words in the sentence is:",numberofwords,"words.")
print("This is the last time",findme,"is found in the sentence, its at",sentence.rfind(findme))
print (sentence.index(findme))
test_words = sentence.split()
position = test_words.index(findme)
position = position +1
if position == 1:
addtoword = "st"
elif position == 2:
addtoword = "nd"
elif position == 3:
addtoword = "rd"
elif position >=4:
addtoword = "th"
print ("The word",findme,"is the",position,addtoword,"and position",position,"word in the sentence.")
print ("The word",findme,"appears",sentence.count(findme),"times in the sentence provided.")
But I want to simplify and display the location of the repeated word for example
in " The cat sat on the mat with another cat." would return " The word Cat occurs 2 times, once at 2nd position then at 9th position.
Using collection's Counter
from collections import Counter
sent = "The cat sat on the mat with another cat."
# lower the sentence, strip it from punctuation and split
l = sent.lower().strip('?!.,').split()
# create Counter and find most common word
word = Counter(l).most_common(1)[0][0] # 'the'
# find positions with the word
indices = [i for i, x in enumerate(l) if x == word] # [0, 4]
As #jonrsharpe suggested, you can store all of the locations in a list and then get the first two elements.
Here is your code again, with the parts I've added commented to explain what they do:
sentence= input("Write a sentence with two words the same: ")
findme = input("Type a word that appears twice: ")
words = sentence.split()
print (list(enumerate(words)))
print ("The length of the sentence in chracters is",len(sentence))
t = words
print("third word in sentence is:", t[2])
if sentence.find(findme)!=-1:
print("found word")
else:
print("word not found")
print (sentence.find(findme))
numberofwords = len(t)
print("The amount of words in the sentence is:",numberofwords,"words.")
print("This is the last time",findme,"is found in the sentence, its at",sentence.rfind(findme))
print (sentence.index(findme))
# Set up the variables we will need
lastFoundIndex = 0 # last position we found the word at
test_words = sentence.split() # List of words
positions = list() # list of positions
while lastFoundIndex < len(test_words):
try: # try will try the code found in the block.
foundPosition = test_words.index(findme, lastFoundIndex)
except ValueError: # except catches errors from try, and then runs the code in it's block.
# In this case, if a ValueError is returned when we run the code in the try block,
# we break out of the loop.
break;
finally: # finally is executed after try and any corresponding excepts.
positions.append(foundPosition) # It adds the found position to the list of positions...
lastFoundIndex = foundPosition + 1 # and increases the lastFoundIndex.
# The +1 is needed so it doesn't constantly find the word we just found.
# Replace everything after this point if you want all the positions
position1 = positions[0] + 1 # Get the positions of the first two occurrences...
position2 = positions[1] + 1 # ...and add 1 to them so they work with the code.
if position1 == 1:
addtoword1 = "st"
elif position1 == 2:
addtoword1 = "nd"
elif position1 == 3:
addtoword1 = "rd"
elif position1 >=4:
addtoword1 = "th"
if position2 == 1:
addtoword2 = "st"
elif position2 == 2:
addtoword2 = "nd"
elif position2 == 3:
addtoword2 = "rd"
elif position2 >=4:
addtoword2 = "th"
print ("The word",findme,"is the",position1,addtoword1,"and",position2,addtoword2,"position word in the sentence.")
print ("The word",findme,"appears",len(positions),"times in the sentence provided.")
Keep in mind that it only shows the positions for the first and second occurences of the word. If you want all of them, replace the code after the commented point that says Replace everything after this point if you want all the positions with this:
print("The word",findme,"is the ", end='') # end='' means that it doesn't end with a newline
wordingIndex = 1 # What item of the list we are on. Used for wording purposes
for position in positions: # Loop through all the elements
position = position + 1
if position == 1:
addtoword = "st"
elif position == 2:
addtoword = "nd"
elif position == 3:
addtoword = "rd"
else:
addtoword = "th"
# Now we word the sentence properly.
if wordingIndex == len(positions): # If we're at the final position, don't add a comma
print(position, addtoword, end='', sep='') # sep is the separator between words. It defaults to a space (' '), but
# setting it to '' will make the text appear as "1st" rather than "1 st".
elif wordingIndex == len(positions) - 1: # If we're at the second-to-last position, add an and
print(position, addtoword, ' and ', end='', sep='') # Keep in mind when using sep='', you have to add spaces between words and variables,
# or you'd get "1stand".
else: # If we're anywhere else, just add a comma
print(position, addtoword, ', ', end='', sep='')
wordingIndex = wordingIndex + 1 # Increment the wording counter
print(" word(s) in the sentence provided.")
print ("The word",findme,"appears",len(positions),"times in the sentence provided.")
Also keep in mind Python requires proper indentation. So this is valid code:
if (someVariable == 1):
print("That variable equals one!")
but this isn't:
if (someVariable == 1):
print("That variable equals one!") # Will not run due to indentation errors
Note that the first example will not work if there are less than two instances of the word.