I have a simple function that I use to read the contents of a text file into a Python variable. I use it to import SQL queries. The function takes a parameter that is the path and name of the text file and allows several attempts to get the name right, allowing for typos or mis-spellings. By default, this parameter is set to None. If the file can't be found, the function prints an error message and presents an input() box to allow a new path and filename to be entered. The function then either returns the string (representing the SQL query) or returns None if the file can't be found.
The function is:
def readQueryFromFile(queryPathAndFileName = None):
maxAttempts = 3
for i in range(maxAttempts):
if (queryPathAndFileName is None) or (i > 0):
queryPathAndFileName = input("Enter path and filename for text file contains SQL query: ")
try:
tempFileObject = open(queryPathAndFileName)
tempQuery = tempFileObject.read()
tempFileObject.close()
break
except FileNotFoundError as e:
print("\nA FileNotFoundError occurred.\nError number {0}: {1}. File named \'{2}\' does not exist at that location.".format(e.args[0],e.args[1],queryPathAndFileName))
if i < (maxAttempts-1):
print('\nPlease re-enter path and filename details.\n') # Only say 'Please try again' if not last attempt.
else:
# If query file can't be found then set tempQuery to None
print('\nFailed to find file containing query after {0} attempts.\n'.format(i+1))
tempQuery = None
return tempQuery
The function could be called in a Jupyter notebook cell using:
myQuery = readQueryFromFile(queryPathAndFileName = '/geosgnasoeg/asgogeso.sges')
Clearly, the path and file name is nonsensical and the function presents an error message and a prompt to enter the path and file name again. However, the error messages appear after the input box is displayed as follows:
Enter path and filename for text file contains SQL query: |________|
A FileNotFoundError occurred.
Error number 2: No such file or directory. File named '/geosgnasoeg/asgogeso.sges' does not exist at that location.
Please re-enter path and filename details.
Having the messages appear out of sequence can be confusing. Interestingly, if a second incorrect path and file name is entered, the output realigns itself correctly.
I'm using a Mac running El Capitan and this issues occurs in both Safari and Firefox.
Is there a way to force the output displayed in Jupyter notebook to appear in the correct (i.e. sequential) order?
Related
I was creating a note taking program, using the user voice command. When the file already exists, I want to show an error. It runs smoothly when the file name is different though.
When the file already exists, I have coded to open in the writing mode. It would erase the earlier file, and write new instead of adding in the append mode.
elif 'note' in query:
try:
speak(" Okay master. what's the file name")
b= takecommand()
f = open(f"{b}.txt","w")
speak("Okay master. tell me what to note down")
a= takecommand()
f.write(f"{a}\n")
f.close()
except Exception as e:
speak("file name already exist")
Can you help me with troubleshooting the script? Like how could I first make it thrown an error when the filename is same?
You'd want to check if the file exists after they input it, which can be done using "os.path.exists" as also suggested by Tim Roberts. Here's code that should work for you:
elif 'note' in query:
try:
Looper = True # Added a loop so it can repeatedly ask the user until they give a valid answer.
speak(" Okay master. what's the file name") # Put here instead of in the loop so it will repeat once since the else condition already asks for a new file name aswell.
while Looper == True:
b = takecommand()
if os.path.exists(f"{b}.txt"):
f = open(f"{b}.txt","w")
speak("Okay master. tell me what to note down")
a= takecommand()
f.write(f"{a}\n")
Looper = False # So the loop won't repeat again (regardless of the below line).
f.close()
else:
speak("That file already exists. Give me a new file name.")
except Exception as e:
speak("Hm, an error occured. Try again later.")
I also added in a while loop for you, so that way if the user gives a file name that already exists, it will keep asking until they give a valid file name.
Ensure you have OS imported for the code to work by adding the following to the top of your code:
import os
Use mode 'x'
x' create a new file and open it for writing. The 'x' mode implies 'w'
and raises an FileExistsError if the file already exists.
try:
# ...
f = open(f"{b}.txt","x")
# ...
except FileExistsError:
speak("file name already exist")
Or mode 'a' to append the strings to existing file.
'a' open for writing, appending to the end of the file if it exists
So I'm trying to capture the output from drush via python. The main problem is that when drush fails in a task (e.g. unable to make a select) it gives an output in non standard format. I want to control this in order to put in on a loop and then if there's an error, continue with the next site.
This is output of the drush:
client_global_hostkeys_private_confirm: server gave bad signature for RSA key 0
In SqlCommands.php line 200:
Query failed. Rerun with --debug to see any error message. ERROR 1146 (42S02) at line 1: Table 'main.users_field_data' doesn't exist
This is the code that i'm trying to run:
import os
import subprocess
import json
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
getuids = os.popen('drush -- sql:query "SELECT GROUP_CONCAT(uid) FROM (SELECT DISTINCT uid FROM users_field_data LIMIT 5000) AS ids"')
outputuids=getuids.read()
valuein = "200"
if valuein in outputuids:
print("Error found")
else:
print("No error")
As you might already discover, the valuein variable is the text that I want to search, but no matter how, I always get no error. BUT if I make a variable and remove the carriage return from this output:
client_global_hostkeys_private_confirm: server gave bad signature for RSA key 0
In SqlCommands.php line 200:
Query failed. Rerun with --debug to see any error message. ERROR 1146 (42S02) at line 1: Table 'main.users_field_data' doesn't exist
The if condition finds the 200 on the text and prints Error Found.
Do you know how to achieve this? I tried replacing it but no result at all.
Any help would be appreciated.
This question already has answers here:
Is it a good practice to use try-except-else in Python?
(11 answers)
Closed 2 years ago.
Hello I am trying to create a program that reads two txt.files and displays them for the user on the console.
I want to write an exception for the case that atleast one of the files is not in the same directory.
The code I display now works fine for the case that both files are in the directory.
However when i try to test my exception i get Traceback Error with NameError ="list_of_cats" not found and then my custom message is displayed.
How should i write the program so that just my custom_message is displayed.
filename_1 = "cats.txt"
filename_2 = "dogs.txt"
try:
with open(filename_1) as file_object_1, open(filename_2) as file_object_2:
list_of_cats = file_object_1.read()
list_of_dogs = file_object_2.read()
except FileNotFoundError:
print(f"Sorry one of the files {filename_2} is not in this directory")
print(list_of_cats)
print(list_of_dogs)
That's the error message:
NameError: name 'list_of_cats' is not defined
Sorry one of the files dogs.txt is not in this directory
Process finished with exit code 1
The error occurs because when printing the variables list_of_cats and list_of_dogs are not defined while printing them. To fix this you can use the following code:
filename_1 = "cats.txt"
filename_2 = "dogs.txt"
try:
with open(filename_1) as file_object_1, open(filename_2) as file_object_2:
list_of_cats = file_object_1.read()
list_of_dogs = file_object_2.read()
except FileNotFoundError:
print(f"Sorry one of the files {filename_2} is not in this directory")
else:
print(list_of_cats)
print(list_of_dogs)
Using cx_Oracle, I am trying to use a Python script to execute a sql command, using the bind variables 'plat' and 'tick'. When trying to execute this command, it gives me the error "ORA-24373: invalid length specified for statement".
To debug, I made a SQL call through Oracle (not Python) using the same arguments as my script (plat=1234567, tick='ABCDE'), and it ran as expected. I tried passing the parameters as both a dict and individual named variables, but both times I got the same error.
I tried changing the values to be lower ('1' and 'A'), but even that is an 'invalid length'.
updateRecords.py
import os
import cx_Oracle
# For security reasons I cannot show my 'create_connection()' function,
# but suffice to say I have tested it and it works as desired.
...
#Setup:
WORKING_PATH = os.path.dirname(os.path.abspath(__file__))
SQL_PATH = os.path.join(WORKING_PATH, 'sql')
cnnSB = create_connection()
cnnSB_cursor = cnnSB.cursor()
...
fetchComp = open(os.path.join(SQL_PATH, 'fetchRecentEntry.sql'), 'r')
for x in range(0, 5):
cnnSB_cursor.execute(fetchComp.read(), {"plat":'A', "tick":1}) # ERROR LINE
fetchRecentEntry.sql
select *
from MFS_PCIINCEXTFUNDBYPLAT
where PLATFORM = :plat
and TICKER = :tick
and STARTDATE = (select max(STARTDATE) from MFS_PCIINCEXTFUNDBYPLAT
where PLATFORM = :plat
and TICKER = :tick)
The above snippet results in the following error message:
File "updateRecords.py", line 297, in main
cnnSB_cursor.execute(fetchComp.read(), plat='A', tick=1)
cx_Oracle.DatabaseError: ORA-24373: invalid length specified for statement
Other things I have checked:
-My fetchComp.read() DOES return the desired code
-Passing in variables as a dict object does NOT change the error message
I found a solution:
The issue comes from the .read() being called inside of a loop. As a result, it would read the file correctly the first time, but on subsequent loops it would only read the null/EOF.
To fix, all I had to do was set the sql.read() to a variable before the loop, and use that variable instead of calling .read() with each loop.
Example:
sql = fetchComp.read()
for index, testRow in testDF.iterrows():
cnnSB_cursor.execute(sql, tick=testRow[1], plat=testRow[0])
compDF = pd.DataFrame(cnnSB_cursor.fetchall())
I have attempted to get this code working in Python 3.5.1 but I am having problems with it not writing the hashed password and username to the file specified. Is there something I'm doing wrong?
import sys
import hashlib
import getpass
def main():
print ('\nUser & Password Storage Program v.01\n')
if input('The file will be modieifed if it exists.\nDo you wish to continue (Y/N): ') not in ('Y','y'):
sys.exit('\nChanges were not recorded\n')
user_name = input(str('Please Enter a User Name: '))
pwdinput = input("Now enter a password:").encode('utf-8')
password = hashlib.sha224(pwdinput).hexdigest()
try:
f = open(passfile.txt,'a+')
f.write(user_name + '\n')
f.write(password + '\n')
f.close()
except:
sys.exit('There was a problem writing to the file!')
print ('\nPassword safely stored in passfile.txt.\n')
main()
You don't have a variable called passfile.txt, and that is making the open call fail. It would be correctly opening the file if you surrounded it in quotes, like 'passfile.txt'
The reason this syntax error isn't obvious is because you have a catch all, and your program will just print 'There was a problem writing to the file!' instead.
Rather than catch all exceptions using except:, use the syntax except IOError:, as that will be thrown whenever there is an actual error in writing to the file.
The error is that your open() function is taking an object as a parameter, but you probably meant to use it as a string.
Also, you generally should use a with block when opening files.
try:
with open("passfile.txt",'a+') as f:
f.write("{}\n{}\n".format(user_name, password))
except Exception as e: # Use other exceptions for more accurate results
sys.exit('There was a problem writing to the file!\nError: {}'.format(str(e)))