Reading a random line from a word doc and printing it - python

So I have a small project with python.
A random song name and artist are chosen.
The artist and the first letter of each word in the song title are displayed.
The user has two chances to guess the name of the song.
If the user guesses the answer correctly the first time, they score 3 points. If the user guesses
the answer correctly the second time they score 1 point. The game repeats.
The game ends when a player guesses the song name incorrectly the second time.
So far I've created a text document and put a few lines of song titles.
In my code I have used the following:
random_lines = random.choice(open("songs.txt").readlines())
This randomly picks a line in the code and does nothing with it.
I am asking where I go from here. I need to display the first letters of each word on the line. I then need a counter or some sort to add chances. I also need to write something that will check to see if they have it correct and add to a score counter.

OK, now just continue with your plan, it's good. Now you have to get the first letter from each word in line. You can do that with:
res = []
for i in line.split():
res.append(i[0])
There you are, you have the first letter of every word in the list res. Now you need to check if the user entered the title correctly. Maybe the best idea would be to keep everything lower-cased (in your file and in the user input) for easier checking. Now you just have to transform the user input to lower-case. You can do it with:
user_entry = input('Song title:')
if user_entry.lower() == line.lower():
score += 3
else:
user_entry_2 = input('Song title:')
if user_entry_2.lower() == line.lower():
score += 1
else:
print('Game over.')
sys.exit()
You should make this into a function ad call it in a loop until user misses. The function could return the current score which you could print out (in that case you should remove sys.exit() call)
I hope this is clear enough. If not, write the question in the comments :)

Assuming your random choice string contains the data in the format {songname} - {artist}
Then you first need to get the song name and the artist as a separate strings.
Print the first letters and ask for input.
After which you need to compare the strings and do some logic with the points.
points = 0;
while(1):
random_line = 'Song - artist' #change this with your random string
song, artist = random_line.split('-')
print("{0} - {1}".format(song.strip()[:2], artist.strip()[:2]))
for i in range(0,3):
if (i == 2):
print('You died with {} points'.format(points))
exit(0)
elif(random_line.lower() == input('Gues the song: ').lower()):
points += 2 - i
print('correct guess. points: ' + str(points))
break
else:
print('Try again')

Related

Hey beginner here! Is there a way to search for a specific word in a text file and then print the line after it?

This is my assignment:
You are provided with two text files names.txt and scores.txt. The names.txt contains first names only of
players of a table game. The scores.txt contains players’ names and scores. Players can play game
multiple times. The goal of the project is to write a program that will read a player’s name from
names.txt, search for the player in scores.txt and total the scores for the player and calculate the
average score. Write the player’s name, total and average scores to another file, name the file report.txt
Identify variables that you will need for the program
e.g., stdName and playScore
All your code must be contained in a single function, e.g., studentReports
Open the three files and use loops to read records in names.txt and scores.text. For every record in
names.txt, read each record in scores.txt and using running total to obtain the total scores and number
of plays and calculate the average score
But we've only been taught how to use the basic read and write functions so I am kind of lost.
this is all I have so far but I'm not really sure
num_player = 0
ask = input('Do you want to add a player? (y=yes,n=no)\n')
while ask == 'y' or ask == 'Y' :
name = input('Enter player name: ')
sFile.write(name + '\n')
num_player+=1
ask = input('Do you want to add another player? (y=yes,n=no)\n')
if ask == 'n' or ask == 'N':
break
nFile.close()
nFile = open('names.txt', 'r')
for player_num in range(num_player):
name = nFile.readline()
name = name.strip('\n')
sFile.write(name + 'n')
score = int(input(f'Enter score for {name}: '))
score = score.strip('\n')
sFile.write(score+'\n')

Deciphering script in Python issue

Cheers, I am looking for help with my small Python project. Problem says, that program has to be able to decipher "monoalphabetic substitute cipher", while we have complete database, which words will definetely (at least once) be ciphered.
I have tried to create such a database with words, that are ciphered:
lst_sample = []
n = int(input('Number of words in database: '))
for i in range(n):
x = input()
lst_sample.append(x)
Way, that I am trying to "decipher" is to observe words', let's say structure, where different letter I am assigning numbers based on their presence in word (e.g. feed = 0112, hood = 0112 are the same, because it is combination of three different letters in such a combination). I am using subprogram pattern() for it:
def pattern(word):
nextNum = 0
letternNums = {}
wordPattern = []
for letter in word:
if letter not in letterNums:
letternNums[letter] = str(nextNum)
nextNum += 1
wordPattern.append(letterNums[letter])
return ''.join(wordPattern)
Right after, I have made database of ciphered words:
lst_en = []
q = input('Insert ciphered words: ')
if q == '':
print(lst_en)
else:
lst_en.append(q)
With such a databases I could finally create process to deciphering.
for i in lst_en:
for q in lst_sample:
x = p
word = i
if pattern(x) == pattern(word):
print(x)
print(word)
print()
If words in database lst_sample have different letter length (e.g. food, car, yellow), there is no problem to assign decrypted words, even when they have the same length, I can sort them based on their different structure: (e.g. puff, sort).
The main problem, which I am not able to solve, comes, when word has the same length and structure (e.g. jane, word).
I have no idea how to solve this problem, while keeping such an script architecture as described above. Is there any way, how that could be solved using another if statement or anything similar? Is there any way, how to solve it with infortmation that words in lst_sample will for sure be in ciphered text?
Thanks for all help!

How can I make strings automatically in Python 3.7?

Now, I'm learning Python and I want to make a dictionary, where the user can add words (in first step just the word, later definition).
word = input('Write a word here')
print('You added ' + word)
So, what I would like is the user can add more word, and the program save it to other string.
How can I do this?
Typically, this could be done in a while-loop where the loop-condition variable is updated upon user input:
continue_condition = True
words = []
while continue_condition:
word = input("Write a word here")
words.append(word)
continue_condition = input("Would you like to add another word? Then please type `Y`") == "Y"
If you want to populate a dictionary instead of a list, just adapt this code to your specific needs.
this will help to automate:
dict = {} # variable to store the key and value
def add(): # add function to add more word in our dictionary.
word = input('enter the word: ') # take the user input
dict[word] = word; # this will add the word to our dict for simplicity this is sample so we are using the same key and value.
if('y' == input('do you want to add more word (y/n): ')): # check if user want to add more word to dictionary.
add() # if yes the call function again ---recursion.
add() # call function for add word for first time.
print(dict) # print all the words in our dict.

TKinter and JSON

I'm looking for a resource to learning me how to connect TKinter and JSON
Like take an input value (word) and search for that word in JSON then print out the result of the search
by way, I have already the python application working through terminal but I want to go further step and build a GUI
Thank you,
import json #import the JSON module
from difflib import get_close_matches #difflib module provides classes and functions
#for comparing sequences
#get_close_matches Return a list of
#the best “good enough” matches
data = json.load(open("data.json")) #load JSON to python dictionary
def translate(w):
w = w.lower() #change the input to lower case
if w in data: #first scenario check if the word exist in the dictionary, if exist load the data
return data[w]
elif w.title() in data: #When the user inputs a proper noun
return data[w.title()] #returns the definition of names that start with a capital letter
elif w.upper() in data: #definition of acronyms
return data[w.upper()]
elif len(get_close_matches(w, data.keys())) > 0: #second scenario compare the word and get the best match
#ask the user if the result of matching what is looking for
YN = input("Did you mean %s instead? Enter y if yes or n if no:" % get_close_matches(w, data.keys())[0])
if YN == "y":
return data[get_close_matches(w, data.keys())[0]]
elif YN == "n":
return "The word doesn't exist. Please double check it."
else:
return "We didn't understand your entry."
#third scenario the word not match or can't found
else:
return "The word doesn't exsit. Please double check it."
word = input("Enter word: ")
#in some cases the word have more than one definition so we need to make the output more readable
output = translate(word)
if type(output) == list:
for item in output:
print(item)
else:
print(output)
Here's how to do it!
Sketch some pictures of what your current program would look like if it had a GUI.
Would "Did you mean %s instead?" be a popup box?
Would you have a list of all the known words?
Build the UI using tkinter.
Connect the UI up to the functions in your program. (You do have those, don't you?)
Your program isn't quite ready yet, since you are doing stuff like using input inside your functions. Rework it so that it makes sense to have these outside your functions, then it'll probably be ready.

How to find keywords in a file using module re

I am looking to make a program that can pick out car information from a file using module re. The user is asked questions about the car that he wants to view and if the input is not in the file I should display an error message and loop the code again if the user wants to. I am having difficulty trying to find the inputs in the file: this is the code so far:
import re
import random
myList = ([])
car = input("What car do you want to view?");
myList.insert(1, car)
model = input("What car model is it of");
myList.insert(2, model)
fuelTy = input("What fuel type is it: diseal or petrol");
myList.insert(3, fuelTy)
engSize = input("What engine size is it : eg 2l");
myList.insert(4, engSize)
rnd = (int(random.randrange(50000000)) + 1)
with open("car.txt", "r") as carfile:
for line in carfile:
if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
splitted_line = line.split(':')
print(splitted_line)
if not myList not in carfile:
print("We don't have the car available currently. Please contact the head office with the case number " + str(rnd))
Cho2 = input("Would you like to see anything yes or no").lower
if Cho2 == "yes":
print("OK")
elif Cho2 == "no":
print("End of program")
Text file is:
bmw : X6 : 3.4l : Engine size 4395cc: petrol: 0-62mph in 4.8s: gear type automatic : 5 doors : economy 29mpg : top speed 155 mph
audi : Q7 : 3.0l : Engine size 2967cc: disel: 0-62mph in 6.5s: gear type automatic : 5 doors : economy: 48mpg : top speed 145 mph
honda : CRV : 2.0l: Engine size 1997cc: petrol : 0-62mph in 10.0s: gear type manual : 5 doors : economy 30mpg : top speed 18 mph
if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
In this line, you are re-defining myList to be a line in the file. But you have an outer loop (for line in carfile) that does the same thing.
Change this to eliminate the for expression, and you'll be on the right track:
if all(myList.lower() in re.findall('\w+', line.lower())):
FWIW, this is going to be very hit-or-miss, because you have things like engine size that use different measures (cc vs. l) in the file.
Next, please be aware that you can (and probably should, as a matter of avoiding errors) use .append() in order to grow a list, instead of .insert(). The difference is that append does not require you to keep track of an index, which in cases like this is not benefiting you (you don't make use of the position information at any time) and is a source of error if you copy/paste a block of code to add a new field.
myList.append(engSize) # was myList.insert(4, engSize)
Also, you should probably give users the option of not entering a field, and skip searching if they don't enter it. (Just don't append the field if it's empty, perhaps?)
engSize = input("What engine size is it : eg 2l")
if engSize: myList.append(engSize)
EDIT
Okay, just got done for the day, back to this program. :-)
There are some more problems, but let's take care of the "all requires an iterableissue first. If you look at the docs for [all`](https://docs.python.org/3/library/functions.html#all), it says
all(iterable)
So we need to restructure the test to give all an iterable (a list, tuple, view, or other expression that can be iterated), or we need to stop using all.
Well, we are trying to iterate over myList, so it should be possible to come up with an iterable. Let's start with that in mind:
if all(s for s in myList):
In fact, we can put the .lower() back in - that made sense. So:
if all(s.lower() for s in myList):
Now, let's treat s.lower() as a word (which it is) and search for it in the input line. What we are doing is converting our previous string expression, s.lower(), into a boolean expression: word in list, within the context of the iteration we already have. This will be a different flavor of the in keyword:
if all( (EXPR) for s in myList):
if all((s.lower() in re.findall('\w+', line.lower())) for s in myList):
When I make this change, I can match the make of the car.
There are some problems with the logic, as well. You want to match the user query to a car type. If you can't match that, then you want to print a message about "We don't have the car ..." But you can't get that test (not matching) in one line. If you could get that test into one line, you could probably get the searching part into one line as well. (Not always, but it's worth looking!)
Instead, just keep track of whether or not you found the car:
found_car = False
for line in carfile:
if ...
found_car = True
break
if not found_car:
print("We don't have the car ...")
Next, let's make the program run longer (for testing if nothing else). You are doing for loops, so I assume you can do a while loop. Let's add a loop around the whole thing to keep going until the user types quit:
while True:
make = input("What make of car do you want (or type 'quit')? ")
if make == 'quit':
break
if make:
myList.append(make)
Finally, let's take a look at your regular expression. You are using \w+, which will match "word characters" (whatever those are) one or more times.
That's a good start for things like "audi" and "honda", but word characters don't include the period ('.') or the hyphen ('-'), both of which appear in your data.
Instead, try changing your regex to match either a word character or a dot, one or more times:
re.findall('[\w.]+', ...)
Good luck!
You have bugs!
First, you are initializing myList = ([]) as a tuple containing a single empty list, so append() or insert() aren't going to work. Try myList = [].
Second, you're getting the indexes wrong in your myList.insert(...) statements. Just use myList.append(...) instead, no need to worry about indexes that way.
Then, try replacing (not tested...):
if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
... with:
if all (item.lower() in re.findall('\w+', line.lower()) for item in myList):
A simple optimization which also makes the code more readable:
line_words = set(re.findall('\w+', line.lower()))
if all(item.lower() in line_words for item in myList):

Categories