I would like to know how I can throw exceptions / errors to say that a parameter is null or its not in the .txt file that works as a dictionnary.
The dictionnary it's like that:
"""rule:parameter:value"""
aa:alfa:1
bba:beta:15
I got this for the moment:
def get(rule_name,parameter_name):
try:
with open("parameters.txt", "r") as infile:
for line in infile:
if line.startswith(rule_name.lower()) and line.split(":")[1] == parameter_name.lower():
return line.split(":")[2]
except Value:
print "Error"
if __name__=="__main__":
print(get("aa","alfa")) #return the value associated to the rule and the parameter
Just raise a value error
raise ValueError("you parameter is null or in wrong format")
Related
I've been working on a function for hours and I just can't see the solution since this is my first time working with opening .txt files, etc.
My function will open a .txt file of 50 names, with the first line (a header) being NAMES. And then it will create a list of those names. I need to test the function so if the line 'NAMES' is not in the txt file it will raise an exception. I have been working on the 'NAMES' part for longer than I care to admit and can't see what I am doing wrong. Here is my code:
EOF = ''
def load_names(fName):
global line, names
print(end = f"Opening file {fName} ...")
try:
f = open(fName, 'r')
except:
raise Exception(f"OOPS! File {fName} not found")
print(end = "reading...")
line = f.readline().strip()
while line.strip() != 'NAMES':
line = f.readline().strip()
while line != EOF and line.strip() != 'NAMES':
raise Exception("!! Oops! Missing line 'NAMES' !!" )
names = [] # To collect names from file
line = f.readline().strip() # Read in first name
while line != EOF:
if line =='\n':
print("!! Oops! Blank line not allowed !!")
names.append(line.strip())
line = f.readline()
f.close()
print(end = "closed.\n")
return names
The 'blank line not allowed' works when tested, but the way I have this code written now, even If I open a file that does have the 'NAMES' line in it, it still gives the error "Exception("!! Oops! Missing line 'NAMES' !!" )". I'm not sure how to do it, basically.
The files i am testing this with look like:
With NAMES -
NAMES
Mike
James
Anna
Without NAMES -
Mike
James
Anna
Your function seems much too complex, and the exception handling is wrong. For example, it will replace a "permission denied" exception with a generic Exception with an incorrect message saying the file wasn't found, even though that was not the reason for the error.
Instead, probably
avoid the use of global variables;
don't trap errors you can't meaningfully handle;
don't strip() more than once - save the stripped value so you can use it again;
simply read one line at a time, and check that it passes all your criteria.
def load_names(fName):
with open(fName, 'r') as f:
seen_names = False
names = []
for line in f:
line = line.strip()
if line == 'NAMES':
seen_names = True
elif line == '':
raise Exception("!! Oops! Blank line not allowed !!")
else:
names.append(line)
if not seen_names:
raise Exception("!! Oops! Missing line 'NAMES' !!" )
return names
If you actually want NAMES to be the first line in the file, it's not hard to change the code to require that instead. Maybe then it does make sense to read the first line separately before the loop.
def load_names(fName):
with open(fName, 'r') as f:
seen_names = False
names = []
for line in f:
line = line.strip()
if not seen_names:
if line == 'NAMES':
seen_names = True
else:
raise Exception("!! Oops! Missing line 'NAMES' !!" )
elif line == '':
raise Exception("!! Oops! Blank line not allowed !!")
else:
names.append(line)
return names
Concretely, the bug in your original attempt is that the code continues to read lines until it gets one which doesn't contain NAMES, and then complains.
for my coding assignment I am to create a file that will read a csv file, offer different attributes to do analysis over (determined by the column values. I had this code working perfectly, but after I added my first try/except block I started getting the following error:
Traceback (most recent call last): File
"/Users/annerussell/Dropbox/Infotec 1040/module 8/csval.py", line 49,
in
row1=next(reader, 'end')[0:] ValueError: I/O operation on closed file.
Here is a link to a file you can test it with if desired. As you probably guessed this is a class assignment, and I am working on learning python for gradschool anyway so any suggestions are greatly appreciated.
import csv
print('Welcome to CSV Analytics!')
# Get file name and open the file
while True:
try:
file_name = input('Enter the name of the file you would like to process: ')
with open(file_name, "rt") as infile:
# Select the attribute to be analyzed
reader=csv.reader(infile)
headers=next(reader)[0:]
max=len(headers)
except FileNotFoundError:
print('The file you entered could not be found. Please' \
+ ' enter a valid file name, ending in .csv.')
continue
except IOError:
print('The file you selected could not be opened. Please ' \
+ 'enter a valid file name, ending in .csv.')
continue
except:
print('There was an error opening or reading your file. Please ' \
+ 'enter a valid file name, ending in .csv.')
continue
else:
print ('The attributes available to analyse are:')
for col in range(1, max):
print(col, headers[col])
while True:
try:
choice=int(input('Please select the number of the attribute you would like to analyze '))
except:
print('Please enter the numeric value for the selection you choose.')
continue
else:
# Build a dictionary with the requested data
dict1= {}
numrows=-1
row1=[]
largest_value=0
key_of_largest_value=0
while row1 != 'end':
row1=next(reader, 'end')[0:]
if row1 !='end':
numrows += 1
key=row1[0]
value=float(row1[choice])
dict1[key] = value
if value>largest_value:
largest_value=value
key_of_largest_value=key
# print('dictionary entry ( key, value)', key, value)
print('Largest ', headers[choice], ' value is ', key_of_largest_value, ' with ', largest_value)
In short: After with block ends, file is closed. You can't read from it, reader will fail.
Probably you didn't notice there is one-space indent for with, replace it with common indent so it will be more clear.
Seach for python context manager for more deep understanding.
Suggestion here is to factor out all logic from try else block to process_file function, and call it inside with statement.
with open(file_name, "rt") as infile:
# Select the attribute to be analyzed
reader=csv.reader(infile)
headers=next(reader)[0:]
max=len(headers)
process_file(reader, headers, max) # <-- like that
using with you need to move second condition to it block or
replace
with open(file_name, "rt") as infile:
with
isProcessing = True
while isProcessing:
....
infile = open(file_name, "rt")
...
#end of line
#print('Largest ',....
infile.close()
# end the loop
isProcessing = False
I am making a simple script that counts some values from a csv file generated from google forms.
The script is as follows:
import csv
import os.path
fileName=None
if __name__=="__main__":
try:
fileName=argv[1]
isFile(fileName)
pass
except Exception as e:
print("You must provide a valid filename as parameter")
raise
def isFile(fileName):
if(not os.path.isfile(fileName)):
raise ValueError("You must provide a valid filename as parameter")
print fileName
def readCsvAndCountPercentPerFormItemFromGoogleForms(fileName):
times={}
totalRows=0
with open(fileName,'r') as csvfile:
csvReader=csv.reader(csvfile);
for row in csvreader:
value=row[1]
if(value in times.values()):
times[value]+=1
else:
times[value]=1
totalRows+=1
return calculateDictionaryAsPercent(times,totalRows)
def calculateDictionaryAsPercent(times,totalRows):
if(totalRows==0):
raise ValueError("The file does not contain any rows")
for key,val in times.items():
times[key]=(val/totalRows)*100
return times
finalTimes=readCsvAndCountPercentPerFormItemFromGoogleForms(fileName)
print finalTimes
But I get the following error:
Traceback (most recent call last):
File "csv.py", line 1, in <module>
import csv
File "/home/pcmagas/Kwdikas/python/csv.py", line 54, in <module>
finalTimes=readCsvAndCountPercentPerFormItemFromGoogleForms(fileName)
File "/home/pcmagas/Kwdikas/python/csv.py", line 26, in readCsvAndCountPercentPerFormItemFromGoogleForms
with open(fileName,'r') as csvfile:
TypeError: coercing to Unicode: need string or buffer, NoneType found
The problem is that for some reason the variable fileName does not change value in:
if __name__=="__main__":
try:
fileName=argv[1]
isFile(fileName)
pass
except Exception as e:
print("You must provide a valid filename as parameter")
raise
The following piece of code was base ton the first answer found on Detect and print if no command line argument is provided
So can you offer me a solution because I do not write python too often, therefore I did the following script in order to learn it better.
Edit 1
The code has been reformated to this:
import csv
from sys import argv
import os.path
def isFile(fileName):
if(not os.path.isfile(fileName)):
raise ValueError("You must provide a valid filename as parameter")
def readCsvAndCountPercentPerFormItemFromGoogleForms(fileName):
times={}
totalRows=0
with open(fileName,'r') as csvfile:
csvReader=csv.reader(csvfile);
for row in csvreader:
value=row[1]
if(value in times.values()):
times[value]+=1
else:
times[value]=1
totalRows+=1
return calculateDictionaryAsPercent(times,totalRows)
def calculateDictionaryAsPercent(times,totalRows):
if(totalRows==0):
raise ValueError("The file does not contain any rows")
for key,val in times.items():
times[key]=(val/totalRows)*100
return times
fileName=None
if __name__=="__main__":
try:
fileName=argv[1]
print("Filename: ",fileName)
isFile(fileName)
pass
except Exception as e:
print("You must provide a valid filename as parameter")
raise
print("Filename: ",fileName)
finalTimes=readCsvAndCountPercentPerFormItemFromGoogleForms(fileName)
print finalTimes
Still the same error.
In the end as mentioned the script should be this one:
import csv
from sys import argv
import os.path
def readCsvAndCountPercentPerFormItemFromGoogleForms(fileName):
times={}
totalRows=0
with open(fileName,'r') as csvfile:
csvReader=csv.reader(csvfile);
for row in csvReader:
value=row[1]
if(value in times.values()):
times[value]+=1
else:
times[value]=1
totalRows+=1
return calculateDictionaryAsPercent(times,totalRows)
def calculateDictionaryAsPercent(times,totalRows):
if(totalRows==0):
raise ValueError("The file does not contain any rows")
for key,val in times.items():
times[key]=(val/totalRows)*100
return times
def isFile(fileName):
if(not os.path.isfile(fileName)):
raise ValueError("You must provide a valid filename as parameter")
fileName=None
if __name__=="__main__":
try:
fileName=argv[1]
isFile(fileName)
pass
except Exception as e:
print("You must provide a valid filename as parameter")
raise
finalTimes=readCsvAndCountPercentPerFormItemFromGoogleForms(fileName)
print finalTimes
The code that uses the expression in question:
def read_file(self,file_name):
try:
with open(file_name,'r') as file:
data=file.read()
return data.split()
except IOError as e:
print("Could not read file:{0.filename}".format(e))
sys.exit()
How does this work? What is meaning of {0.filename}.format(e)? Why do we use {0.filename} and not {1.filename}?
This essentially means takes the positional argument at position 0 (in format(e), e is the zero position arg) and grab the filename attribute defined on it:
print("No such file: {0.filename}".format(e))
Is similar to:
print("No such file: {0}".format(e.filename))
It isn't 1.filename because format hasn't been called with an argument at position 1, another example might help you out even more:
print("{0}{1.filename}".format("No such File: ", e))
Here {0} will grab "No such File: " and {1.filename} will grab e.filename and add it to the resulting string.
This produces and error:
ValueError: Expecting value: line 1 column 1 (char 0)
Here is my code:
...
print("Your phonebook contains the following entries:")
for name, number in phoneBook.items():
print("%s - %s" % (name, number))
while not created:
if not os.path.isfile('phonebook.json'):
with open('phonebook.json', 'wb') as f:
try:
f.write('{}')
except TypeError:
{}
created = True
print('New phonebook created!')
else:
print('Phonebook found!')
created = True
with open('phonebook.json', 'r') as f:
try:
phoneBook_Ori = json.load(f)
phoneBook_Upd = dict(phoneBook_Ori.items() + phoneBook.items())
phoneBook_Ori.write(phoneBook_Upd)
except EOFError:
{}
if EOFError:
with open('phonebook.json', 'w') as f:
json.dump(phoneBook, f)
else:
with open('phonebook.json', 'w') as f:
json.dump(phoneBook_Ori, f)
Has anyone got an idea of how to fix this?
I have also previously asked a question on this code here
I copy pasted your code in the python 2.x interpreter.
I received a ValueError regarding the phonebook.json file. I created a dummy file with:
{'sean':'310'}
My error reads:
ValueError: Expecting property name: line 1 column 2
This was the only way I was able to receive a ValueError.
Therefore, I believe your issue lies in the way the json is written in phonebook.json. Can you post its contents or a subset?
Also, using phoneBook_Ori.write() seems very questionable, as the json module has no method called write(), and the return on json.load(), if used on json objects, is a dictionary, which also cannot write(). You would probably want to use json.dump().
read more at:
https://docs.python.org/2/library/json.html
Anyway, I hope I was helpful.
I was getting this error whilst using json.load(var) with var containing an empty JSON response from a REST API call.
In your case, the JSON response (phonebook.json) must have records. This will fix the error.