Formatting data in a text file using Python - python

I am fairly new to python and I am creating a program to try and take data from a text file, The quiz has 10 questions, and the name and scores of the users are saved in a text file. This is what the text file looks like:
Bob - 7
Steve - 4
Jake - 10
The idea is if the person tries again and gets another score, the program will realise the user already has data in the file, and it will be appended as such:
Bob - 7, 8, 3
The user can only save a maximum of 3 scores, e.g. If Bob tries again and gets a 10, the 7 will be removed and the 8 and 3 move one place forward like this:
Bob - 8, 3, 10
Then as an option, all the names and scores need to be read back in and placed in order of score with their names attached, If anyone could help that would be greatly appreciated.
Here is the code:
import random, time, re
name = input("Welcome, please type your name to continue: ")
class_number = input("What class are you in? (1, 2 or 3)")
class_number = ("H:\A453\\Class_"+class_number+".txt")
print("\nThank you", name, "you will now answer a short series of questions..\n")
score_counter = 0
x = 1
The Questions come here.... score_counter + 1 if correct etc..
f = open(class_number,"r")
contents = f.read()
items = re.findall(str(name+".*$"),contents,re.MULTILINE)
for y in items:
username, score = y.split(' - ')
print(username, score)
The part that adds the score to the database is here, but I have omitted it as I have yet to complete the bit above ^
f = open(class_number,"r")
f.write(str(name)+" - "+str(score_counter))
f.close()
Any help would be greatly appreciated, also I am not sure how to fix the problem of if for instance the user's name is Bob, and in the text file there is:
Bobby - 9
It will pull up Bobby's score instead, a fix for this would also be great.
Jake

Related

How do I overwrite part of a text file in Python?

I have a text file that contains users username, password and highest score, however I want to overwrite their high score when the achieve a high score. However I only want to overwrite that specific value and no others.
This is my text file (called 'users.txt') :
david 1234abc 34 hannah 5678defg 12 conor 4d3c2b1a 21
For example, if 'hannah' gets a new score of 15, I want to change 12 to 15
Here is what I've tried:
# splitting the file
file = open("users.txt","r")
read = file.read()
users = read.split()
file.close()
# finding indexs for username, password and score
usernamePosition1 = users.index(user)
passwordPosition1 = usernamePosition1 + 1
scorePosition1 = passwordPosition1 + 1
file = open("users.txt","a")
# setting previous high score to an integer
player1OldScore = int(users[scorePosition1])
if player1Score > player1OldScore:
# setting in back to a str for text file
player1ScoreStr = str(player1Score)
# from here on i dont really know what i was doing
users.insert([scorePosition1],player1ScoreStr)
file.write(users)
print(player2 + "\n \nAchieved a new high score")
else:
print("\n \n" + player1 + " , you didn't achieve a new high score")
Your text file format is rather brittle. If David uses "hannah" as a password, then when Hannah tries to update her score, instead of locating her score (the sixth field), it will find her name as the second field and try using the fourth field (her name) as her score! Anyone using a space in their password would also cause problems, although a sneaky person could use “abcd 1000000” as their initial password and seed their initial score as one million.
These problems can be fixed by:
Using 1 line per user, or
Searching for user names only in the first of every 3 fields
And
disallowing spaces in passwords, or
coding/encrypting the passwords
In any case, you must read in and store the existing data, and then write out the entire dataset to the file. The reason is the data is not stored in fixed-width fields. A score changing from 99 to 100 will require moving all subsequent characters of the file one character forward, which is not a modification you can make to the file without actually reading and rewriting it in it’s entirety.
You are going to need to find and replace the strings. This means you will need to format the users.txt file in a way that you are able to simply replace the user data. If you have each user and their data on a seperate line this should be fairly easy:
import string
s = open("users.txt","r+")
for line in s.readlines():
print line
string.replace(line, 'hannah 5678defg 12','hannah gfed8765 21')
print line
s.close()
You have the right idea (note that I your code will only work for 1 user, but I'll let you figure out how to extend it), but there is no way to change the file without writing the entire file.
As such I recommend something like this:
...
file = open("users.txt","w") # change this from 'a' to 'w' to overwrite
player1OldScore = int(users[scorePosition1])
if player1Score > player1OldScore:
users[scorePosition1] = str(player1Score) # change the score
file.write(" ".join(users)) # write a string with spaces between elements
print(player2 + "\n \nAchieved a new high score")
...

Python: deleting records from a file sequentially with user's choice

Why is my program skipping through the names as presented in the output?
I am not extremely familiar with dealing with records, but I can work with them.
I need to add code that will allow me to delete a donor and their number. I ask the user if they want to delete each person as the person is read in. However, my program is not reading the fields correctly
This is what the original text file looks like ("name:" and "number:"
are not apart of the text file. I put it there to be more specific about format of records.)
name: mike
number: 5
name: lee
number: 0
name: ramage
number: 2
name: james
number: 6
name: mack
number: 10
More specific on goal:
I want my program to read the name, prompt the user to delete,
if yes, don't write the name or number to temp file (that i will later rename),
if no, write the name and number to temp file.
This is the output after running
Would you like to delete mike (y/n)? y
mike has been deleted
Would you like to delete (y/n)? y
has been deleted
Would you like to delete 0 (y/n)? y
0 has been deleted
Would you like to delete ramage (y/n)? n
Would you like to delete (y/n)? n
Would you like to delete 6 (y/n)? y
6 has been deleted
Would you like to delete mack (y/n)? n
import os
def main():
openOriginal = open("donors.txt", "r")
openNew = open("tempDonor.txt", "w")
readW = openOriginal.readline()
while readW != "":
readW = readW.rstrip("\n")
readN = openOriginal.readline()
print(readW)
print(readN)
s_ask = input("Would you like to delete " + readW + " (y/n)? ")
if s_ask != "y":
openNew.write(readW + "\n")
openNew.write(readN + "\n")
else:
print(readW, "has been deleted")
readW = openOriginal.readline()
openOriginal.close()
openNew.close()
main()
You need to take into account the lines that are blank. As it is, your algorithm deals with the data only 2 lines at a time. Modify your algorithm to deal with 3 lines at a time:
name: james
number: 6
blank line
name: mack
number: 10
blank line
etc..

How do I work out the difference in numbers when reading and writing to text files in python?

Alright, so I am studying python as a hobby, and I need to write a program that: should look at data for each student and calculate the number of marks a student needs to achieve the minimum score when they re-sit their exam. So I am going to say that the minimum score that a user needs to pass their exam is 85, and if a student record says 80, they would need 5. I have written the text file, and started the python code, but I have hit a dead end, any help would be greatly appreciated. Many thanks in advance!
Python:
def menu():
with open('homework.txt','r') as a_file:
contents_of_file = a_file.read()
print(contents_of_file)
input()
Text file:
emma smith,79
noah jones,32
olivia williams,26
liam taylor,91
sophia green,80
mason brown,98
Instead of reading the whole file at once, we will look at each line individually. We'll use split to divide the lines into a name and a number, then use int to convert the string of a number into a numeric type.
def menu():
target = 85
with open('homework.txt','r') as a_file:
for l in a_file:
name, number = l.split(',')
number = int(number)
print(name + ': ' + ('passed' if number>=target else str(target - number)))
input()
('passed' if number>=target else str(target - number)) is just a way of doing an if statement in one line for simple things
There is other possibilities and shorter ways, but to give you a basic understanding, this might help: This should read each line and split it at the comma.
with open('homework.txt','r') as a_file:
for line in a_file.readlines():
split_line=line.split(",")
name=split_line[0]
score=split_line[1]
YOUR CODE HERE
The pandas package is great for manipulating text files like yours. While it might be overkill for your current scenario, it may be useful to learn.
import pandas as pd
marks_needed = 85
df = pd.read_csv('homework.txt', header=None)
for name, marks in df.values:
if marks > marks_needed:
print('{} passed!'.format(name)
else:
extra_marks = marks_needed - marks
print('{} needs {} more marks'.format(name, extra_marks))

Python: Search for the specific strings in a text file consisting of multiple columns

I have a text file which is tab-delimited (every column is responsible for a certain component.):
1 (who?) 2 (age) 3 (Does what?) 4 )(where lives?)
A Dog 4 Walks Lives in a box
B Parrot 2 Eats Lives in a cage
C Cat 3 Sleeps Lives in a house
User has to choose between two option of finding all the information about the animal. User can either type his guess into the first column or the fourth:
1=Cat*
OR
4=Live in a box**
And if there is a match it prints the whole line.
in the first case, if user decides to use first column(who?) to find information about the animal in would show:
Cat 3 Sleeps Lives in a house
in the second case, if user decides to use fourth column(where lives?) to find information about the animal in would show:
Dog 4 Walks Lives in a box
What I need is to find a proper function that will search for an animal. I tried using search() and match() but to no avail.
**EDIT after codesparkle's advice**
I can't seem to integrate the advised function into my program. I am particularly confused with line[column-1] bit. I tried to "play" with this function but I could not come up with anything useful. So here is the real piece of code that I need complete.
while True:
try:
OpenFile=raw_input(str("Please enter a file name: "))
infile=open(OpenFile,"r")
contents=infile.readlines()
infile.close()
user_input = raw_input(str("Enter A=<animal> for animal search or B=<where lives?> for place of living search: \n"))
if user_input.startswith("A="):
def find_animal(user_input,column):
return next(("\t".join(line) for line in contents
if line[column-1]==user_input),None)
find_animal(user_input[1:])
print str((find_animal(user_input[1:], "WHO?"))) # I messed up the first time and gave numeric names to the columns. In reality they should have been words that indicate the proper name of the column. In this case it is WHO- the first column which signifies the animal.
else:
print "Unknown option!"
except IOError:
print "File with this name does not exist!"
Assuming your input looks like this (the example you posted contained spaces, not tabs):
Dog 4 Walks Lives in a box
Parrot 2 Eats Lives in a cage
Cat 3 Sleeps Lives in a house
You can take the following approach:
Open the file and read the lines, splitting them by tab and removing the newline characters.
Create a function that returns the first line whose requested column contains the search term. In this example, None is returned if nothing is found.
with open('input.txt') as input_file:
lines = [line.rstrip().split('\t')
for line in input_file.readlines()]
def find_animal(search_term, column):
return next(('\t'.join(line) for line in lines
if line[column-1] == search_term), None)
print(find_animal('Cat', 1))
print(find_animal('Lives in a box', 4))

Search user input from a string and print

I have a string called new_file that I read from a file with these contents:
;ASP718I
;AspA2I
;AspBHI 0 6 9 15 ...
;AspCNI
;AsuI 37 116 272 348
...
I am using name = raw_input ("enter the enzyme ")
to get data from the user and I am trying to print the corresponding fields from the above file (new_file).
For the input ;AspBHI I'd like the program to print the corresponding line from the file:
;AspBHI 0 6 9 15 ...
How can I achieve this?
This is a start:
db = dict((x.split(" ")[0], x) for x in new_file.split("\n"))
name = raw_input("enter the enzyme ")
print db[name]
Also try to be nice next time, people might help you with more enthusiasm and even explain their approach.

Categories