Im trying to understand why I cannot access the methods on an object that is instantiated inside of a class. For example i'm attempting to build a script that utilizes the python-pptx library and I want to wrap the entire slide creation within a class to abstract it and make it a bit more reusable based on my configuration.
class Builder():
def __init__(self, template='template.pptx', output_file='out.pptx'):
self.cust_name = ''
self.author = ''
self.job_title = ''
self.present_date = ''
self.assessment_type = ''
self.template = template
self.agenda = ['Overview','Resources']
self.outfile = output_file
self.prs = Presentation('template.pptx') <--- This is what im referring to.
def addAgendaSlide(self):
agenda_slide = self.prs.add_slide(self.prs.slide_layouts[AGENDA]) <-- When trying to access this
agenda_slide.shapes.title.text = 'Agenda'
agenda_slide.placeholders[10].text = 'A test Agenda slide'
agenda_slide.placeholders[15].top = STANDARD_TOP
agenda_slide.placeholders[15].left = STANDARD_LEFT
agenda_slide.placeholders[15].width = 8229600
agenda_slide.placeholders[15].height = 4572000
for para in self.agenda:
p = agenda_slide.placeholders[15].text_frame.add_paragraph()
p.text = para
Traceback (most recent call last):
File "test.py", line 19, in <module>
test.addAgendaSlide()
File "/dev/pythonpptx/DocMaker/Slides.py", line 89, in addAgendaSlide
agenda_slide = self.prs.add_slide(self.prs.slide_layouts[AGENDA])
AttributeError: 'Presentation' object has no attribute 'add_slide'
If I use the same bits of code outside the class it works fine. I do have other methods in the class that are fine, it seems to be my implementation of the Presentation() bit that is messing me up.
The following works fine:
prs = Presentation('template.pptx')
agenda_slide = prs.slides.add_slide(prs.slide_layouts[AGENDA])
agenda_slide.shapes.title.text = 'Agenda'
agenda_slide.placeholders[15].top = STANDARD_TOP
agenda_slide.placeholders[15].left = STANDARD_LEFT
agenda_slide.placeholders[15].width = 8229600
agenda_slide.placeholders[15].height = 4572000
prs.save('out.pptx')
I think your problem is you are forgetting to add slides as follows:
agenda_slide = self.prs.slides.add_slide(self.prs.slide_layouts[AGENDA])
instead of
agenda_slide = self.prs.add_slide(self.prs.slide_layouts[AGENDA])
Related
I am creating a universal text field that can be used in many python turtle projects. I am trying to create an instance of it but I get this error:
>>> import TextField
>>> tf = TextField('None', False)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
tf = TextField('None', False)
TypeError: 'module' object is not callable
>>>
What in a module causes this type of error? I completely wrote this module and I'm getting an error creating an instance of it :( ... What do I need in this module to make it 'callable'? I have tried adding a def __call__(self): but that doesn't affect the problem at all, nor create any errors.
Here is the beginning of the script where the problem is most likely happening:
# Created by SUPERMECHM500 # repl.it
# Edited by cdlane # stackoverflow.com
class TextField:
TextFieldBorderColor = '#0019fc'
TextFieldBGColor = '#000000'
TextFieldTextColor = '#ffffff'
ShiftedDigits = {
'1':'!',
'2':'#',
'3':'#',
'4':'$',
'5':'%',
'6':'^',
'7':'&',
'8':'*',
'9':'(',
'0':')'
}
def __init__(self, command, CanBeEmpty): # Ex. textField = TextField('Execute()', True)
self.CmdOnEnter = command
self.turtle = Turtle()
self.CanBeEmpty = CanBeEmpty
self.turtle.speed('fastest')
self.inp = []
self.FullOutput = ""
self.TextSeparation = 7
self.s = self.TextSeparation
self.key_shiftL = False
......
The module is not the class. If your class TextField is in a module called TextField, then it is referred to as TextField.TextField.
Or change your import to
from TextField import TextField
I have the following functions, that are working within the boundaries on the Python script
The loop_vcenters function will return a dictinary with cluster: host
subs_per_socket function will return the number of sockets for esx
def loop_vcenters(vcenters):
#------------------------- connect to vcenter ----------------------------------------
si = SmartConnect(host = vcenters,user = 'username',pwd = 'password' ,sslContext=context)
# disconnect from vcenter one done
atexit.register(Disconnect, si)
#get the object content from vcenter
content = si.RetrieveContent()
#list clusters
cluster_host_dic_list=[]
cluster_name = ""
for cluster_obj in get_obj(content, vim.ComputeResource):
cluster=cluster_obj.name
hosts=[]
for host in cluster_obj.host:
hosts.append(host.name)
#create dictinary ,key=cluster value=esx
cluster_dic={cluster:hosts}
cluster_host_dic_list.append(cluster_dic)
return cluster_host_dic_list
def subs_per_socket(host):
shost = content.searchIndex.FindByDnsName(dnsName=host, vmSearch=False)
socket_count = shost.summary.hardware.numCpuPkgs
sub_per_socket = socket_count/2
return sub_per_socket
I want to put both functions into a class, but I cannot figure out how
class loop_vcenters:
def hosts_dic(self,name):
si = SmartConnect(host = vcenters,user = 'username',pwd = 'password' ,sslContext=context)
atexit.register(Disconnect, si)
content = si.RetrieveContent()
cluster_host_dic_list=[]
cluster_name = ""
for cluster_obj in get_obj(content, vim.ComputeResource):
cluster=cluster_obj.name
hosts=[]
for host in cluster_obj.host:
hosts.append(host.name)
cluster_dic={cluster:hosts}
cluster_host_dic_list.append(cluster_dic)
return cluster_host_dic_list
I am unable to get the host dictionary like the loop_vcenters function returned.
d = loop_vcenters('vcenters')
Traceback (most recent call last):
File "", line 1, in
File "", line 5, in __init__
NameError: global name 'vcenters' is not defined
How can I add the subs_per_socket(host) function to the class?
d = loop_vcenters('vcenters')
You are calling the class loop_vcenters with an argument when no init is defined.
File "", line 5, in __init__
NameError: global name 'vcenters' is not defined
If you want to pass the argument to host_dic, you should be calling
d = loop_vcenters.host_dic('vcenters')
which will return cluster_host_dic_list to the variable d.
To add subs_per_socket(host), just define it under the class just as you did the other function.
EDIT: I have managed to solved the issue I wa having previously but instead of me creating another new question, this issue I have encountered are pretty much similar I guess?
As I am modifying some of the contents of this script that I am currently doingn, it will boot up this UI whenever user imports in a .chan object
Currently I am trying to edit the camera name such that when users selects the camera, it will inherits the name of the imported camera into its namespace.
Though I am not very sure, I think the reader function in the customNodeTranslator class is the one that reads the imported camera?
This is the error messgae:
# Error: global name 'cameraName' is not defined
# Traceback (most recent call last):
# File "/user_data/scripts/test/maya/plugins/chan.py", line 210, in readFileIn
# self.importTheChan = ChanFileImporter(chanRotationOrder)
# File "/user_data/scripts/test/maya/plugins/chan.py", line 286, in __init__
# self.cameraName = cameraName
# NameError: global name 'cameraName' is not defined #
This is the original code:
class customNodeTranslator(OpenMayaMPx.MPxFileTranslator):
...
...
...
def reader(self, fileObject, optionString, accessMode):
self.initialWindow()
try:
fullName = fileObject.fullName()
print ">>> full Name is %s" %fullName
#self.fileHandle = open(fullName,"r")
camHandle = open(fullName,"r")
camPath = os.path.basename(camHandle.name)
camName = os.path.splitext(camPath)[0]
print ">>> This is the name: %s" % camName
except:
sys.stderr.write( "Failed to read file information\n")
raise
return camName
class chanImport():
""" importing chan camera from nuke """
def __init__(self, rotation):
self.rotation = rotationOrder
# create the camera
self.cameraName = cmds.camera(n=str(camName))
self.cameraShape = self.cameraName[1]
cmds.select(self.cameraShape)
cmds.scale(0.5, 0.5, 0.5)
The following code is the actual code itself before I modified:
class customNodeTranslator(OpenMayaMPx.MPxFileTranslator):
...
...
...
def writer( self, fileObject, optionString, accessMode ):
try:
fullName = fileObject.fullName()
fileHandle = open(fullName,"w")
selectList = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList(selectList)
node = OpenMaya.MObject()
depFn = OpenMaya.MFnDependencyNode()
path = OpenMaya.MDagPath()
iterator = OpenMaya.MItSelectionList(selectList)
animationTime = OpenMayaAnim.MAnimControl()
class ChanFileImporter():
def __init__(self, rotationOrder):
self.rotationOrder = rotationOrder
# create the camera
self.cameraName = cmds.camera()
self.cameraShape = self.cameraName[1]
cmds.select(self.cameraShape)
cmds.scale(0.5, 0.5, 0.5)
You aren't passing the camName to the importer class. In fact you're not invoking the importer class at all in the sample above.
If you modify chanImport so it takes the name you want:
class chanImport(object):
""" importing chan camera from nuke """
def __init__(self, camName):
self.desiredCameraName = camName
self.cameraName = None
self.cameraShape = None
def create_camera(self):
self.cameraName, self.cameraShape = cmds.camera(n=str(camName))
cmds.select(self.cameraShape)
cmds.scale(0.5, 0.5, 0.5)
return self.cameraName
You should be able to invoke it inside your reader function:
def reader(self, fileObject, optionString, accessMode):
self.initialWindow()
try:
fullName = fileObject.fullName()
print ">>> full Name is %s" %fullName
camHandle = open(fullName,"r")
camPath = os.path.basename(camHandle.name)
camName = os.path.splitext(camPath)[0]
print ">>> This is the name: %s" % camName
importer = chanImport(camName)
actual_cam_name = importer.create_camera()
print ">>> created " + actual_cam_name
return actual_cam_name
except:
sys.stderr.write( "Failed to read file information\n")
raise
I've refactored my models files into a module - this way it's much easier to maintain the code since it has grown quite a bit.
The funny thing is though that it won't work for one of the classes that references another class that references the fist one in it's turn:
UPD: the cycling references are confusing python and this is what the problem is caused by. This is easy to fix when you only reference other models from your model definition. However, Picture has methods that reference paperType class and vice versa - how can this be fixed?
Here's class Picture:
from django.db import models
from django.utils import simplejson
from picviewer.models import Collection, ImageSizeRatio, printSize
class Picture(models.Model):
name = models.TextField(null=False,blank=False,unique=False)
collection = models.ForeignKey(Collection)
popularity = models.IntegerField(default=0,unique=False)
isPurchasable = models.BooleanField(default=False)
allowBuyExclusive = models.BooleanField(default=False)
basePrice = models.DecimalField(decimal_places=2,max_digits=8)
imageSizeRatio = models.ForeignKey(ImageSizeRatio)
imageThumbnail = models.FileField(upload_to='pictures')
imagePreview = models.FileField(upload_to='pictures')
imageSmall = models.FileField(upload_to='pictures')
imageNormal = models.FileField(upload_to='pictures')
imageLarge = models.FileField(upload_to='pictures')
imageHuge = models.FileField(upload_to='pictures')
allowedPrintSize = models.ManyToManyField(printSize)
Here is printSize class that it references - you see it calls Picture functions to do some math around pictures of specified printSize:
from django.db import models
from picviewer.models import paperType
from picviewer.models import Picture
class printSize (models.Model):
name = models.CharField(null=False,blank=False,unique=True,max_length=60)
width = models.IntegerField(null=False,blank=False)
height = models.IntegerField(null=False,blank=False)
allowedPaperType = models.ManyToManyField(paperType)
#isActive = models.NullBooleanField(null=True, default=None)
def json(self, picture_id, base_price):
sizes_selector = printSize.objects.filter(picture__id = picture_id)
sizes = list()
for size in sizes_selector:
papers = list()
for paper in size.allowedPaperType.all():
cost_for_paper = Picture.objects.get(id=picture_id).calculatePrice(paper.id,size.id)
p = dict(id = paper.id,
name = paper.name,
description = paper.description,
price = paper.pricePerSqMeter.__str__(),
cost = "%.2f" % cost_for_paper)
papers.append(p)
s = dict(id = size.id,
name = size.name,
width = size.width,
height = size.height,
allowedPapers = papers)
sizes.append(s)
return sizes
now this is what I get in shell trying to import Picture:
>>> from picviewer.models import Picture
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "D:\~Sasha\eclipse_workspace\zavalen\picviewer\models\Picture.py", line 4, in <module>
from picviewer.models import Collection, ImageSizeRatio, printSize
File "D:\~Sasha\eclipse_workspace\zavalen\picviewer\models\printSize.py", line 4, in <module>
from picviewer.models import Picture
ImportError: cannot import name Picture
>>>
can I cure this? :)
To avoid cyclic imports, specify FK model as a string, e.g
collection = models.ForeignKey('Collection') # Collection is in the same module
or
collection = models.ForeignKey('myapp.Collection') # Collection is in another app
I'm new to Python. I can't understand why a variable is None at a certain point in my code:
class UsersInRoom(webapp.RequestHandler):
def get(self):
room_id = self.request.get("room_id")
username = self.request.get("username")
UserInRoom_entities = UserInRoom.gql("WHERE room = :1", room_id).get()
if UserInRoom_entities:
for user_in_room in UserInRoom_entities:
if user_in_room.username == username:
user_in_room.put() # last_poll auto updates to now whenenever user_in_room is saved
else:
user_in_room = UserInRoom()
user_in_room.username = username
user_in_room.put()
// error here, on line 160
UserInRoom_entities = []
UserInRoom_entities.append(user_in_room)
# name is `user_at_room` intead of `user_in_room` to avoid confusion
usernames = [user_at_room.username for user_at_room in UserInRoom_entities]
self.response.out.write(json.dumps(usernames))
The error is:
Traceback (most recent call last):
File "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 507, in __call__
handler.get(*groups)
File "path\to\chat.py", line 160, in get
AttributeError: 'NoneType' object has no attribute 'append'
How is this possible? I'm setting UserInRoom_entities = [] immediately before that call. Or is something else the None in question?
UPDATE: This code works:
class UsersInRoom(webapp.RequestHandler):
def get(self):
room_id = self.request.get("room_id")
username = self.request.get("username")
UserInRoom_entities = UserInRoom.gql("WHERE room = :1", room_id).get()
if UserInRoom_entities:
for user_in_room in UserInRoom_entities:
if user_in_room.name == username:
user_in_room.put() # last_modified auto updates to now whenenever user_in_room is saved
else:
user_in_room = UserInRoom(room=Key(room_id), name=username)
user_in_room.put()
UserInRoom_entities = []
UserInRoom_entities.append(user_in_room)
# name is `user_at_room` intead of `user_in_room` to avoid confusion
usernames = [user_at_room.name for user_at_room in UserInRoom_entities]
self.response.out.write(json.dumps(usernames))
class ChatRoom(db.Model):
name = db.StringProperty()
last_modified = db.DateTimeProperty(auto_now=True)
message_contents = db.StringListProperty()
message_users = db.StringListProperty()
class UserInRoom(db.Model):
room = db.ReferenceProperty(ChatRoom)
name = db.StringProperty()
last_modified = db.DateTimeProperty(auto_now=True)
Since it appears that my comment to the question had the answer to this, I'll repeat it as an answer, with the hope of gaining some reputation points:
Is the UserInRoom instance initialized properly? I am not familiar with the GAE data model, but I could imagine that the put() ing the instance would require that the room attribute was set, if there is a relationship between UserInRoom and Room (assuming a Room class exists).
To make sure that you're not the one raising exception, you can do something like:
UserInRoom_entities = []
# raised? then your .append is missing otherwise something else is wrong
UserInRoom_entities.append
UserInRoom_entities.append(user_in_room)