prevent the closure of command Prompt with Python when an "exception" occurs - python

I have a script in Python 2.7 converted in executable with py2exe. The INPUT data is a text file where the delimiter need to be valid following this function:
# Check if delimeter is valid
def get_parse(filename, delimiters=['\t', ',', ' ', ':', ';', '-']):
with open(filename) as f:
f.next()
secondline = f.next()
for delimiter in delimiters:
if len(secondline.rstrip().split(delimiter)) >= 3:
return delimiter
raise Exception("couldn't find a delimiter that worked!")
When the delimiter is not valid (ex: a dot) i am looking for two solution in a Python elegant way:
Until the right INPUT data is not load you can not pass to OUTFILE
or
The script break the code, show the error, but the windows (when is a
*.exe) doesn't close immediately leaving the user without an explanation
INPUT = raw_input("Input (*.txt): ")
while not os.path.exists(INPUT):
print IOError("No such file or directory: %s" % INPUT)
INPUT = raw_input("Input (*.txt): ")
try:
parse = get_parse(INPUT)
except Exception:
print ValueError("Delimiter type not valid")
break
OUTPUT = raw_input("Output (*.txt): ")
with this solution (break) the Window of my *.exe file close leaving the user without an explanation

You are not really searching for a delimiter, just a character in a string. You should really use the CSV module for this.
from __future__ import print_function
delimiters=['\t', ',', ' ', ':', ';', '-']
def getfile():
fname =""
while fname is "":
fname = str.lower(raw_input("Input(*.txt): "))
while fname.endswith(".txt") is not True:
print ("File must be .txt")
fname = str.lower(raw_input("Input(*.txt): "))
if fname.endswith(".txt"):
try:
with open(fname,'rb') as f:
parsed = False
while not parsed:
data = f.readline()
for d in delimiters:
if d in data:
print ("Delimiter: {0} found".format(d))
parsed = True
# do your additional stuff here
else:
print ("Unable to find delimiter {0}".format(d))
parsed = True
except IOError as e:
print( "Error: ", e)
getfile()

You can hook the exception handler for uncaught exceptions using sys.excepthook, and have it call raw_input() (or input() in 3.x) as per this answer.
For a quick example:
import sys
def wait_on_uncaught_exception(type, value, traceback):
print 'My Error Information'
print 'Type:', type
print 'Value:', value
print 'Traceback:', traceback
raw_input("Press any key to exit...")
sys.excepthook=wait_on_uncaught_exception
Just modify that to have whatever output or whatever you want (I suggest looking into the traceback module).
But if you want it more specific to your code, then just put raw_input("Press any key to exit...") in the solution you already have, and it should be fine. The above should provide a more general solution.

Related

Python program to match string based on user input

I need to write a python program that allows user to enter input
like Apple,Ball and it if matches the line in the file print it.
so far I am able to get this.
import re
import sys
print('Enter the values')
value1=input()
try:
filenm1="D:\names.txt"
t=open(filenm1,'r')
regexp=re.search(value1,line)
for line in t:
if regexp:
print(line)
catch IOerror:
print('File not opened')
sys.exit(0)
Sample Input File
Apple
Ball
Stackoverflow
Call
Doll
User input : App
Output : Apple
now I want to modify this program to search by
user input : App,Doll
Output :
Apple
Doll
You can change your loop into this:
import sys
print('Enter the values')
value1=input()
value1=value1.split(',')
try:
filenm1="D:\names.txt"
t=open(filenm1,'r')
for line in t:
alreadyPrinted = False
for value in value1:
if value in line:
if not alreadyPrinted: #this bit prevents line being printed twice
print(line)
alreadyPrinted = True
except IOerror:
print('File not opened')
sys.exit(0)

Why won't this python script generate the desired text file? (despite the script running with no errors)

This script is supposed to generate a text file of stock price values. I can't seem to either find the text file that is supposed to be generated from this script or have this script actually create the desired text file... I added a section of code to check if the file exists, but I keep getting the result that the text file is indeed not created. Please let me know what I can do to correct. When I run the code I do not get any errors. Thanks.
import urllib2
import time
import os
import sys
stockToPull = 'AAPL'
def pullData(stock):
try:
fileLine = stock+'.txt'
urlToVisit = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/csv'
sourceCode = urllib2.urlopen(urlToVisit).read()
splitSource = sourceCode.split('\n')
for eachLine in splitSource:
splitLine = eachLine.split(', ')
if len(splitLine)==6:
if 'values' not in eachLine:
saveFile = open(fileLine,'a')
lineToWrite = eachLine+'\n'
saveFile.write(lineToWrite)
print 'Pulled', stock
print 'sleeping'
if os.path.isfile(fileLine): # checks to see if text file created
print "file does exist"
else:
print "No such file"
time.sleep(5)
except Exception, e:
print 'main loop', str(e)
pullData(stockToPull)
You are splitting each row on the string ', ' (note the space). You should be splitting on the comma only:
for eachLine in splitSource:
splitLine = eachLine.split(',')
if len(splitLine)==6:
# etc
You would be better off opening the file once, writing each line to it, then closing the file when finished. You can use a with statement to do this:
with open(fileLine, 'w') as outfile:
for eachLine in splitSource:
splitLine = eachLine.split(',')
if len(splitLine) == 6 and 'values' not in eachLine:
outfile.write('%s\n' % eachLine)
outfile.close()
i think you need to check whether data is arriving or not using
from urllib2 import Request, urlopen, URLError, HTTPError
fileLine = stock+'.txt'
urlToVisit = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/csv'
try:
response = urlopen(urlToVisit)
sourceCode = response.read()
<place your logic here>
except HTTPError as e:
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
except URLError as e:
print 'We failed to reach a server.'
print 'Reason: ', e.reason
your code works fine
output i got
['uri:/instrument/1.0/AAPL/chartdata;type=quote;range=1y/csv', 'ticker:aapl', 'Company-Name:Apple Inc.', 'Exchange-Name:NMS', 'unit:DAY', 'timestamp:', 'first-trade:19801212', 'last-trade:20140702', 'currency:USD', 'previous_close_price:59.7843', 'Date:20130703,20140702', 'labels:20130703,20130801,20130903,20131001,20131101,20131202,20140102,20140203,20140303,20140401,20140501,20140602,20140701', 'values:Date,close,high,low,open,volume', 'close:59.2929,94.2500', 'high:60.1429,95.0500', 'low:58.6257,93.5700', 'open:59.0857,94.7300', 'volume:28420900,266380800', '20140620,90.9100,92.5500,90.9000,91.8500,100813200', .....
'20140702,93.4800,94.0600,93.0900,93.8700,28420900', '']
['uri:/instrument/1.0/AAPL/chartdata;type=quote;range=1y/csv']
['ticker:aapl']
['Company-Name:Apple Inc.']
['Exchange-Name:NMS']
['unit:DAY']
['timestamp:']
['first-trade:19801212']
['last-trade:20140702']
['currency:USD']
['previous_close_price:59.7843']
['Date:20130703,20140702']
['labels:20130703,20130801,20130903,20131001,20131101,20131202,20140102,20140203,20140303,20140401,20140501,20140602,20140701']
['values:Date,close,high,low,open,volume']
['close:59.2929,94.2500']
['high:60.1429,95.0500']
['low:58.6257,93.5700']
['open:59.0857,94.7300']
['volume:28420900,266380800']
['20130703,60.1143,60.4257,59.6357,60.1229,60232200']
['20130705,59.6314,60.4700,59.3357,60.0557,68506200']
['20130708,59.2929,60.1429,58.6643,60.0157,74534600']
......
['20140630,92.9300,93.7300,92.0900,92.1000,49482300']
['20140701,93.5200,94.0700,93.1300,93.5200,38170200']
['20140702,93.4800,94.0600,93.0900,93.8700,28420900']
['']
Pulled AAPL
sleeping
file does exist
Your code is fine, but I don't think it is able to do what you want or you don't know what you want. You haven't observed your data correctly. I have made minor changes to your script. Please run this script now:
import urllib2
import time
import os
import sys
stockToPull = 'AAPL'
def pullData(stock):
try:
fileLine = stock+'.txt'
urlToVisit = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/csv'
sourceCode = urllib2.urlopen(urlToVisit).read()
splitSource = sourceCode.split('\n')
for eachLine in splitSource:
splitLine = eachLine.split(', ')
if len(splitLine)==6:
print 'Entering outer'
if 'values' not in eachLine:
print 'Entering innter'
saveFile = open(fileLine,'a')
lineToWrite = eachLine+'\n'
saveFile.write(lineToWrite)
print 'Pulled', stock
print 'sleeping'
if os.path.isfile(fileLine): # checks to see if text file created
print "file does exist"
else:
print "No such file"
time.sleep(5)
except Exception, e:
print 'main loop', str(e)
pullData(stockToPull)
If you'd notice, I have just put two print statements inside the if blocks that actually write to a file. On running the script, I noticed that the print statements are never executed. So there are no errors in your code to my knowledge but it doesn't seem to be doing what you want it to. So re-check your data again.
Lastly, to solve these kind of problems, you must use the pdb library which stands for Python Debugger and it is an amazingly helpful tool to debug your code without making a mess of it. Checkout this video from PyCon.

Python - Keep command window open to see results

I have a text file (test.txt) that contains
text1 text2 text text text
Below is my code:
import codecs
BOM = codecs.BOM_UTF8.decode('utf8')
name = (raw_input("Please enter the name of the file: "))
with codecs.open(name, encoding='utf-8') as f:
words=[] #define words here
for line in f:
line = line.lstrip(BOM)
words.extend(line.split()) #append words from each line to words
if len(words) > 2:
print 'There are more than two words'
firstrow = words[:2]
print firstrow #indentation problem here
elif len(words) <2: #use if
print 'There are under 2 words, no words will be shown'
raw_input("Press return to close this window...")
When I run the .py file, I want to keep the command window open so I can see all the prints, but for some reason it closes right away, when I run this in shell it works. For some reasoning the raw_input is not working like it normally has for me. Its my 2nd day at python so I am still a newbie!
Thanks in advance for the help
Newbie question, newbie answer!!
I didnt have my text file in the directory of my .py only in my shell path which is why it was working there.
You should put at least the file reading code in a try/except block, so you can see what errors occur;
import codecs
BOM = codecs.BOM_UTF8.decode('utf8')
name = raw_input("Please enter the name of the file: ")
try:
with codecs.open(name, encoding='utf-8') as f:
words=[] #define words here
for line in f:
line = line.lstrip(BOM)
words.extend(line.split())
except Exception as details:
print "Unexpected error:", details
raw_input("Press return to close this window...")
exit(1)
if len(words) > 2:
print 'There are more than two words'
firstrow = words[:2]
print firstrow
elif len(words) <2: #use if
print 'There are under 2 words, no words will be shown'
raw_input("Press return to close this window...")
If I try this with a nonexisting filename:
Please enter the name of the file: bla
Unexpected error: [Errno 2] No such file or directory: 'bla'
Press return to close this window...

How do I remove a particular line from a file but keep other lines intact?

I want to learn Python so I started writing my first program which is a phone book directory.
It has the options to add a name and phone number, remove numbers, and search for them.
Ive been stuck on the remove part for about 2 days now and just can't get it working correctly. I've been in the Python IRC and everything, but haven't been able to figure it out.
Basically, my program stores the numbers to a list in a file. I cannot figure out how to remove a particular line in the file but keep the rest of the file intact. Can someone please help me with this?
Some people have advised that it will be easier to do if I create a temp file, remove the line, then copy the remaining lines from the original file over to the temp file. Then write over the original file over with the temp file. So I have been trying this...
if ui == 'remove':
coname = raw_input('What company do you want to remove? ') # company name
f = open('codilist.txt', 'r') # original phone number listing
f1 = open('codilist.tmp', 'a') # open a tmp file
for line in f:
if line.strip() != coname.strip():
for line in f:
f1.write(line)
break # WILL LATER OVERWRITE THE codilist.txt WITH THE TMP FILE
else:
f1.write(line)
else:
print 'Error: That company is not listed.'
f1.close()
f.close()
continue
I assume your file contains something like <name><whitespace><number> on each line? If that's the case, you could use something like this for your if statement (error handling not included!):
name, num = line.strip().split()
if name != coname.strip():
# write to file
Suggestion:
Unless there is some specific reason for you to use a custom format, the file format json is quite good for this kind of task. Also note the use of the 'with' statement in these examples, which saves you having to explicitly close the file.
To write the information:
import json
# Somehow build a dict of {coname: num,...}
info = {'companyA': '0123456789', 'companyB': '0987654321'}
with open('codilist.txt', 'w') as f:
json.dump(info, f, indent=4) # Using indent for prettier files
To read/amend the file:
import json
with open('codilist.txt', 'r+') as f:
info = json.load(f)
# Remove coname
if coname in info:
info.pop(coname)
else:
print 'No record exists for ' + coname
# Add 'companyC'
info['companyC'] = '0112233445'
# Write back to file
json.dump(info, f, indent=4)
You'll need python2.6 or later for these examples. If you're on 2.5, you'll need these imports:
import simplejson as json
from __future__ import with_statement
Hope that helps!
Here is a pretty extensively rewritten version:
all the phone data is wrapped into a Phonebook class; data is kept in memory (instead of being saved and reloaded for every call)
it uses the csv module to load and save data
individual actions are turned into short functions or methods (instead of One Big Block of Code)
commands are abstracted into a function-dispatch dictionary (instead of a cascade of if/then tests)
This should be much easier to understand and maintain.
import csv
def show_help():
print('\n'.join([
"Commands:",
" help shows this screen",
" load [file] loads the phonebook (file name is optional)",
" save [file] saves the phonebook (file name is optional)",
" add {name} {number} adds an entry to the phonebook",
" remove {name} removes an entry from the phonebook",
" search {name} displays matching entries",
" list show all entries",
" quit exits the program"
]))
def getparam(val, prompt):
if val is None:
return raw_input(prompt).strip()
else:
return val
class Phonebook(object):
def __init__(self, fname):
self.fname = fname
self.data = []
self.load()
def load(self, fname=None):
if fname is None:
fname = self.fname
try:
with open(fname, 'rb') as inf:
self.data = list(csv.reader(inf))
print("Phonebook loaded")
except IOError:
print("Couldn't open '{}'".format(fname))
def save(self, fname=None):
if fname is None:
fname = self.fname
with open(fname, 'wb') as outf:
csv.writer(outf).writerows(self.data)
print("Phonebook saved")
def add(self, name=None, number=None):
name = getparam(name, 'Company name? ')
number = getparam(number, 'Company number? ')
self.data.append([name,number])
print("Company added")
def remove(self, name=None):
name = getparam(name, 'Company name? ')
before = len(self.data)
self.data = [d for d in self.data if d[0] != name]
after = len(self.data)
print("Deleted {} entries".format(before-after))
def search(self, name=None):
name = getparam(name, 'Company name? ')
found = 0
for c,n in self.data:
if c.startswith(name):
found += 1
print("{:<20} {:<15}".format(c,n))
print("Found {} entries".format(found))
def list(self):
for c,n in self.data:
print("{:<20} {:<15}".format(c,n))
print("Listed {} entries".format(len(self.data)))
def main():
pb = Phonebook('phonebook.csv')
commands = {
'help': show_help,
'load': pb.load,
'save': pb.save,
'add': pb.add,
'remove': pb.remove,
'search': pb.search,
'list': pb.list
}
goodbyes = set(['quit','bye','exit'])
while True:
# get user input
inp = raw_input("#> ").split()
# if something was typed in
if inp:
# first word entered is the command; anything after that is a parameter
cmd,args = inp[0],inp[1:]
if cmd in goodbyes:
# exit the program (can't be delegated to a function)
print 'Goodbye.'
break
elif cmd in commands:
# "I know how to do this..."
try:
# call the appropriate function, and pass any parameters
commands[cmd](*args)
except TypeError:
print("Wrong number of arguments (type 'help' for commands)")
else:
print("I didn't understand that (type 'help' for commands)")
if __name__=="__main__":
main()
Something simple like this will read all of f, and write out all the lines that don't match:
for line in f:
if line.strip() != coname.strip():
f1.write(line)
Ned's answer looks like it should work. If you haven't tried this already, you can set python's interactive debugger above the line in question. Then you can print out the values of line.strip() and coname.strip() to verify you are comparing apples to apples.
for line in f:
import pdb
pdb.set_trace()
if line.strip() != coname.strip():
f1.write(line)
Here's a list of pdb commands.
You probably don't want to open the temp file in append ('a') mode:
f1 = open('codilist.tmp', 'a') # open a tmp file
also, be aware that
for line in f:
...
f1.write(line)
will write everything to the file without newlines.
The basic structure you want is:
for line in myfile:
if not <line-matches-company>:
tmpfile.write(line + '\n') # or print >>tmpfile, line
you'll have to implement <line-matches-company> (there isn't enough information in the question to know what it should be -- perhaps if you showed a couple of lines from your data file..?)
I got this working...
if ui == 'remove':
coname = raw_input('What company do you want to remove? ') # company name
f = open('codilist.txt')
tmpfile = open('codilist.tmp', 'w')
for line in f:
if coname in line:
print coname + ' has been removed.'
else:
tmpfile.write(line)
f.close()
tmpfile.close()
os.rename('codilist.tmp', 'codilist.txt')
continue

Python checking file content with string

Hello! I have the following script:
import os
import stat
curDir = os.getcwd()
autorun_signature = [ "[Autorun]",
"Open=regsvr.exe",
"Shellexecute=regsvr.exe",
"Shell\Open\command=regsvr.exe",
"Shell=Open" ]
content = []
def read_signature(file_path):
try:
with open(file_path) as data:
for i in range(0,5):
content.append(data.readline())
except IOError as err:
print("File Error: "+ str(err))
read_signature(os.getcwd()+'/'+'autorun.inf')
if(content==autorun_signature):
print("Equal content")
else:
print("Not equal")
It prints not equal, then I tried this method:
import os
import stat
curDir = os.getcwd()
autorun_signature = "[Autorun]\nOpen=regsvr.exe\nShellexecute=regsvr.exe\nShell\Open\command=regsvr.exe\nShell=Open"
content = ""
def read_signature(file_path):
try:
with open(file_path) as data:
content = data.read()
except IOError as err:
print("File Error: "+ str(err))
read_signature(os.getcwd()+'/'+'autorun.inf')
if(content==autorun_signature):
print("Equal content")
else:
print("Not equal")
It also print not equal!
I want to store the content of autorun.inf file in script and every time i find such file I want to check its content if it is or not, I could not do, can anyone help me?
the content of autorun.inf:
[Autorun]
Open=regsvr.exe
Shellexecute=regsvr.exe
Shell\Open\command=regsvr.exe
Shell=Open
Linebreaks under Windows \r\n are different from Linux's \n.
So try replacing \n with \r\n.
It is probably due to the fact that Windows new lines are \r\n instead of \n.
Also, you should escape the "\", so instead use"\\".

Categories