Permission denied once code is changed - python

I'm still a newb to this, so sorry if I mess up :D
So I'm trying to write a script that goes through some .xml files to get certain lines and put's them into an excel sheet.
Code:
import os
import openpyxl
def main():
print_header()
folder = get_folder_from_user()
if not folder:
print("Sorry, that folder doesn't exist.")
return
text = get_search_text_from_user()
if not text:
print("Sorry, I can't search for nothing.")
return
count = input("Show match count? y/n")
name = "output.xlsx"
# name = input("Name for workbook: ")
x = []
output = search_file(folder, text)
match_count = 0
for i in output:
match_count += 1
string = i
string = string.split(">")
string = string[1]
string = string.split("<")
string = string[0]
i = string
print(i)
x.extend([i])
write_to_workbook(name, x)
if count == "y":
print("==================")
print("Found {} matches".format(match_count))
print("==================")
def write_to_workbook(name, x):
wb = openpyxl.Workbook()
ws = wb.active
a = 1
ws.append(x)
wb.save("C:/Users/Kevin/Desktop/{}".format(name))
a += 1
def print_header():
print("-----------------------------------")
print("----------File Search App----------")
print("-----------------------------------")
print()
def get_folder_from_user():
folder = input("Which folder do you want to search? ")
if not folder or not folder.strip():
return None
if not os.path.isdir(folder):
return None
return os.path.abspath(folder)
def get_search_text_from_user():
print("Which data do you want me to copy for you?")
print("[1]SeqTest Read")
print("[2]SeqTest Write")
print("[3]Random 4K1TTest Read")
print("[4]Random 4K1TTest Write")
print("[5]Random 4K64TTest Read")
print("[6]Random 4K64TTest Write")
print("[7]AccTimeTest Read")
print("[8]AccTimeTest Write")
print("[9]Score")
print("[0]All")
choice = int(input("Choose now: "))
if choice == 1:
line = 15
elif choice == 2:
line = 16
elif choice == 3:
line = 19
elif choice == 4:
line = 20
elif choice == 5:
line = 23
elif choice == 6:
line = 24
elif choice == 7:
line = 27
elif choice == 8:
line = 28
elif choice == 9:
line = 99
elif choice == 0:
line = 100
else:
line = 0
line = 15
return int(line)
def search_folders(folder, line):
items = os.listdir(folder)
for item in items:
full_item = os.path.join(folder, item)
if os.path.isdir(full_item):
yield from search_folders(full_item, line)
else:
yield from search_file(full_item, line)
def search_file(filename, line):
with open(filename, 'r', encoding='utf-8') as fin:
lines = fin.readlines()
if line == 99:
print(lines[31])
print(lines[32])
print(lines[33])
yield ("/n".join(lines[31:34]))
elif line == 100:
s = 0
while s < 10:
print(filename)
print(lines[4])
if line == 15 or 16:
print("Seq")
if line == 15:
print("Read")
else:
print("Write")
elif line == 19 or 20:
print("4k ")
if line == 19:
print("Read")
else:
print("Write")
elif line == 23 or 24:
print("4k 64")
if line == 23:
print("Read")
else:
print("Write")
elif line == 27 or 28:
print("Acc")
if line == 27:
print("Read")
else:
print("Write")
elif line == 99:
print("")
yield (lines[line])
else:
print(filename)
print(lines[4])
if line == 15 or 16:
print("Seq")
if line == 15:
print("Read")
else:
print("Write")
elif line == 19 or 20:
print("4k ")
if line == 19:
print("Read")
else:
print("Write")
elif line == 23 or 24:
print("4k 64")
if line == 23:
print("Read")
else:
print("Write")
elif line == 27 or 28:
print("Acc")
if line == 27:
print("Read")
else:
print("Write")
elif line == 99:
print("")
yield (lines[line])
if __name__ == '__main__':
main()
In short:
User has to type in the directory with the text files.
Then the wanted lines are chosen. (Fixed to line 15 for testing. I didn't get to the point to fix a problem when I want every line specified in the selection).
The user is then asked if he wants the total amount of matches.
Then it runs through all the text files and outputs line 15 of every file (just some data from ssd benchmarks).
The data is denn written into an excel file.
The code is working mostly. I still have to figure out how to properly output the data to excel (format is not as I want it).
But the problem is that the permissions to the directory change as soon as I add this Code:
def trigger_search(filename, line):
xyz = search_file(filename, line)
return xyz
As soon as I add this I get an errno 13: Permission denied.
It can't access the directory with the .xml files anymore.
Even if I delete the added code, I still get this error.
Only workaround is to copy the "unchanged" code (without the trigger_search) and overwrite the .py file.
Just copy paste and it works fine (no matter how often I run the code).
Any hint why this happens and how to fix this?
Please don't be too harsh because of the code, I know it's really newbie like. It'll be made properly as soon as it works :D

Nevermind guys.
I'm just dumb.
in the trigger_search I had to use search_folders, not search_file.
When changing the code back, I also replaced it with search_file although it was search_folders before in main method..
Using the right method actually works.
I'm so sorry...

The reason here that it is returning an error is because you have not run it as an administrator. Before I show you how to solve the problem, you will either need to be an administrator on your computer or you will have to know the password of an administrator. Also, this answer assumes that you are running Windows on your computer.
2 WAYS IF YOU RAN THIS PROGRAM FROM CMD
There are two ways to do this. The first way is to run the program "Run" (it was automatically installed by Windows), then type in cmd.exe. The second way is to tap the Windows key and look up cmd, and right-click the button that says "Command Prompt", and click on the button that says "Run as administrator".
The second way is to open the Command Prompt, and type in runas /profile /user:administrator “insert\path\here\program.py” where "administrator" should be replaced with your username on the computer, and "insert\path\here" should be replaced with the path where your program is in, and "program.py" should be replaced with the name of your program (if you are in the same directory as the program, then you do not need to include the path.)
1 WAY IF YOU RAN THIS PROGRAM FROM THE WINDOWS SEARCH BAR
When in the Windows Search Bar (at the bottom-left), then search up your program's filename (for example, "program.py") then right-click it and click the button that says "Run as adminstrator".

Related

Using tkinter's folder choosing dialog box twice

At the start of my code, I let the user choose a file and store its path in a text file. Here is the function for that:
def choose_folder():
root = tk.Tk()
root.withdraw()
global DIR
DIR = filedialog.askdirectory()
global settings_file # Somehow works without this line despite being declared in main
with open(settings_file, "w") as sf:
sf.write(DIR)
Now, I want to let the user change the folder. In the main loop, the user chooses an option each time. Option 4 is to change the directory. Here is my code to change it:
elif user_input == 4:
open(settings_file, "w").close() # Clear the settings file
choose_folder()
The problem is, that for some reason the folder choosing dialog box will not open the second time. I've already checked and the code reaches the choose_folder() function but stops running on filedialog.askdirectory() (the screen flickers for a second which means that something happens but doesn't open the dialog box). What causes this to happen and how can I fix it?
EDIT: Here's the code snippet (I have also slightly changed choose_folder()):
import tkinter as tk
from tkinter import filedialog
import os
#other imports
def prompt_continue() -> bool:
choice = input("Do you want to continue (y/n)? ")[0].lower()
while choice != 'y' and choice != 'n':
choice = input("Invalid Input. ")[0].lower()
return choice == 'y'
def choose_folder():
root = tk.Tk()
root.withdraw()
global DIR
DIR = filedialog.askdirectory()
while not os.path.isdir(DIR):
print("Please choose a folder.")
DIR = filedialog.askdirectory()
while os.listdir(DIR):
print("Please choose an empty folder.")
DIR = filedialog.askdirectory()
with open(settings_file, "w") as sf:
sf.write(DIR)
if __name__ == "__main__":
DIR = ""
settings_file = os.path.expanduser('~/Documents/flagdir.txt')
if os.path.isfile(settings_file): # if settings file exists
if os.stat(settings_file).st_size == 0: # if settings file is empty
choose_folder()
else:
choose_folder()
with open(settings_file, 'r') as file:
DIR = file.read()
user_continue = True
total = 0
while user_continue:
print("Choose option:")
print("[1] Download n random flags")
print("[2] Enter 2 countries and download their mashup")
print("[3] Clear the flags folder")
print("[4] Change the flags folder path")
print("[5] Print the flags folder path")
print("[6] Exit")
user_input = int(input())
while user_input < 1 or user_input > 6:
user_input = int(input("Invalid Input."))
if user_input == 1:
# working code
elif user_input == 2:
# working code
elif user_input == 3:
# working code
elif user_input == 4:
open(settings_file, "w").close()
choose_folder()
elif user_input == 5:
# working code
else:
break
user_continue = prompt_continue()
print("Bye!")

Rewriting CSV file in Python messes up index of rows

This is my entire project at the moment. The original CSV file has 4 rows with a contacts name, email, and phone information. The "list" "view" and "add" functions work fine until I use the "delete" function. In order to delete the desired line, I put the file in a list, deleted the row the user inputs, and rewrote the list into the CSV file with what appears to be good format.
import csv
print("Contact List\n")
print(" list - Display all contacts\n","view - View a contact\n","add - Add a contact\n", "del - Delete a contact\n", "exit - Exit program\n")
def main():
userCom = input("\nCommand: ")
if userCom == "list":
lists()
elif userCom == "view":
count()
elif userCom == "add":
add()
elif userCom == "del":
delete()
elif userCom == "exit":
exitt()
else :
print("Invaild input, try again")
main()
def count():
counter = 1
with open("contacts.csv") as file:
number = file.readline()
for line in file:
counter = counter +1
view(counter)
def lists():
with open("contacts.csv", newline="") as file:
reader = csv.reader(file)
counter = 0
for row in reader:
print(int(counter) + 1, ". ",row[0])
counter = counter+1
main()
def view(count):
num = input("Enter a contact's number to view their information: ")
while num.isdigit() == False or int(num) < 1 or int(num) > int(count):
print("Invaild input, try again")
view(count)
reader = csv.reader(open("contacts.csv"))
lines = list(reader)
print("Name: ",lines[int(num)-1][0],"\nEmail: ",lines[int(num)-1][1],"\nPhone Number: ",lines[int(num)-1][2])
main()
def add() :
name = input("Name: ")
email = input("Email: ")
phone = input("Phone: ")
added = [name,",",email,",",phone]
with open("contacts.csv", "a") as file:
for item in added:
file.write(item)
print(name, " was added.")
file.close()
main()
def delete():
deleted = input("Enter number to delete: ")
reader = csv.reader(open("contacts.csv"))
contacts = list(reader)
del contacts[int(deleted)-1]
with open("contacts.csv", "w") as file:
writer = csv.writer(file)
writer.writerows(contacts)
print("Number ",deleted," was deleted.")`enter code here`
file.close()
main()
main()
When I use delete and try the "list" or "view" features, I get this error message:
Traceback (most recent call last):
File "C:\Users\Test\Desktop\contacts_1.py", line 81, in <module>
main()
File "C:\Users\Test\Desktop\contacts_1.py", line 15, in main
delete()
File "C:\Users\Test\Desktop\contacts_1.py", line 72, in delete
main()
File "C:\Users\Test\Desktop\contacts_1.py", line 9, in main
lists()
File "C:\Users\Test\Desktop\contacts_1.py", line 35, in lists
print(int(counter) + 1, ". ",row[0])
IndexError: list index out of range
Any help helps!
This is because your row doesnt contain any line, so it doesn't even have the 0 index.
Yo must check if the list contain something before accessing any item inside:
if row:
print(row[0])
As I said in comment, your solution is flawed, because it will overflow the stack at some point. You should use an infinite loop instead of calling the main function again and again
def main():
while 1:
userCom = input("\nCommand: ")
if userCom == "list":
lists()
elif userCom == "view":
count()
elif userCom == "add":
add()
elif userCom == "del":
delete()
elif userCom == "exit":
exitt()
else:
print("Invaild input, try again")
# main()

Writing to a file using a users input in Python

I'm trying to write a user input to a word file for my troubleshooting system. However it doesn't write to the file and ends the code. I am trying to make it so that if the user inputs 'no' twice, then it should follow the following code:
if count == 2:
f = open('problems.txt', 'w')
ui = ("What is the problem?")
f.write(ui)
Instead the code ends.
Here's the code:
count = 0
while count != 2:
a = input("Is your phone broken?")
if a == "no":
count = count + 1
if count == 2:
f = open('problems.txt', 'w')
ui = ("What is the problem?")
f.write(ui)
But the code doesn't open the file and write to the file, the program just ends after the user inputs no. I don't understand what I'm doing wrong? Could anyone help me please.
If you are using Python 2.x, use raw_input.
count = 0
while count != 2:
a = raw_input("Is your phone broken?")
print a
if a == "no":
count = count + 1
if count == 2:
f = open('problems.txt', 'w')
ui = ("What is the problem?")
f.write(ui)

Python - Why does my .read() not work on my .txt file? Nothing is outputted to the cmd line

Running
I am running Python version 3.5, from the cmd prompt on Windows 7
What is in the .txt file and what the cmd outputs
What the cmd prompt outputs
What the .txt contains
My current code
"""Opens a file and let\'s you read it and write to it"""
open_pls = open("text.txt", "a+")
#Main function
def read_write():
program_running = True
while program_running == True:
choice = input("Write R for read, write W for write or write X for exit:")
choice = choice.upper()
if choice == "W":
what_write = input("What do you want to write to the end of the file?:")
open_pls.write(what_write)
print("Succesfully written!")
print("Running program again...")
continue
elif choice == "R":
print("This file contains:")
read_pls = open_pls.read()
print(read_pls)
print("Running program again...")
continue
elif choice == "X":
program_running = False
open_pls.close()
else:
print("That was not a valid command!")
print("Running program again...")
continue
run = input("Run the program? (Y/N):")
run = run.upper()
if run == "Y":
read_write()
elif run == "N":
input("Exit program? Press enter:")
else:
input("Exit program? Press enter:")
I think the problem lies somewhere in here
elif choice == "R":
print("This file contains:")
read_pls = open_pls.read()
print(read_pls)
print("Running program again...")
continue
When you open the file with the 'a' append mode, the OS gives you a file with the file position at the end of the file.
You could try to seek back to the start first, but it depends on your OS if that'll actually be permitted:
open_pls.seek(0)
read_pls = open_pls.read()
You may want to open the file in 'r+' mode instead, and seek to the end when writing.
When you open a file with 'a' mode, the file is seeks to the end. To get the contents of the file, you have to seek back to the beginning: open_pls.seek(0).

What is wrong with my defintion of the function prompt_int?

I have been trying to program a maths quiz that both works and is as efficient as possible. Looking over my code I saw I had a lot of integer inputs and that lead to me having the program to ask the question/exit the system if the criteria isn't met, so to help me I thought that it would be useful to create a new function. Here is my attempt:
def prompt_int(prompt=''):
while True:
if status == prompt_int(prompt=''):
val = input(prompt)
if val in (1,2):
return int(val)
return true
elif status != prompt_int(prompt=''):
val = input(prompt)
if val in (1,2,3):
return int(val)
return true
else:
print("Not a valid number, please try again")
However, when I try to implement this function around my code it doesn't work properly as it says that status isn't defined however, when I do define status it goes into a recursion loop. How can I fix this problem?
Here is my original code before i try to implement this function:
import sys
import random
def get_bool_input(prompt=''):
while True:
val = input(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
sys.exit("Not a valid input (yes/no is expected) please try again")
status = input("Are you a teacher or student? Press 1 if you are a student or 2 if you are a teacher")# Im tring to apply the new function here and other places that require integer inputs
if status == "1":
score=0
name=input("What is your name?")
print ("Alright",name,"welcome to your maths quiz."
"Remember to round all answer to 5 decimal places.")
level_of_difficulty = int(input(("What level of difficulty are you working at?\n"
"Press 1 for low, 2 for intermediate "
"or 3 for high\n")))
if level_of_difficulty not in (1,2,3):
sys.exit("That is not a valid level of difficulty, please try again")
if level_of_difficulty == 3:
ops = ['+', '-', '*', '/']
else:
ops = ['+', '-', '*']
for question_num in range(1, 11):
if level_of_difficulty == 1:
number_1 = random.randrange(1, 10)
number_2 = random.randrange(1, 10)
else:
number_1 = random.randrange(1, 20)
number_2 = random.randrange(1, 20)
operation = random.choice(ops)
maths = round(eval(str(number_1) + operation + str(number_2)),5)
print('\nQuestion number: {}'.format(question_num))
print ("The question is",number_1,operation,number_2)
answer = float(input("What is your answer: "))
if answer == maths:
print("Correct")
score = score + 1
else:
print ("Incorrect. The actual answer is",maths)
if score >5:
print("Well done you scored",score,"out of 10")
else:
print("Unfortunately you only scored",score,"out of 10. Better luck next time")
class_number = input("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
while class_number not in ("1","2","3"):
print("That is not a valid class, unfortunately your score cannot be saved, please try again")
class_number = input("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
else:
filename = (class_number + "txt")
with open(filename, 'a') as f:
f.write("\n" + str(name) + " scored " + str(score) + " on difficulty level " + str(level_of_difficulty))
with open(filename, 'a') as f:
f = open(filename, "r")
lines = [line for line in f if line.strip()]
f.close()
lines.sort()
if get_bool_input("Do you wish to view previous results for your class"):
for line in lines:
print (line)
else:
sys.exit("Thanks for taking part in the quiz, your teacher should discuss your score with you later")
if status == "2":
class_number = input("Which classes scores would you like to see? Press 1 for class 1, 2 for class 2 or 3 for class 3")
if class_number not in (1,2,3):
sys.exit("That is not a valid class")
filename = (class_number + "txt")
with open(filename, 'a') as f:
f = open(filename, "r")
lines = [line for line in f if line.strip()]
f.close()
lines.sort()
for line in lines:
print (line)
Well, just a part:
def prompt_int(prompt=""):
while True:
val = input(prompt)
if val in ("1", "2"):
return int(val), True
Will ask again and again. And return when the user enter "1" or "2"!
But better: "if val in "12":
def prompt_int(prompt=""):
while True:
val = input(prompt)
if val.isdigit():
return int(val)
Hi if you dont want to have valid values send to your you could change your code as the function above.
But you could also change it to do the system exits:
def prompt_int(prompt="", authorized=()):
while True:
val = raw_input(prompt)
if val.isdigit():
if int(val) in authorized:
return int(val)
else:
sys.exit("Bla bla bla too bad")
def prompt_int(prompt=''):
while True:
if status == prompt_int(prompt=''):
This line will look for the name "status" in the global namespace (module's namespace), and raise a NameError if there's no global variable named 'status'.
If there's one, it will then recursively calls prompt_int without any possible termination, resulting theoretically in an endless recursion, but practically (in CPython at least) in a RuntimeError when it will hit the maximum recursion depth.
There are also quite a few other things that won't work as you expect:
val = input(prompt)
if val in (1,2):
In Python 3.x, val will be a string, so it will never compare equal to an int. In Python 2.x, input() is a shortcut for eval(raw_input()), which might return an int, but is also a huge security flaw since it unconditionnally execute untrusted code.
return int(val)
return true
The second return statement will never be executed, obviously, since the function will exit at the first one.
A simpler implementation might look like this:
# rebinds raw_input to input for python < 3
import sys
if sys.version_info.major < 3:
input = raw_input
def prompt_int(prompt='', choices=None):
while True:
val = input(prompt)
try:
val = int(val)
if choices and val not in choices:
raise ValueError("{} is not in {}".format(val, choices))
return val
except (TypeError, ValueError) as e:
print(
"Not a valid number ({}), please try again".format(e)
)
While we're at it, there's room for improvement in other parts of your code. Let's start with this:
def get_bool_input(prompt=''):
while True:
val = input(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
sys.exit("Not a valid input (yes/no is expected) please try again")
First point: your naming is not consistent. If your other function is named prompt_int, this one should be named prompt_bool. Also, you have one function (prompt_int) looping forever and the other one exiting the whole program on invalid input, which is another inconsistency. If you want to allow the user to exit on any prompt, provide an explicit option for it, ie:
def prompt_bool(prompt, quit='Q'):
prompt += " (hit '{}' to exit) : ".format(quit)
while True:
val = input(prompt).strip().upper()
if val == quit:
sys.exit("Goodbye")
elif val == 'yes':
return True
elif val == 'no':
return False
else:
print "Invalid input '{}', please try again".format(val)
Of course you then want to provide the same option in prompt_int(), which leads to a more generic function:
def get_input_or_quit(prompt, quit="Q"):
prompt += " (hit '{}' to exit) : ".format(quit)
val = input(prompt).strip()
if val.upper() == quit:
sys.exit("Goodbye")
return val
def prompt_bool(prompt):
while True:
val = get_input_or_quit(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
print "Invalid input '{}', please try again".format(val)
And of course you also replace the call to input by a call to get_input_or_quit in prompt_int.
We could go on for long - splitting all your code in distinct, self-contained function, writing a "main()" function to drive them (instead of having the "main" part at the top level), and obviously using the operator module instead of eval().

Categories

Resources