Python, Writing the file twice - python

I'm trying to get my code so it will update Y7,Set1.txt but it keeps writing the data inside it again, + my new data that was added.
My code below:
print("Registration System")
print("Make sure their is atleast one name in register!")
password = ("admin")
check = input("The Administration Password is: ")
if check == password:
input("Enter any key to continue ")
print("If their is no names in the register.txt\nThe script will stop working here!")
set1 = list()
set2 = list()
set3 = list()
set4 = list()
set5 = list()
with open("register.txt", "r") as register:
registers = [line.rstrip("\n") for line in register]
for pop in registers:
print(pop)
choice = input(
'Where would you like it to go? (Enter 1 - set1, enter 2 - set2)')
if choice == '1':
set1.append(pop)
elif choice == '2':
set2.append(pop)
elif choice == '3':
set3.append(pop)
elif choice == '4':
set4.append(pop)
elif choice == '5':
set5.append(pop)
with open("Y7,Set2.txt", "r") as Y7R:
Y7 = [line.rstrip("\n") for line in Y7R]
with open("Y7,Set2.txt", "w") as Y7Y:
data = (str(Y7) + str(set2))
Y7Y.writelines(data)
with open("Y7,Set1.txt", "r") as d:
Y7S = [line.rstrip("\n") for line in d]
with open("Y7,Set1.txt", "w") as Y7D:
data2 = str(Y7S) + str(set1)
Y7D.writelines(data2)
else:
print("Access Denied!")
However the text file keeps printing the previous values, + a lot of ///////
Anyway I can get my code just to add information to that file, without adding all the /// and previous names? Thanks!
What's happening in the file is:
['[\'[\\\'[\\\\\\\'[\\\\\\\\\\\\\\\'[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'[\\\\\\\
PaulBrennan\\\\\\\\\

Open the file with "a" mode. "r" mode is used when the file only needs to be read and "w" for only writing (an existing file with the same name will be erased).
open("Y7,Set2.txt", "a")
You can check the docs.

Related

How to open and read a file in python while it's an subfolder?

I have created a program where I have two text files: "places.txt" and "verbs.txt" and It asks the user to choose between these two files. After they've chosen it quizzes the user on the English translation from the Spanish word and returns the correct answer once the user has completed their "test". However the program runs smoothly if the text files are free in the folder for python I have created on my Mac but once I put these files and the .py file in a subfolder it says files can't be found. I want to share this .py file along with the text files but would there be a way I can fix this error?
def CreateQuiz(i):
# here i'm creating the keys and values of the "flashcards"
f = open(fileList[i],'r') # using the read function for both files
EngSpanVocab= {} # this converts the lists in the text files to dictionaries
for line in f:
#here this trims the empty lines in the text files
line = line.strip().split(':')
engWord = line[0]
spanWord = line[1].split(',')
EngSpanVocab[engWord] = spanWord
placeList = list(EngSpanVocab.keys())
while True:
num = input('How many words in your quiz? ==>')
try:
num = int(num)
if num <= 0 or num >= 10:
print('Number must be greater than zero and less than or equal to 10')
else:
correct = 0
#this takes the user input
for j in range(num):
val = random.choice(placeList)
spa = input('Enter a valid spanish phrase for '+val+'\n'+'==> ')
if spa in EngSpanVocab[val]:
correct = correct+1
if len(EngSpanVocab[val]) == 1:
#if answers are correct the program returns value
print('Correct. Good work\n')
else:
data = EngSpanVocab[val].copy()
data.remove(spa)
print('Correct. You could also have chosen',*data,'\n')
else:
print('Incorrect, right answer was',*EngSpanVocab[val])
#gives back the user answer as a percentage right out of a 100%
prob = round((correct/num)*100,2)
print('\nYou got '+str(correct)+' out of '+str(num)+', which is '+str(prob)+'%'+'\n')
break
except:
print('You must enter an integer')
def write(wrongDict, targetFile):
# Open
writeFile = open(targetFile, 'w')
# Write entry
for key in wrongDict.keys():
## Key
writeFile.write(key)
writeFile.write(':')
## Value(s)
for value in wrongDict[key]:
# If key has multiple values or user chooses more than 1 word to be quizzed on
if value == wrongDict[key][(len(wrongDict[key])) - 1]:
writeFile.write(value)
else:
writeFile.write('%s,'%value)
writeFile.write('\n')
# Close
writeFile.close()
print ('Incorrect answers written to',targetFile,'.')
def writewrong(wringDict):
#this is for the file that will be written in
string_1= input("Filename (defaults to \'wrong.txt\'):")
if string_1== ' ':
target_file='wrong.txt'
else:
target_file= string_1
# this checs if it already exists and if it does then it overwrites what was on it previously
if os.path.isfile(target)==True:
while True:
string_2=input("File already exists. Overwrite? (Yes or No):")
if string_2== ' ':
write(wrongDict, target_file)
break
else:
over_list=[]
for i in string_1:
if i.isalpha(): ovrList.append(i)
ovr = ''.join(ovrList)
ovr = ovr.lower()
if ovr.isalpha() == True:
#### Evaluate answer
if ovr[0] == 'y':
write(wrongDict, target)
break
elif ovr[0] == 'n':
break
else:
print ('Invalid input.\n')
### If not, create
else:
write(wrongDict, target)
def MainMenu():
## # this is just the standad menu when you first run the program
if len(fileList) == 0:
print('Error! No file found')
else:
print( "Vocabulary Program:\nChoose a file with the proper number or press Q to quit" )
print(str(1) ,"Places.txt")
print(str(2) ,"Verbs.txt")
while True:
#this takes the user input given and opens up the right text file depending on what the user wants
MainMenu()
userChoice = input('==> ')
if userChoice == '1':
data = open("places.txt",'r')
CreateQuiz(0)
elif userChoice == '2':
data = open("verbs.txt",'r')
CreateQuiz(1)
elif userChoice == 'Q':
break
else:
print('Choose a Valid Option!!\n')
break
You are probably not running the script from within the new folder, so it tries to load the files from the directory from where you run the script.
Try setting the directory:
import os
directory = os.path.dirname(os.path.abspath(__file__))
data = open(directory + "/places.txt",'r')

Trying to make encryption program which reads and writes to files and encrypts with two keywords. len() function not working

Trying to create an encryption/decryption program in python that reads a message from a file, encrypts with two keywords then outputs to another file. Also, it can do this in reverse.
I'mm having an issue with the len() function:
I get the error: object of type built in function or method has no len() in this section of code:
if (len(line)) == 0:
fileRead = True
In context this is the whole program:
print("Welcome to Python Encrypt 2015")
print("Only enter alphabet charcters into the file - no punctuation!")
#repeat loop for using program again and so on...
finished = False
while not finished:
#input and validation of encrypt/decrypt input
option = input("Do you want to encrypt or decrypt? (E/D): ")
while "E" != option != "D":
option = input("Only input 'E' or 'D'! Do you want to encrypt or decrypt? (E/D): ")
#file to be encrypted/decrypted is opened to read
message = ""
fileRead = False
if option == "E":
file = open("Task3Decrypted.txt","r")
else:
file = open("Task3Encrypted.txt","r")
#message from 'to encrypt' file is read and outputted to variable
while not fileRead:
line = (file.readline()).strip()
if line.isalpha()==True:
line = line.lower
else:
input("Message contains numbers or symbols. Please correct! Press any key to continue: ")
sys.exit
if (len(line)) == 0:
fileRead = True
else:
message = message + line
#file closed - saving it
file.close()
#validating keyword and stretching and cutting to length of message
key1True = False
while key1True == False:
keyword1 = input("Enter your first keyword: ")
if keyword1.isalpha()==True:
keyword1 = keyword1.lower()
key1True = True
key1length = len(keyword1)
while len(keyword1)<len(message):
keyword1=keyword1+keyword1
keyword1=keyword1[:len(message)]
key2True = False
while key2True == False:
keyword2 = input("Enter your second keyword: ")
if keyword2.isalpha()==True:
keyword2 = keyword2.lower()
key2True = True
key2length = len(keyword2)
while len(keyword2)<len(message):
keyword2=keyword2+keyword2
keyword2=keyword2[:len(message)]
newMessage = ""
for i in range(len(message)):
char = ord(message[i])-96
key1 = ord(keyword1[i])-96
key2 = ord(keyword2[i])-96
if char==-64:
newMessage = newMessage+" "
else:
if option == "E":
#clearing original file for security
clearFileE = open("Task3Decrypted.txt","w")
clearFileE.close
#encryption
if char+key1+key2>26:
newMessage = newMessage+chr(char+key1+key2-26+96)
else:
newMessage = newMessage+chr(char+key1+key2+96)
newFile = open("Task3Encrypted.txt","w")
newFile.write(newMessage)
newFile.close()
else:
clearFileD = open("Task3Encrypted.txt","w")
clearFileD.close
#decryption
if char-key1-key2<1:
newMessage = newMessage+chr(char-key1-key2+26+96)
else:
newMessage = newMessage+chr(char-key1-key2+96)
newFile = open("Task3Decrypted.txt","w")
newFile.write(newMessage)
newFile.close()
carryOn = input("Do you want to encrypt/decrypt another message? (Y/N): ")
while "Y" != carryOn != "N":
carryOn = input("Only input 'Y' or 'N'! Do you want to encrypt/decrypt another message? (Y/N): ")
if carryOn == "N":
finished = True
Thanks in advance!
You left off the parentheses in
line = line.lower()
Without the (), you're setting line to the object of the lower() function itself, hence the error message.

python: Adding to username

I am fairly new to python and I need to make a program to ask 10 questions, save the score into a file and allow someone to read the scores in from the file.
My problem: I need to check if the person who has done the quiz already has a record in the file, and if so, I need to add their score to the end of their record.
The records should look like this:
name,score,score,score,score,
etc so they can be split using commas.
I am also looking for the simplest answer, not the most efficient. Also, if you could comment the code, it would make it much easier. Here is my code so far:
import random
import math
import operator as op
import sys
import re
def test():
num1 = random.randint(1, 10)
num2 = random.randint(1, num1)
ops = {
'+': op.add,
'-': op.sub,
'*': op.mul,
}
keys = list(ops.keys())
rand_key = random.choice(keys)
operation = ops[rand_key]
correct_result = operation(num1, num2)
print ("What is {} {} {}?".format(num1, rand_key, num2))
while True:
try:
user_answer = int(input("Your answer: "))
except ValueError:
print("Only enter numbers!")
continue
else:
break
if user_answer != correct_result:
print ("Incorrect. The right answer is {}".format(correct_result))
return False
else:
print("Correct!")
return True
print("1. Are you a student?")
print("2. Are you a teacher?")
print("3. Exit")
while True:
try:
status = int(input("Please select an option:"))
except ValueError:
print("Please enter a number!")
else:
if status not in {1,2,3}:
print("Please enter a number in {1,2,3}!")
else:
break
if status == 1:
username=input("What is your name?")
while not re.match("^[A-Za-z ]*$", username) or username=="":
username=input(str("Please enter a valid name (it must not contain numbers or symbols)."))
print ("Hi {}! Wellcome to the Arithmetic quiz...".format(username))
while True:
try:
users_class = int(input("Which class are you in? (1,2 or 3)"))
except ValueError:
print("Please enter a number!")
else:
if users_class not in {1,2,3}:
print("Please enter a number in {1,2,3}!")
else:
break
correct_answers = 0
num_questions = 10
for i in range(num_questions):
if test():
correct_answers +=1
print("{}: You got {}/{} {} correct.".format(username, correct_answers, num_questions,
'question' if (correct_answers==1) else 'questions'))
if users_class == 1:
class1 = open("Class1.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class1.write(newRecord)
class1.close()
elif users_class == 2:
class2 = open("Class2.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class2.write(newRecord)
class2.close()
elif users_class == 3:
class3 = open("Class3.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class3.write(newRecord)
class3.close()
else:
print("Sorry, we can not save your data as the class you entered is not valid.")
EDIT:
Add this function before your "test" function:
def writeUserScore(file, name, score):
with open (file, "r") as myfile:
s = myfile.read()
rows = s.split("\n")
data = {}
for row in rows:
tmp = row.split(",")
if len(tmp) >= 2: data[tmp[0]] = tmp[1:]
if name not in data:
data[name] = []
data[name].append(str(score))
output = ""
for name in data:
output = output + name + "," + ",".join(data[name]) + "\n"
handle = open(file, "w+")
handle.write(output)
handle.close()
After that, where you have "if users_class == 1:" do this:
writeUserScore("Class1.txt", username, str(correct_answers))
Do the same for the other two else ifs.
Let me know what you think!
Try using a dictionary to hold the existing file data.
Read the file in a variable called "str" for example. And then do something like this:
rows = str.split("\n")
data1 = {}
for row in rows:
tmp = row.split(",")
data1[tmp[0]] = tmp[1:]
When you have a new score you should then do:
if username not in data1:
data1[username] = []
data1[username] = str(correct_answers)
And to save the data back to the file:
output = ""
for name in data1:
output = outupt + name + "," + ",".join(data1[name]) | "\n"
And save the contents of "output" to the file.
PS: If you are not bound by the file format you can use a JSON file. I can tell you more about this if you wish.
Hope that helps,
Alex
First, define these functions:
from collections import defaultdict
def read_scores(users_class):
"""
If the score file for users_class does not exist, return an empty
defaultdict(list). If the score file does exist, read it in and return
it as a defaultdict(list). The keys of the dict are the user names,
and the values are lists of ints (the scores for each user)
"""
assert 0 <= users_class <= 3
result = defaultdict(list)
try:
lines =open("Class%d.txt"%users_class,'r').readlines()
except IOError:
return result
for line in lines:
# this line requires python3
user, *scores = line.strip().split(',')
# if you need to use python2, replace the above line
# with these two lines:
# line = line.strip().split(',')
# user, scores = line[0], line[1:]
result[user] = [int(s) for s in scores]
return result
def write_scores(users_class, all_scores):
"""
Write user scores to the appropriate file.
users_class is the class number, all scores is a dict kind of dict
returned by read_scores.
"""
f = open("Class%d.txt"%users_class,'w')
for user, scores in all_scores.items():
f.write("%s,%s\n"%(user, ','.join([str(s) for s in scores])))
def update_user_score(users_class, user_name, new_score):
"""
Update the appropriate score file for users_class.
Append new_score to user_name's existing scores. If the user has
no scores, a new record is created for them.
"""
scores = read_scores(users_class)
scores[user_name].append(new_score)
write_scores(users_class, scores)
Now, in the last portion of your code (where you actually write the scores out) becomes much simpler. Here's an example of writing some scores:
update_user_score(1, 'phil', 7)
update_user_score(1, 'phil', 6)
update_user_score(1, 'alice', 6)
update_user_score(1, 'phil', 9)
there will be two lines in Class1.txt:
phil,7,6,9
alice,6
We read the whole file into a dict (actually a defaultdict(list)),
and overwrite that same file with an updated dict. By using defaultdict(list), we don't have to worry about distinguishing between updating and adding a record.
Note also that we don't need separate if/elif cases to read/write the files. "Scores%d.txt"%users_class gives us the name of the file.

Python file scanning

I have a some code in a game I'm making where it stores user data on a text file called data.txt. The following code is when a person continues, then it will read the part where the level is stored and see where it will begin the game:
elif choice==("2"):
contusername = input("Enter the name you registered with")
with open("data.txt") as f:
f.readline()
for lines in f:
name, level = lines.split()
if name == contusername:
userdata = level
break
while True:
if level == 1:
level1()
elif level == 2:
level2()
#and so on
But it won't work. Python can't read the text file. How do I fix this?
You probably forgot to cast to int:
userdata = int(level)
Other way your userdata are strings of form '1\n'
Also, you want to use this userdata in comparison, not level
while True:
if userdata == 1:
level1()
p.s. I don't know whether this while True: statement is correct, as only a code excerpt is presented, but it also looks suspitious for me.
It appears you have a Type problem. Reading from a file will give you a string, but you are checking for integers.
Try forcing the level numbers to an int.
elif choice==("2"):
contusername = input("Enter the name you registered with")
with open("data.txt") as f:
f.readline()
for lines in f:
name, level = lines.split()
if name == contusername:
userdata = level
break
level = int(level) # <-- force the level to an integer
while True:
if level == 1:
level1()
elif level == 2:
level2()
This should work :
elif choice == "2":
contusername = raw_input("Enter the name you registered with")
with open("data.txt") as f:
for lines in f.readlines():
name, level = lines.split()
if name == contusername:
userdata = int(level)
break
while True:
if userdata == 1:
level1()
elif userdata == 2:
level2()

Anything other than the variable Python

I am very much new to Python and basically want anything other than d or o to rerun the question? Any help?
Myfile = raw_input( '''Specify filename (o) or use default chain (d)? ''')
if Myfile == 'd':
print 'default choosen '
Myfile = 'M:/test/testchains_a.csv'
if Myfile == 'o':
print 'own file choosen '
Myfile = raw_input('Enter absolute path to the .csv file:')
else:
print 'successful'
You could use a while loop to check whether or not the input is and 'o' or a 'd':
MyFile = None
while MyFile != 'o' and MyFile != 'd':
Myfile = raw_input( '''Specify filename (o) or use default chain (d)? ''')
You can do this the way squiguy suggested, but it might be more readable to put the whole thing into a loop, so you don't have to repeat the same checks twice:
while True:
Myfile = raw_input( '''Specify filename (o) or use default chain (d)? ''')
if Myfile == 'd':
print 'default choosen '
Myfile = 'M:/test/testchains_a.csv'
break
elif Myfile == 'o':
print 'own file choosen '
Myfile = raw_input('Enter absolute path to the .csv file:')
break
This will loop forever, until it hits a breakā€”in other words, until they select 'd' or 'o'.
You can use a loop:
wrong = True
while(wrong):
file = raw_input("My awesome prompt")
if file == "d":
file = '/some/path'
wrong = False
if file == "o":
file = raw_input("Where?")
wrong = False
# Continue your program...
I think your actual problem here is bad UI design. The first question is superfluous and can be easily eliminated:
myfile = raw_input('Enter absolute path to the .csv file (leave blank to use the default):')
myfile = myfile or 'M:/test/testchains_a.csv'
This "hit enter to use the default" approach is quite common in dialogue programs.
To answer the question as asked, I'd suggest using a function like this:
def prompt(message, choices):
while True:
s = raw_input(message)
if s in choices:
return s
and in your main code:
option = prompt('Specify filename (o) or use default chain (d)? ', 'od')
if option == 'd':
...
elif option == 'o':
...
use elif (elseif) and else
file = input("enter (d) to use the default file or enter (c) to specify a custom path: ")
if file.lower() == "d":
print("some code")
elif file.lower() == "c":
print("some code")
else:
print("invalid answer!")
input()

Categories