Try/Except Block causing ValueError - python

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

Related

Extract IP addresses from text file without using REGEX

I am trying to extract IPv4 addresses from a text file and save them as a list to a new file, however, I can not use regex to parse the file, Instead, I have check the characters individually. Not really sure where to start with that, everything I find seems to have import re as the first line.
So far this is what I have,
#Opens and prints wireShark txt file
fileObject = open("wireShark.txt", "r")
data = fileObject.read()
print(data)
#Save IP adresses to new file
with open('wireShark.txt') as fin, open('IPAdressess.txt', 'wt') as fout:
list(fout.write(line) for line in fin if line.rstrip())
#Opens and prints IPAdressess txt file
fileObject = open("IPAdressess.txt", "r")
data = fileObject.read()
print(data)
#Close Files
fin.close()
fout.close()
So I open the file, and I have created the file that I will put the extracted IP's in, I just don't know ow to pull them without using REGEX.
Thanks for the help.
Here is a possible solution.
The function find_first_digit, position the index at the next digit in the text if any and return True. Else return False
The functions get_dot and get_num read a number/dot and, lets the index at the position just after the number/dot and return the number/dot as str. If one of those functions fails to get the number/dot raise an MissMatch exception.
In the main loop, find a digit, save the index and then try to get an ip.
If sucess, write it to output file.
If any of the called functions raises a MissMatch exception, set the current index to the saved index plus one and start over.
class MissMatch(Exception):pass
INPUT_FILE_NAME = 'text'
OUTPUT_FILE_NAME = 'ip_list'
def find_first_digit():
while True:
c = input_file.read(1)
if not c: # EOF found!
return False
elif c.isdigit():
input_file.seek(input_file.tell() - 1)
return True
def get_num():
num = input_file.read(1) # 1st digit
if not num.isdigit():
raise MissMatch
if num != '0':
for i in range(2): # 2nd 3th digits
c = input_file.read(1)
if c.isdigit():
num += c
else:
input_file.seek(input_file.tell() - 1)
break
return num
def get_dot():
if input_file.read(1) == '.':
return '.'
else:
raise MissMatch
with open(INPUT_FILE_NAME) as input_file, open(OUTPUT_FILE_NAME, 'w') as output_file:
while True:
ip = ''
if not find_first_digit():
break
saved_position = input_file.tell()
try:
ip = get_num() + get_dot() \
+ get_num() + get_dot() \
+ get_num() + get_dot() \
+ get_num()
except MissMatch:
input_file.seek(saved_position + 1)
else:
output_file.write(ip + '\n')

Python 3: search text file with user input?

there is a part of my program where I would like to pass a sorted list of names from a text file to a function which asks the user to enter a name and then indicate whether the name entered is found in the list or not. If the name is found, its position (i.e. index) is also printed.
The file is just 30 names, but when the second function is executed, it will show this after I input which name I would like to search for:
name not found.
name not found.
name found
name not found.
name not found.
...etc for all 30 names.
Here's the code:
def main():
infile = open('names.txt', 'r')
line = infile.readline()
while line !='':
line = line.rstrip('\n')
print(line)
line = infile.readline()
print('\nHere are the names sorted:\n')
infile = open("names.txt", 'r')
names = infile.readlines()
names.sort()
for line in names:
line = line.rstrip('\n')
print(line)
line = infile.readline()
search_file(line) # I don't this this is the correct way to
# pass the sorted list of names?
def search_file(line):
search = open('names.txt', 'r')
user_search = input('\nSearch for a name(Last, First): ')
#item_index = line.index(search)
print()
with open('names.txt', 'r') as f:
for line in f:
if user_search in line:
print('name found')#, item_index)
else:
print('name not found.')
updated code here:
this time it always displays "not found"
def search_file(line):
user_search = input('\nSearch for a name(Last, First): ')
print()
try:
item_index = line.index(user_search)
print(user_search, 'found at index', item_index)
except ValueError:
print('not found.')
Well first you would only want to open the file you are searching one time. You could load all lines in the file into a list with .readlines() this function returns a string in a list for each line. Then you can search for the user string with in each line with
for l in lines:
if (l.find(userstring)>-1):
foundvar=True

inputting a words.txt file python 3

I am stuck why the words.txt is not showing the full grid, below is the tasks i must carry out:
write code to prompt the user for a filename, and attempt to open the file whose name is supplied. If the file cannot be opened the user should be asked to supply another filename; this should continue until a file has been successfully opened.
The file will contain on each line a row from the words grid. Write code to read, in turn, each line of the file, remove the newline character and append the resulting string to a list of strings.After the input is complete the grid should be displayed on the screen.
Below is the code i have carried out so far, any help would be appreciated:
file = input("Enter a filename: ")
try:
a = open(file)
with open(file) as a:
x = [line.strip() for line in a]
print (a)
except IOError as e:
print ("File Does Not Exist")
Note: Always avoid using variable names like file, list as they are built in python types
while True:
filename = raw_input(' filename: ')
try:
lines = [line.strip() for line in open(filename)]
print lines
break
except IOError as e:
print 'No file found'
continue
The below implementation should work:
# loop
while(True):
# don't use name 'file', it's a data type
the_file = raw_input("Enter a filename: ")
try:
with open(the_file) as a:
x = [line.strip() for line in a]
# I think you meant to print x, not a
print(x)
break
except IOError as e:
print("File Does Not Exist")
You need a while loop?
while True:
file = input("Enter a filename: ")
try:
a = open(file)
with open(file) as a:
x = [line.strip() for line in a]
print (a)
break
except IOError:
pass
This will keep asking untill a valid file is provided.

Using Subprocess module to capture file names?

I'm trying to read in a list of account numbers, then have my program do a search in the appropriate directory for each account number. I want to capture the information from this search, to then split out the file name, date, and time as the output from my program. Currently I'm receiving this error: TypeError: bufsize must be an integer
Here is my code:
def app_files(level):
piv_list_file = raw_input(r"Please enter the full path of the file containing the Pivot ID's you would like to check: ")
piv_id_list = []
proc_out_list = []
input_dir = ''
try:
with open(piv_list_file, 'rbU') as infile:
for line in infile:
line = line.rstrip('\r\n')
piv_id_list.append(line)
except IOError as e:
print 'Unable to open the account number file: %s' % e.strerror
if level == 'p':
input_dir = '[redacted]'
else:
input_dir = '[redacted]'
subprocess.call('cd', input_dir)
for i, e in enumerate(piv_id_list):
proc_out = subprocess.check_output('ls', '-lh', '*CSV*APP*{0}.zip'.format(e))
proc_out_list.append(proc_out)
print(proc_out)
Your subprocess.check_output() function call is wrong. You should provide the complete command as a list (as the first argument). Example -
subprocess.check_output(['ls', '-lh', '*CSV*APP*{0}.zip'.format(e)])
Similar issue with subprocess.call in your code .

Pickling data in python

I have been staring at this code for a day and a half now and google is not helping. It looks fine to me but it keeps throwing out errors.
The program runs through a quiz and collects a score at the end as shown here:
print("That was the last question!")
print("Your final score is", score)
name = input('What is the players name? ')
highsc = highscore(score, name)
I Know that score works but when i enter the players name it then tries to run my highscore definition:
def highscore(score, name):
entry = (score, name)
hs_data = open('tops.dat', 'rb')
highsc = pickle.load(hs_data)
hs_data.close()
hs_data = open('tops.dat', 'ab')
highsc.append(entry)
highsc.sort(reverse=True)
highsc = highsc[:5]
pickle.dump(highsc, hs_data)
hs_data.close()
return highsc
But the i get the same error each time which is:-
File "C:\Users\Desktop\py3e_source\py3e_source\trivia_challenge.py", line 55, in highscore
highsc = pickle.load(hs_data)
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
EOFError
Please help.
You are opening an empty file, pickle is reaching the end before it finds anything to unpickle. You can fix this by catching the EOFError and setting a default value when caught.
Something like this should work:
with open('tops.dat', 'rb') as hs_data:
try:
highsc = pickle.load(hs_data)
except EOFError:
highsc = []
The error says EOFError, which means you have reached the end of the file and pickle was not in a normal state. Is the file filled before using that function?
Also, opening the file in append mode to write the new data doesn't seem like a good idea. load reads the entire file, not discarding characters after the first object, but once you have added a new highscore, you have two highscore objects in the file, which also leads to an error.

Categories

Resources