Write a program that defines a class Movie that has the following attributes: title, director, length (length of the movie in minutes). Create five objects of class Movie, pickle them, and store them in a file.
#!/usr/local/bin/python
import pickle
class Movies:
def __init__(self,title,director,length):
self.x=title
self.y=director
self.z=length
def main():
movie1 = Movies(1,100,10)
movie2 = Movies(2,200,20)
movie3 = Movies(3,300,30)
movie4 = Movies(4,400,40)
movie5 = Movies(5,500,50)
main()
import pickle
try:
file=open("movies.txt","w")
fold =[movie1,movie2,movie3,movie4,movie5]
pickle.dump[fold,file]
except IOError:
print("file could not be open")
except ValueError:
print("could not make list")
except:
print("some unknown error")
else:
print("successfully done!")
finally:
print("printing always")
file.close()
So everything works fine but the movies.txt file is empty. Im new to Python so I have less experience with exception handling. But from what I understood pickle isnt working.
You are defining the movie variables in the function main however they will not be present in the scope where you define your try block. Additionally, as have been noted in the comments of the question you are using the wrong syntax to call pickle.dump. It should use parentheses and not squeare brackets, i.e. pickle.dump(fold,file).
Finally moving your try block into the main function will make things work as expected. Like this:
def main():
movie1 = Movies(1,100,10)
movie2 = Movies(2,200,20)
movie3 = Movies(3,300,30)
movie4 = Movies(4,400,40)
movie5 = Movies(5,500,50)
import pickle
try:
file=open("movies.txt","w")
fold =[movie1,movie2,movie3,movie4,movie5]
pickle.dump(fold,file)
except IOError:
print("file could not be open")
except ValueError:
print("could not make list")
except:
print("some unknown error")
else:
print("successfully done!")
finally:
print("printing always")
file.close()
main()
There are still a bunch of style issues with the code, but this should get you going!
Related
I would like use "try except" statement, but in two function. I caught an exception in function, but function2 does anyway. How can i stop it until there is an exception
i want to transfer it to a window application. If the file does not load, I want to display an information window. I only want the program to go on (function2) when the file loads
class Files:
def __init__(self):
self.name = "fle.txt"
def function(self):
try:
self.f = open(self.name, 'rb')
except OSError:
print("Problem!!!")
def function2(self):
print(self.f.read())
def main():
file=Files()
file.function()
file.function2()
Don't catch an exception unless you actually know how to handle it.
class Files:
def __init__(self):
self.name = "fle.txt"
self.f = None
def function(self):
self.f = open(self.name, 'rb')
def function2(self):
if self.f is None:
raise Exception("File not initialized!") #Example
#return #just if you don't throw or exit
print(self.f.read())
def main():
file=Files()
try:
file.function()
except OSError:
print("Problem!!!")
else:
file.function2()
main()
Wrap your function calls in a higher level try/except.
Of course, you would never write anything like this because it's so inflexible. This answer does not condone the OP's approach but suggests how that could be made to work.
class Files:
def __init__(self):
self.name = 'fle.txt'
def function_1(self):
self.fd = open(self.name)
def function_2(self):
print(self.fd.read())
def __del__(self):
try:
self.fd.close()
except Exception:
pass
file = Files()
try:
file.function_1()
file.function_2()
except Exception as e:
print(e)
So we don't do any exception handling (except in __del__ where we ignore any issues) within the class functions but allow all/any exceptions to propagate to the caller. Here we want to call two class functions but we wrap them in the same try/except block.
If function_1 raises an exception, function_2 won't be called.
del added to show how one could clean up but it's not the way this should be handled
#tomgalpin is right you could just exit right there after the problem
But this being a class maybe you want to print the error and pass back no data?
Here's one way to look at that with Tom's included sys exit (commented out)
Also be sure if you keep your code to close the file handler. Calling open on a file without .close() can leave file handlers open and cause problems for you if your class were to continue on after.
class Files:
def __init__(self):
self.name = "fle.txt"
# Empty string in data if no data
self.data = ""
def function(self):
try:
#self.f = open(self.name, 'rb')
with open(self.name, 'rb') as f:
self.data = f.read()
except OSError as err:
print("Problem!!!", err)
# You could exit
# sys.exit()
# But you could also return an empty string,
# which is "falsy", regardless of what happens
finally:
return self.data
def function2(self):
print(f"Data 3 {self.data}")
def main():
file=Files()
# You could print this, or use it to get the data
print("Data 1", file.function())
data = file.function()
print(f"Data 2 {data}")
# this now also shows the data
file.function2()
Use the variable that is usually True but becomes False if function fails
Example
class Files:
def __init__(self):
self.name = "file.txt"
self.Continue=True
self.data = ""
def function(self):
try:
#self.f = open(self.name, 'rb')
with open(self.name, 'rb') as f:
self.data = f.read()
except OSError as err:
print("Problem!!!", err)
self.Continue=False
return False
finally:
return self.data
def function2(self):
if self.Continue:
print(self.data)
else:
#Code if function failed
def main():
file=Files()
file.function()
file.function2()
I am running a code to create cloudformation stack, delete stack, update stack with defined parameter variable using json file using python.
I have defined a 3 different statement under init() function. I need to put a if condition:
if i want to create a stack, it will call "create_products"
else, update a stack, it will call "update_products"
elif, delete a stack, it will update "delete_products"
from __future__ import print_function
import subprocess
import json
import yaml
import sys
import os
import re
import boto3
from glob import glob
def createstack(productName, productId, paramlist):
try:
client = boto3.client('servicecatalog', region_name='us-east-1')
ProvisioningArtifactId = client.list_provisioning_artifacts(ProductId=productId)
ArtifactId = ProvisioningArtifactId['ProvisioningArtifactDetails'][0]['Id']
response = client.provision_product(ProvisionedProductName=productName, ProductId=productId, ProvisioningArtifactId=ArtifactId, ProvisioningParameters=paramlist)
print(response)
except Exception as e:
error = "An error occurred processing this request: " + str(e)
print(error)
def updatestack(productName, productId, paramlist):
try:
client = boto3.client('servicecatalog', region_name='us-east-1')
ProvisioningArtifactId = client.list_provisioning_artifacts(ProductId=productId)
ArtifactId = ProvisioningArtifactId['ProvisioningArtifactDetails'][0]['Id']
response = client.update_provisioned_product(ProvisionedProductName=productName, ProductId=productId, ProvisioningArtifactId=ArtifactId, ProvisioningParameters=paramlist)
print(response)
except Exception as e:
error = "An error occurred processing this request: " + str(e)
print(error)
def deletestack(productName):
try:
client = boto3.client('servicecatalog', region_name='us-east-1')
response = client.terminate_provisioned_product(ProvisionedProductName=productName)
print(response)
return response
except Exception as e:
error = "An error occurred processing this request: " + str(e)
return(error)
def init():
#global args
with open("list_provisional_product.json") as f:
product_list = json.load(f)
with open("testing-pipeline-params.json") as f:
baselist = json.load(f)
for product in product_list["update_products"]:
for provisioned_product_name in product["provisioned_product_names"]:
updatestack(productName=provisioned_product_name, productId=product["product_id"], paramlist=baselist[provisioned_product_name])
for product in product_list["delete_products"]:
for provisioned_product_name in product["provisioned_product_names"]:
deletestack(productName=provisioned_product_name)
for product in product_list["create_products"]:
for provisioned_product_name in product["provisioned_product_names"]:
createstack(productName=provisioned_product_name, productId=product["product_id"], paramlist=baselist[provisioned_product_name])
def main():
init()
if __name__== "__main__":
main()
Yes, You have to get operation name(Create/ Update/ Delete) from user via command line argument or ask user during code execution via input function.
Demo 1: Get Operation name from command line argument by using sys.argv
You have to give operation name when you run your python code. Here Py file name is if_loop.py
import sys
print("arg:", sys.argv)
try:
operation_name = sys.argv[1].lower()
except IndexError:
print("Argument is missing")
exit()
if operation_name == "create":
print("Call Create function")
elif operation_name == "update":
print("Call Update function")
elif operation_name == "delete":
print("Call Dale function")
else:
print("Invalid Operation name")
Output
Invalid Operation name
(env) PS C:\Users\vivek\Documents\Workplace\stackoverflow> python .\if_loop.py Create
arg: ['.\\if_loop.py', 'Create']
Call Create function
Demo 2: Using input function
operation_name = input("Give Operation Name:").lower()
if operation_name == "create":
print("Call Create function")
elif operation_name == "update":
print("Call Update function")
elif operation_name == "delete":
print("Call Dale function")
else:
print("Invalid Operation name")
Output
Give Operation Name:Update
Call Update function
Thank you so much Vivek ! I would rather go with approach 1st ie argv and it actually worked based on my need !! BRAVO
I have written a code to write parallel in a csv file in python.
When my program gets over, what I see is that few lines are merged instead of in seperate lines. Each line should only contain 3 columns. But instead it shows as below
EG
myname myage myvalue
myname myage myvaluemyname
myname myage myvalue
myage
What I understood by reading few other questions, is that I need to lock my file if I want to avoid such scenarios. So I added fcntl module. But it seems my file is still not being locked as it produces similar output
My code
def getdata(x):
try:
# get data from API
c.writefile(x,x1,x2)
except Exception,err:
print err
class credits:
def __init__(self):
self.d = dict()
self.details = dict()
self.filename = "abc.csv"
self.fileopen = open(self.filename,"w")
def acquire(self):
fcntl.flock (self.fileopen, fcntl.LOCK_EX)
def release(self):
fcntl.flock(self.fileopen, fcntl.LOCK_UN)
def __del__(self):
self.fileopen.close()
def writefile(self,x,x1,x2,x3):
try:
self.acquire()
self.fileopen.write(str(x)+","+str(x1)+","+str(x2)+"\n")
except Exception, e:
raise e
finally:
self.release()
if __name__ == '__main__':
conn = psycopg2.connect()
curr = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
curr.execute("select * from emp")
rows = curr.fetchall()
listdata = []
for each in rows:
listdata.append(each[0])
c = credits()
p = Pool(processes = 5)
results = p.map(getdata,listdata)
conn.close()
I had to declare getdata as TOP level function otherwise it gave me "Cant pickle function"
Why don't you write to multiple files in each separate process and then merge them? It might be more computationally expensive but it will ensure thread safety.
I am stuck with a Python issue related to threading.
import threading
import time
import random
import sys
import echo
class presence(threading.Thread):
def __init__(self, cb):
threading.Thread.__init__(self)
self.callback = cb
def run(self):
minValue = 0
maxValue = 3
try:
while True:
time.sleep(1)
if random.randint(minValue, maxValue) == 1:
self.callback(1)
elif random.randint(minValue, maxValue) == 2:
raise Exception('An error')
else:
self.callback(0)
except:
print 'Exception caught!'
pass
def showAlert():
echo.echo('Someone is behind the door!')
def count(x):
if x == 1:
showAlert()
sys.stdout.flush()
That is how I call it:
t2 = presence.presence(presence.count)
t2.start()
I eventually get an "Exception caught!", but the thread stops not returning alerts anymore.
What did I do wrong here?
The try/except block should be inside the loop. For example:
while True:
...
elif random.randint(minValue, maxValue) == 2:
try:
raise Exception('An error')
except Exception:
print 'Exception caught!'
Otherwise, the loop will be exited when the exception is raised and Python jumps to the except: block in order to handle it.
You'll notice too that I selectively placed the try/except block in my example to only cover the code that might actually raise the exception. This is a best practice and I recommend it for your code. Having a try/except block enclose large portions of code decreases readability and also wastes space (lots of lines are unnecessarily indented).
This seems like a remedial topic, but I'm a bit unsure of how to deal with this. Every solution I think of seems messy.
I'm working with some code that builds up a message while performing several actions, then ultimately returns that msg with an http response. Currently it looks somewhat like this:
try:
pdict = parser.parseProtocol(id)
msg = "parsing worked"
except:
msg = "parsing failed"
try:
file = parser.getFile(pdict['filePath'])
msg += "file retrieved"
except:
msg += "file not found"
Say I want to encapsulate the code into functions. How could do I have a message that gets updated throughout? Strings are immutable, so I can't just pass them to a function and modify them. A super ugly solution would be:
(pdict, msg) = parseSomething()
if pdict:
(file, msg) = retrieveFile(pdict, msg)
def parseSomething():
try:
pdict = parser.parseProtocol(id)
return (pdict, "parsing worked")
except:
return (None, "parsing failed")
def retrieveFile(pdict, msg)
try:
file = parser.getFile(pdict['filePath'])
return (file, msg + "file retrieved")
except:
return (None, msg + "file not found")
Super ugly.
I could create a message class, or use a list of length 1, and that would be prettier, but still not very pythonic, right? I think I just want these functions to take a message string and modify it, without having to return it, but strings are immutable so that's not the default behavior.
There's gotta be a smooth way to do this that I'm just blanking on. Help?
Consider putting your messages in a list and appending to it as you go?
messages = []
try:
pdict = parser.parseProtocol(id)
messages.append("parsing worked")
except:
messages.append("parsing failed")
try:
file = parser.getFile(pdict['filePath'])
messages.append("file retrieved")
except:
messages.append("file not found")
print '\n'.join(messages)
If your codepath is particularly convuluted, consider embedding them in a class:
class Tests(object):
def __init__(self):
messages = []
self.pdict = None
def parsetest(self):
try:
self.pdict = parser.parseProtocol(id)
except:
self.messages.append("parsing failed")
else:
self.messages.append("parsing worked")
def retrievetest(self):
if self.pdict is None:
raise Exception("called retrievetest() before successfully parsing")
try:
file = parser.getFile(self.pdict['filePath'])
except:
self.messages.append("file not found")
else:
self.messages.append("file retrieved")
And then later:
tests = Tests()
tests.parsetest()
if condition:
tests.retrievetest()
print '\n'.join(tests.messages)
put your message in an array, pass it around, and just append each part to it.
just before sending it, do a ''.join(msg).
Make your message a member of a class, and pass around an instance of the class.
Better yet, make all these function methods on a class, and keep the message as an attribute of the object.