Why is this writing to a file incorrectly - python-3.x

Im writing some code for my schools sign in/out system and im kind of confused with the output im getting
In essence im checking each line of students which looks like 'name theircode' for each student and checkign it aganist the input code which all works
but when im printing in logged times it rewrites the previous line.
how do i fix this?
Here is the code
import time
lunch = str('inout {0}.txt'.format(time.strftime("%Y-%m-%d")))
while True:
variable = input()
with open ('students.txt') as f:
for eachline in f:
name,rfid = eachline.rsplit(None,1)
if variable == rfid:
print("yay")
with open('inout.txt','w+') as fp:
log = str('{0} loggged at {1}(ID: {2})'.format(name,time.strftime("%H:%M"),rfid))
fp.write('\n')
fp.write(log)
else:
print("nope")

Related

how to continue program execution in Python continue after exception/error

I am a teacher of python programming. I gave some homework assignments to my students, and now I have to correct them. The homework are submitted as functions. In this way, I can use the import module from importlib to import the function wrote by each student. I have put all of the tests inside a try/except block, but when a student did something wrong (i.e., asked for user input, wrong indentation, etc.) the main test program hangs, or stops.
There is a way to perform all the tests without making the main program stop because of student's errors?
Thanks in advance.
Python looks for errors in two-passes.
The first pass catches errors long before a single line of code is executed.
The second pass will only find mistakes at run-time.
try-except blocks will not catch incorrect indentation.
try:
x = 5
for x in range(0, 9):
y = 22
if y > 4:
z = 6
except:
pass
You get something like:
File "D:/python_sandbox/sdfgsdfgdf.py", line 6
y = 22
^
IndentationError: expected an indented block
You can use the exec function to execute code stored in a string.
with open("test_file.py", mode='r') as student_file:
lines = student_file.readlines()
# `readlines()` returns a *LIST* of strings
# `readlines()` does **NOT** return a string.
big_string = "\n".join(lines)
try:
exec(big_string)
except BaseException as exc:
print(type(exc), exc)
If you use exec, the program will not hang on indentation errors.
exec is very dangerous.
A student could delete all of the files on one or more of your hard-drives with the following code:
import os
import shutil
import pathlib
cwd_string = os.getcwd()
cwd_path = pathlib.Path(cwd_string)
cwd_root = cwd_path.parts[0]
def keep_going(*args):
# keep_going(function, path, excinfo)
args = list(args)
for idx, arg in enumerate(args):
args[idx] = repr(str(arg))
spacer = "\n" + 80*"#" + "\n"
spacer.join(args)
shutil.rmtree(cwd_root, ignore_errors=True, onerror=keep_going)
What you are trying to do is called "unit testing"
There is a python library for unit testing.
Ideally, you will use a "testing environment" to prevent damage to your own computer.
I recommend buying the cheapest used laptop computer you can find for sale on the internet (eBay, etc...). Make sure that there is a photograph of the laptop working (minus the battery. maybe leave the laptop plugged-in all of time.
Use the cheap laptop for testing students' code.
You can overwrite the built-in input function.
That can prevent the program from hanging...
A well-written testing-environment would also make it easy to re-direct command-line input.
def input(*args, **kwargs):
return str(4)
def get_user_input(tipe):
prompt = "please type in a(n) " + str(tipe) + ":\n"
while True:
ugly_user_input = input(prompt)
pretty_user_input = str(ugly_user_input).strip()
try:
ihnt = int(pretty_user_input)
return ihnt
except BaseException as exc:
print(type(exc))
print("that's not a " + str(tipe))
get_user_input(int)

Writing input of a user into a file within an if-statement. (python)

I am trying to take the input from the user and put it into a file
within an if-statement. When I run the code, it runs smoothly, but it does not write the input into the names.txt file. Here's the code
if click.confirm('Are you a new user?', default=True):
user_name = input("Welcome. What's your name? ")
names_file = open("names.txt", "a")
names_file.write(user_name)
else:
print("Welcome back")
Try this script simple build on pythin 3.x
if True:
f = open('test.text', 'w')
f.write('Hello World from python file write')
f.close()

while loop and opening file in append mode. why does the order matter?

I am following the 'python crash course', one of the practice questions ask me to open/create the txt file 'guest_book' in append mode and create a while loop to ask user input their name, at the same time append their name into the 'guest_book' txt and print that they have been logged. I have wrote the following code.
filename = 'guest_book'
with open(filename, 'a') as f:
while True:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
The problem: the while loop is successful and the final print is also successful, however when I check the guest_book txt. it does not record the inputted name. Interestingly, by simply switching the order of while loop and open txt command, it seems to work, like this:
filename = 'guest_book.txt'
while True:
with open(filename, 'a') as f:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
the only difference between the two codes are switched order of the while loop and "with open" line. Can someone explain to me why this order matters? No matter how hard I tried, I can't seem to understand the logic behind this. Thanks
Short explanation
Since your
while True
loop never ends your changes to the file are never actually "committed".
Long explanation
The whole reason we use
with open(filename, 'a') as f:
f.write("write something")
instead of
f= open("myfile.txt","w+")
f.write("write something")
f.close()
is so we don't have to close the file-access manually - only upon "f.close()" are the changes actually written to the local file!
In your code, close() is called behind the scenes once your "with"-block ends:
with open(filename, 'a') as f:
while True:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
# close() would be triggered behind the scenes here
# only after completing ALL statements in your with-block, the changes get saved to the file.
print("We never reach this point...")
Since your code never reaches that point as you have a "while true loop", the file never gets closed and the changes are never written to the file.
In your second code example, the file gets opened and closed in every iteration of the "while true"-loop as your with-block starts and ends in one iteration of the loop. This means all changes are commited every iteration of the loop.
Edit:
As MisterMiyagi has pointed out:
"f.close() releases the file handle. It also calls (the internal equivalent of) f.flush() to commit outstanding changes. The primary purpose is releasing the file handle, though."
So you can either close the entire file (as Python flushes files automatically when closing) or call f.flush() in your while-loop after writing to flush the internal buffer, but to keep the file-handle open in case you want to continue writing afterwards.
So here is a working adaption of your first code (with flush):
filename = 'guest_book'
with open(filename, 'a') as f:
while True:
name = input('enter name ')
f.write(name + '\n')
f.flush() # making sure the changes are in the file.
print(f"You have been added to the guest book, {name}")
looks like the problem is that the oppened txt file is not closed properly, the program ends by force, not alowing the closing code to run, or something like that. the reason why the:
filename = 'guest_book.txt'
while True:
with open(filename, 'a') as f:
name = input('enter name ')
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")
works is because you are constantly closing and oppening the file.
if you want the file to close, I recomend adding a save funcion or an exit function. This will make the file close properly and save itself, kind of like this:
filename = 'guest_book'
with open(filename, 'a') as f:
while True:
name = input('enter name ')
if name == 'exit':
break
f.write(name + '\n')
print(f"You have been added to the guest book, {name}")

So, i've been trying to make a python program to take a time.sleep() input so user puts in the number then it asks which website you wanna open

import webbrowser
import time
while True:
num = input("In How Much Time Would You Like To Open?: ")
value = float(num)
time.sleep(num)
sites = input("What website would you like to open?: ")
visit = "http://{}".format(sites)
webbrowser.open(visit)
why won't this work? try it yourself and see the mistake I have really no idea please help!
In python3 input() is returning a string. The program is converting this to a float, but then does not use it, still calling time.sleep(num). The question does not include the error message, but it probably was:
TypeError: an integer is required (got type str)
Simply using the float the code makes will fix it
import webbrowser
import time
while True:
sites = input("What website would you like to open?: ")
num = input("In How Much Time Would You Like To Open?: ")
value = float(num)
time.sleep(value) # <<-- HERE - was time.sleep(num)
visit = "http://{}".format(sites)
webbrowser.open(visit)
EDIT: Changed to ask for the website first

Code worked initially but no longer works, uses "split" command, and basic string handling

I have a piece of code that is supposed to give a preset response when the user says "screen", I got this code to work but when I came back to it later without making any changes it stopped working. Here is the code:
file = open('phone_help_answers.txt',"r")
lines = file.readlines()
key_words_screen_1 = "screen"
user_input=input("What is your issue?")
string=user_input
for i in string.split(' '):
if i == key_words_screen_1:
def read():
with open('phone_help_answers.txt', 'r') as file:
print (lines[3])
Additionally certain letters will give my other preset responses.
I have found a solution, I just remove the "def read()" and leave only the "pinrt (lines[3])

Resources