I cant get my simple shelve python script to work - python

Hey guys i am working on a project for school where i have to ask 10 math questions then store their score name and class but the only thing is i cant seem to get the right back to work in shelve. below is the code im trying to get to work any help would be good.
global username
global clss
global score
file = shelve.open('score.txt',writeback=True)
try:
file['score'] = (username, score, clss)
finally:
file.close ()
EDIT
The thing I am trying to do is to create a script that saves the score class and age of a person. the error im getting is that every time i run the script it deletes the previous data
EDIT change my code to
global username
global clss
global score
file = shelve.open('score',writeback=True)
try:
if 'scores' not in file.keys():
file['score'] = [ (username, score, clss) ]
else:
file['score'].append( (username, score, clss) )
finally:
file.close ()

As I mentioned above, writeback alone will not work if you are just using one tuple. If you want to append a list of user/score/class (i.e. subject) tuples, then do that. (Make sure to keep writeback set to true or else this direct call to append will not work).
try:
if 'scores' not in file.keys():
file['scores'] = [ (username, score, clss) ]
else:
file['scores'].append( (username, score, clss) )

Check the Python documentation for "open." https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files
There is a second field, a string (e.g. "r+"), which changes whether the file is appended to, read-only, or re-written. That should help you.
You may want to bookmark the Python documentation online for more questions of this sort.

Related

delete only 1 instance of a string from a file

I have a file that looks like this:
1234:AnneShirly:anneshirley#seneca.ca:4:5\[SRT111,OPS105,OPS110,SPR100,ENG100\]
3217:Illyas:illay#seneca.ca:2:4\[SRT211,OPS225,SPR200,ENG200\]
1127:john Marcus:johnmarcus#seneca.ca:1:4\[SRT111,OPS105,SPR100,ENG100\]
0001:Amin Malik:amin_malik#seneca.ca:1:3\[OPS105,SPR100,ENG100\]
I want to be able to ask the user for an input(the student number at the beginning of each line) and then ask which course they want to delete(the course codes are the list). So the program would delete the course from the list in the student number without deleting other instances of the course. Cause other students have the same courses.
studentid = input("enter studentid")
course = input("enter the course to delete")
with open("studentDatabase.dat") as file:
f = file.readlines()
with open("studentDatabase.dat","w") as file:
for line in lines:
if line.find(course) == -1:
file.write(line)
This just deletes the whole line but I only want to delete the course
Welcome to the site. You have a little ways to go to make this work. It would be good if you put some additional effort in to this before asking somebody to code this up. Let me suggest a structure for you that perhaps you can work on/augment and then you can re-post if you get stuck by editing your question above and/or commenting back on this answer. Here is a framework that I suggest:
make a section of code to read in your whole .dat file into memory. I would suggest putting the data into a dictionary that looks like this:
data = {1001: (name, email, <whatever the digits stand for>, [SRT111, OPS333, ...],
1044: ( ... )}
basically a dictionary with the ID as the key and the rest in a tuple or list. Test that, make sure it works OK by inspecting a few values.
Make a little "control loop" that uses your input statements, and see if you can locate the "record" from your dictionary. Add some "if" logic to do "something" if the ID is not found or if the user enters something like "quit" to exit/break the loop. Test it to make sure it can find the ID's and then test it again to see that it can find the course in the list inside the tuple/list with the data. You probably need another "if" statement in there to "do something" if the course is not in the data element. Test it.
Make a little "helper function" that can re-write a data element with the course removed. A suggested signature would be:
def remove_course(data_element, course):
# make the new data element (name, ... , [reduced course list]
return new_data_element
Test it, make sure it works.
Put those pieces together and you should have the ingredients to change the dictionary by using the loop and function to put the new data element into the dictionary, over-writing the old one.
Write a widget to write the new .dat file from the dictionary in its entirety.
EDIT:
You can make the dictionary from a data file with something like this:
filename = 'student_data.dat'
data = {} # an empty dictionary to stuff the results in
# use a context manager to handle opening/closing the file...
with open(filename, 'r') as src:
# loop through the lines
for line in src:
# strip any whitespace from the end and tokenize the line by ":"
tokens = line.strip().split(':')
# check it... (remove later)
print(tokens)
# gather the pieces, make conversions as necessary...
stu_id = int(tokens[0])
name = tokens[1]
email = tokens[2]
some_number = int(tokens[3])
# splitting the number from the list of courses is a little complicated
# you *could* do this more elegantly with regex, but for your level,
# here is a simple way to find the "chop points" and split this up...
last_blobs = tokens[4].split('[')
course_count = int(last_blobs[0])
course_list = last_blobs[1][:-1] # everything except the last bracket
# split up the courses by comma
courses = course_list.split(',')
# now stuff that into the dictionary...
# a little sanity check:
if data.get(stu_id):
print(f'duplicate ID found: {stu_id}. OVERWRITING')
data[stu_id] = (name,
email,
some_number,
course_count,
courses)
for key, value in data.items():
print(key, value)
i got something for you. What you want to do is to find the student first and then delete the course: like this.
studentid = input("enter studentid")
course = input("enter the course to delete")
with open("studentDatabase.dat") as file:
f = file.readlines()
with open("studentDatabase.dat","w") as file:
for line in lines:
if studentid in line: # Check if it's the right sudent
line = line.replace(course, "") # replace course with nothing
file.write(line)
You want to check if we are looking at the correct student, then replace the line but without the course code. Hope you can find it useful.

Need to define dictionary without making changes to it

I am trying to do a password saver, where users can insert a password and it will save to a computer. I started with
password = str(input("What is your password that you want to save?"))
url = str(input("Which is the site that you want your password to save to?"))
password_saved = {url : password}
with open('password_saved', 'wb') as password_saved_file:
pickle.dump(password_saved, password_saved_file)
print(password_saved)
However, password_saved = {url:password} resets the whole dictionary in to that one, so if you run it, it will just resets to only one, insead of saving all of it. So, I tried to replace it with:
password_saved[url] = password
But, then, it will say it is not defined. How can I define the dictionary without making any changes to it, including blank-spacing it?
Actually, your code is all fine. But, if you put in the same value 2 times, it won't show. Make sure to try different URLs for each one to make sure that everything works.
First, declare a dictionary then pass index and value to the dictionary.
password_saved = {}
password_saved[url] = password
when you say "it" is not defined, do you mean the dictionary? If so, this could just be a problem of initializing it before you call it. Right now, you are creating a new dictionary named "password_saved" with only one entry. It should look something like
password_saved = {}
...
password = str(input("What is your password that you want to save?"))
url = str(input("Which is the site that you want your password to save to?"))
password_saved[url] = password
with open('password_saved', 'wb') as password_saved_file:
pickle.dump(password_saved, password_saved_file)
print(password_saved)

Write to text file with bot command using discord.py

So basically, I want to be able to add a new employee for a game I play and store the points to rank up in the game. So the first command would be to create the new employee. So say Bob needed to be created. I would want to say "!addcurrentemployee bob" for it to write to the text file and default his points to 0. This is what I have but it isn't working:
#bot.command
async def addcurrentemployee(ctx, username=None, points=0):
desk = "G:/Python/Diamond Security Bot/"
with open(desk + "employees.txt", "rw+") as f:
user = str(username)
pointamount = str(points)
points = 0
f.write(f'{user}, {pointamount}')
f.close()
Is there a specific error you're encountering? Is this decorated as a command? What's the input you're trying? Without more information or context beyond "it isn't working", it's difficult to determine what exactly the issue is that you're asking for help with.
Based on this snippet though, points will be an integer and you'll get a TypeError when you try to concatenate a string with it. This also applies to username, which will be None if one isn't specified. You should look into string formatting.
You might also consider using a context manager for the file instead, e.g.
with open(desk + "employees1.txt", "w") as f:

Check if username already exists in database (Python + Pymongo)

I'm trying to make a registration module to use in a larger login/authentication program and I need to make a function that can check if a username already exists in a collection.
I haven't tried much more than this, this is my first real programming project and I'm stuck on this part. I realize I could use in-line dictionary databases, but I want to learn how to integrate 3rd party databases with my programming.
from pymongo import MongoClient
import time
client = MongoClient('localhost', 27017)
loginDB = client["loginDB"]
userCol = loginDB["userCol"]
##Username##
print('Choose A Unique Username')
time.sleep(1.2)
unameInput = input("Enter Username: ")
unameList = {'Username': unameInput}
unameQuery = {}
unameQuery2 = userCol.find_one({'Username.Username': {'$gt': 'a'}})
if unameInput != unameQuery2:
print('Name is Available | Accepted!')
allList = {'Username': unameList}
userCol.insert_one(allList)
else:
print('Sorry, Please Try Again.')`
The expected result is to search the database for everything that starts with the letter "a", forward. If the input (unameInput) does not equal anything in the query result (unameQuery2), then print "Username is available". If anything in the query matches the input, then print "Please try again", however, it's accepting everything that is input and exiting the code.
You are using find_one() to find one entry in Username and then checking if unameInput is equal to it. If it's not an exact match, it will execute the code for name is available.
Try find() instead as this will iterate over all the documents in the collection.
unameQuery2 = userCol.find()
if unameInput not in unameQuery2:
# do something
I figured it out, I was putting dictionaries inside of dictionaries inside of documents, as well as not iterating "allList".

Checking to see whether the users input is correct with the correct version

OK, so what my program is all about is that the user has to solve a coded puzzle which gets read in from an external file. The user then guesses what letter matches up with the symbol in the coded puzzle and they can then add this to a list of clues.
One of the options in my program allows the user to check whether the clues they have entered are correct with the solved version. The solved version is read in from an external file and this is what needs to get checked with the list of clues.
So far I have a basic piece of code but what keeps on happening is that the output I get is that " You scored 0 out of 10" even though some of the pairings I have entered are correct.
My code so far for this section of code is this...
def check_clues():
count = 0
# TRIES TO OPEN FILE SOLVED.TXT
try:
with open('solved.txt') as r:
# READS THROUGH ALL THE LINES IN SOLVED.TXT
solved = r.readlines()
# WILL DISPLAY AN ERROR MESSAGE IF SOLVED.TXT IS NOT FOUND
except:
print("Error finding file")
# WILL TRY AND OPEN THE FILE 'clues.txt'
try:
with open('clues.txt') as r:
clues = r.readlines()
except:
print("Error finding ")
# GOES THROUGH BOTH THE USERS CLUES AND SOLVED.TXT TO SEE HOW MANY CLUES ARE THE SAME
for clue in clues:
if clue in solved:
count += 1
# Prints the amount of clues the user got right out of 10
print('You got:', count, 'correct!')
Below is what is in the solved.txt file:
ACQUIRED
ALMANAC
INSULT
JOKE
HYMN
GAZELLE
AMAZON
EYEBROWS
AFFIX
VELLUM
Below is what is in clues.txt
A#
M*
N%
However please note clues.txt is the list which the user can add to. So if the user decides to enter S and &, this will add to the clues.txt as S&
Below is the file words.txt which contains the list of coded words the user has to solve...
#+/084&"
#3*#%#+
8%203:
,1$&
!-*%
.#7&33&
#*#71%
&-&641'2
#))85
9&330*
I had a hand at this, using what you're provided. I believe this is what you're looking for provided you have all the files you listed. Basically I used the words.txt and solved.txt files and created a dictionary mapping all the symbols to their correct letters. Then I used that dictionary to compare each clue to see if they match. This would increment the count and you would get your correct output.
The problem with your original code is that you're simply searching if the clue is inside of the solved text file. For example, you search if your first clue A* is inside of the words text file. Obviously it isn't because there isn't a * in that file. So you need something to baseline/compare it to. Which is why in this case I created a dictionary. I also removed your try/except loops since your program should technically never run if a file is missing. In which case your exceptions will allow the program to keep running even if a file is missing producing multiple error outputs. It should stop if no files are found or be handled specifically, not allow it to keep running as it normally would. If you go that route, I'd also advise only using except WindowsError to avoid catching any other potential exceptions.
def check_clues():
# Dictionary to hold all of the symbol/letter combos
coded_dict = {}
# Go through each symbol/letter combination together
with open("words.txt") as fw, open("solved.txt") as fs:
for fw_line, fs_line in zip(fw, fs):
for fw_symbol, fs_letter in zip(fw_line.strip(), fs_line.strip()):
# Add the symbol/letter combination to the dictionary
coded_dict[fw_symbol] = fs_letter
correct_clues = []
with open("clues.txt") as fc:
for fc_line in fc:
# If the symbol is in the dictionary and the letter matches the symbol
if fc_line[1] in coded_dict and coded_dict[fc_line[1]] == fc_line[0]:
# Add a correct clue to your list
correct_clues.append(fc_line.strip())
print("You got a total of {0} correct: {1}".format(len(correct_clues), ", ".join(correct_clues)))
if __name__ == "__main__":
check_clues()
If you need me to elaborate on anything let me know.

Categories