NameError on initialization of class instance - python

I have been playing around with scripts for a couple of weeks and have not had any issues, but I am now trying to create a class and am running into problems.
I don't fully understand it myself but I am getting this error NameError: global name 'instance_status_check' is not defined when I try to create an instance of the following class.
I am fully aware the class isn't doing much at this time but I can't move on until I resolve the problem. Can someone explain what I am doing wrong?
import sys
import boto
import boto.ec2
class Monitor:
def __init__(self,conn,identifier):
self.connection = conn
self.identifier = identifier
self.dispatcher ={'1': instance_status_check}
def user_menu():
for i, value in self.dispatcher.itertems():
print "Please press {i} for {value}".format(i,value)
def instance_status_check():
pass

You are missing the self parameter from both methods and it is iteritems not itertems:
class Monitor: # upper case for class names
def __init__(self,conn,identifier):
self.connection = conn
self.identifier = identifier
self.dispatcher ={'1': self.instance_status_check} # call self.instance_status_check()
def user_menu(self): # self here
for i, value in self.dispatcher.iteritems():
print("Please press {i} for {value}".format(i,value))
def instance_status_check(self): # self here
return "In status method"
m = Monitor(3,4)
print(m.dispatcher["1"]())
In status method
I suggest you have a look at the classes tutorial from the docs

You have this error because you have defined instance_status_check after you are already using it.
Move the declaration above the class:
def instance_status_check():
pass
class monitor:
def __init__(self,conn,identifier):
self.connection = conn
self.identifier = identifier
self.dispatcher ={'1': instance_status_check}
def user_menu(self):
for i, value in self.dispatcher.itertems():
print "Please press {i} for {value}".format(i,value)
Also, this will not print Please press 1 for instance_status_check it will print something like Please press 1 for <function instance_status_check at 0xsomething>

Related

Calling a function from a class in main

I seem to be making a stupid mistake that I cant find. Im simply trying to call my functions from my record class and having an invalid syntax error despite looking at sample code and trying to emulate the syntax.
Ive tried following tutorials and calling the function in every which way so the problem may not be in the calling of the function but something else I feel.
class definitions
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
def addrecord(self,x,y,z):
x = input('Enter telephone number')
y = input('Enter lastname')
z = input('Enter firstname')
phonebook.append(record(x,y,z))
return
def deleterecord(self,x):
phonebook[x-1].pop
return
Main
phonebook = record[]
addrecord(515,'fin','matt')
print(phonebook[0].firstname)
deleterecord(1)
print(phonebook[0].firstname)
If all this works I expect the output to be
"matt"
"null"
There are a number of problems with your code:
you are defining phonebook otuside of the class
in deleterecord you should call phonebook.pop(x).
there should be two classes that handle the phonebook and records, and the record could be modeled using a namedtuple.
there are syntax errors like calling record[] which is not valid Python.
Alternative implementation:
from collections import namedtuple
PhoneRecord = namedtuple("PhoneRecord", ['firstname', 'lastname', 'telephone'])
class PhoneBook:
def __init__(self):
self._phonebook = []
def addrecord(self, record):
self._phonebook.append(record)
return self._phonebook.index(record)
def deleterecord(self, i):
self._phonebook.pop(i)
phonebook = PhoneBook()
record_index = phonebook.addrecord(PhoneRecord(firstname="matt", lastname="snow", telephone="25512521"))
print(phonebook._phonebook)
phonebook.deleterecord(record_index)
print(phonebook._phonebook)
which will yield in the console:
[PhoneRecord(firstname='matt', lastname='snow', telephone='25512521')]
[]
The simplified version of your question is, given code
records = []
records.append("matt")
print(records[0])
del records[0]
print(records[0])
why don't I get the following output
"matt"
None
Instead, you get an IndexError exception.
The reason is that you are accessing an element beyond the size of the list, and Python handles this by raising an exception rather than returning None.

blender python increment an integer

I'm pretty sure this has been answered, but I can't seem to locate it.
What I want is a python script for Blender that creates a custom tab that contains a button. When that button is pressed, it prints the value of an integer and increments it, so that when you press the button again, it shows an incremented value. Everything seems to work, except for the incremental part.
Here is the code I am using at the moment:
===
import bpy
from bpy.props import (IntProperty,)
from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup,)
def main(context):
my_number += 1
print(str(my_number))
class MySettings(PropertyGroup):
my_number = IntProperty(
name="Int property",
description="This is an integer.",
default = 1
)
class AddOne(bpy.types.Operator):
"""This is an operator"""
bl_idname = "op.add_one"
bl_label = "Increment by 1"
def execute(self, context):
main(context)
return {'FINISHED'}
class CreatePanel(bpy.types.Panel):
bl_label = "Render Setup Panel"
bl_idname = "OBJECT_PT_hello"
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'TOOLS'
bl_category = "Increment by 1 Tab"
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.operator("op.add_one")
def register():
bpy.utils.register_class(AddOne)
bpy.utils.register_class(MySettings)
bpy.utils.register_class(CreatePanel)
def unregister():
bpy.utils.unregister_class(AddOne)
bpy.utils.unregister_class(MySettings)
bpy.utils.unregister_class(CreatePanel)
if __name__ == "__main__":
register()
===
However, when I press the button 'Increment by 1', I get the following error:
"local variable 'my_number' referenced before assignment"
The point of this exercise is just to create an integer variable, store it, then increment it's value and print it out.
EDIT: I added the actual code, rather than an image of it.
The variable my_number is defined in the class MySettings - it can only be accessed through that class, whether that is inside a method that is also part of the class (self.my_number) or directly as a property that is part of an instance of the class (settings_instance.my_number).
You need to find a place outside of the operator and panel to store persistent variables. Adding a custom property to the object or scene types are common options. As you are showing your panel in the node editor, maybe you will want to add it to the material to keep it specific to a material, instead of global to the scene. You define these properties in the addons register() and remove them in unregister().
def register():
bpy.types.Scene.my_settings = bpy.props.PointerProperty(type=MySettings)
def unregister():
del bpy.types.Scene.my_settings
Then in your operator (or main() function) and your panel you can access the variable through the context paramater.
context.scene.my_settings.my_number += 1
Putting that together into your example, with a label to show the value -
import bpy
from bpy.props import (IntProperty,)
from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup,)
def main(context):
context.scene.my_settings.my_number += 1
print(str(context.scene.my_settings.my_number))
class MySettings(PropertyGroup):
my_number: IntProperty(
name="Int property",
description="This is an integer.",
default = 1
)
class AddOne(Operator):
"""This is an operator"""
bl_idname = "op.add_one"
bl_label = "Increment by 1"
def execute(self, context):
main(context)
return {'FINISHED'}
class CreatePanel(Panel):
bl_label = "Render Setup Panel"
bl_idname = "OBJECT_PT_hello"
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_category = "Increment by 1 Tab"
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.operator("op.add_one")
row = layout.row()
row.label(text='Value is: '+str(context.scene.my_settings.my_number))
def register():
bpy.utils.register_class(AddOne)
bpy.utils.register_class(MySettings)
bpy.utils.register_class(CreatePanel)
bpy.types.Scene.my_settings = bpy.props.PointerProperty(type=MySettings)
def unregister():
bpy.utils.unregister_class(AddOne)
bpy.utils.unregister_class(MySettings)
bpy.utils.unregister_class(CreatePanel)
del bpy.types.Scene.my_settings
if __name__ == "__main__":
register()
You will find blender.stackexchange a better place to ask for blender specific python help.
Generally this problem "local variable 'my_number' referenced before assignment" comes when you have 'my_number' variable in code and you had not initialized that variable at top of your code or before using that variable do one thing .
Declare my_number=0 and then do your calculation on my_number variable .

Python error 'NoneType' object has no attribute '<....>'

I'm having trouble with the following code:
import tweepy
from tweet import TweetBuilder
from libs.session import Session
class GameHandler:
open_sessions = []
def get_session(self, sessionname):
for session in GameHandler.open_sessions:
#FOLLOWING STATEMENT GOES WRONG
if session.roomname == sessionname:
return session
return None
def session_create(self, sessionname, owner_id, owner_name):
new = Session(sessionname, owner_id, owner_name).add_player(owner_id, owner_name)
GameHandler.open_sessions.append(new)
return TweetBuilder.new_session(sessionname, owner_name)
def session_join(self, sessionname, player_id, player_name):
session = self.get_session(sessionname)
if session != None:
session.add_player(player_id, player_name)
return TweetBuilder.join_session(session, player_name)
return ""
Also part of the Session class:
class Session:
def __init__(self, name, owner_id, owner_name):
#keep track of tweets
self.tweetid_start = None
self.tweetid_current = None
#game elements
self.roomname = name
#THIS LINE WORKS CORRECTLY
print(self.roomname)
self.players = []
self.currentround = None
self.roundnumber = 0
self.players.append(Player(owner_id, owner_name))
When I call session_create() everything works fine. The app runs Session.__init__(), the print statement prints self.roomname.
When I call session_join(), and session_join() calls get_session() problems arise. The for loop is supposed to iterate over the Session-array called open_sessions, but the moment it tries to access the Session-attribute called 'roomname' it gives me the following error:
'NoneType' object has no attribute 'roomname'
Why are my Session-objects suddenly NoneType?
Thanks in advance.
The problem is here:
new = Session(sessionname, owner_id, owner_name).add_player(owner_id, owner_name)
GameHandler.open_sessions.append(new)
By immediately calling add_player on the newly created Session, new is not the Session but the result of add_player, and whatever that does, it seems to return None. Thus you are adding a bunch of None objects to your open_sessions list. Use this instead:
new = Session(sessionname, owner_id, owner_name)
new.add_player(owner_id, owner_name)
GameHandler.open_sessions.append(new)
Or if you want to keep it the way it was, you could change your Session class to provide kind of a "fluent interface" and have add_player (and other methods) return self:
class Session:
...
def add_player(self, id_, name):
....
return self

Python global empty in class

I tried to get array parameters values in another class , where and why i wrong here ?
My second python file => myModule.py :
parameters = ([])
class MyFirstClass():
def __init__(self, params):
global parameters
parameters = params
class MySecondClass():
def __init__(self):
global parameters
print parameters
class MyClassWhereIHaveAProblem(http.HTTPFactory):
proto = .....
global parameters
print parameters **// array is empty here**
class start_server():
def __init__(self, params):
self.x_params = params[0] //ip
self.y_params = int(params[1]) //port
global parameters
parameters = params[2]
def start():
reactor.listenTCP(self.y, MyClassWhereIHaveAProblem(), interface=self.x)
My first python file => Handle.py :
from myModule import MyFisrtClass
from myModule import MySecondClass
from myModule import MyClassWhereIHaveAProblem
from myModule import start_server
class Handle():
def __init__(self):
params = (["vector1", "vector2"])
self.params = (["127.0.0.1","3128", params])
def go_to_another(self):
s = start_server(self.params)
s.start()
if __name__ == '__main__':
H = Handle()
H.go_to_another()
I tried to get array parameters values in another class , where and why i wrong here ?
It looks like you are simply:
forgetting the second set of double underscores for the special method names
making typos in the class names, you had "First" spelled "Fisrt"
you never did anything to use the MySecondClass class, so I initialized one in your main routine with: y = MySecondClass()
Handle.py:
#!/usr/bin/env python
from myModule import MyFirstClass
from myModule import MySecondClass
class Handle():
def __init__(self):
self.params = (["ele1","ele2","ele3"])
def go_to_another(self):
X = MyFirstClass(self.params)
if __name__ == '__main__':
H = Handle()
H.go_to_another()
y = MySecondClass()
myModule.py:
#!/usr/bin/env python
parameters = ([])
class MyFirstClass():
def __init__(self, params):
global parameters
parameters = params
class MySecondClass():
def __init__(self):
global parameters
print 'this should not be empty: %s' % parameters # array is no longer empty here
Output:
this should not be empty: ['ele1', 'ele2', 'ele3']
You have X = MyFisrtClass(self.params) instead of X = MyFirstClass(self.params)! Also __init should be __init__.
You are printing the variable when the class is first defined, but defining the variable when the class is initialized.
In Python, anything here:
class MyClass:
# here
Is evaluated as soon as the interpreter reaches that line-- not when the class is initialized.
Try running this code to get a better idea of what I mean:
my_global_var = 'set initially!'
class MyClass():
# Will print 'set initially', as this
# print statement is run before an instance of the
# class ever gets initialized,
print 'in class defn: %s' % my_global_var
def __init__( self ):
global my_global_var
my_global_var = 'set by the class instance!'
x = MyClass()
# Will print 'set by the class instance', as now
# you are printing it after the class has been initialized
# at least once
print 'after class is initialized: %s' % my_global_var
For your code:
# I have a problem here
class MyClassWhereIHaveAProblem(http.HTTPFactory):
#proto = .....
#global = parameters
print 'not set here, this is static: %s' % parameters #**// array is empty here**
def __init__(self):
print 'now it is set: %s' % parameters
But make sure you actually initialize one of those MyClassWhereIHaveAProblem.
From what I think is the documentation:
listenTCP(port, factory, backlog=50, interface='')
port a port number on which to listen
factory a twisted.internet.protocol.ServerFactory instance
backlog size of the listen queue
interface The local IPv4 or IPv6 address to which to bind; defaults to '', ie all IPv4 addresses. To bind to all IPv4 and IPv6 addresses, you must call this method twice.
So I think you want to simply do:
listenTCP(self.y_params, YourProblemClass(), interface=self.x_params)
Where:
- y_params is what you called the port, and
- x_params is what you called the address.
ok, I'll go to sleep :) I had also itinialise my object (logical), now everything is ok, Thanks for your time Alex.B, solution here:
class MyClassWhereIHaveAProblem(http.HTTPFactory):
proto = .....
def __init__(self):
http.HTTPFactory.__init__(self)
global parameters
print parameters

Using getattr to work with a method from another class

pI am working on a bit of code that does nothing important, but one of the things I am trying to make it do is call a function from another class, and the class name is pulled out of a list and put into a variable. Mind you I have literally just learned python over the last 2 weeks, and barely know my way around how to program.
What I believe that this should do is when getattr() is called, it will pass the attribute 'run_question' that is contained in the respective class with the same name as what is in question_type, and then pass it onto 'running_question'. I know there are probably better ways to do what I am attempting, but I want to know why this method doesn't work how I think it should.
#! /usr/bin/python
rom random import randrange
class QuestionRunner(object):
def __init__(self):
##initialize score to zero
self.score = 0
##initialize class with the types of questions
self.questiontypes = ['Addition', 'Subtraction', 'Division', 'Multiplication']
##randomly selects question type from self.questiontypes list
def random_type(self):
type = self.questiontypes[randrange(0, 4)]
return type
##question function runner, runs question function from self
def run_questions(self):
try:
question_type = self.random_type()
running_question = getattr(question_type, 'run_question' )
except AttributeError:
print question_type
print "Attribute error:Attribute not found"
else: running_question()
class Question(object):
pass
class Multiplication(Question):
def run_question(self):
print "*"
class Division(Question):
def run_question(self):
print "/"
class Subtraction(Question):
def run_question(self):
print "-"
class Addition(Question):
def run_question(self):
print "+"
test = QuestionRunner()
test.run_questions()
This outputs:
[david#leonid mathtest] :( $ python mathtest.py
Division
Attribute error:Attribute not found
[david#leonid mathtest] :) $
Which indicates that I am not getting the run_question attribute as I expect.
I should note that when I put the functions into the QuestionRunner class in the following way, everything works as expected. The main reason I am using classes where it really isn't needed it to actually get a good grasp of how to make them do what I want.
#! /usr/bin/python
from random import randrange
class QuestionRunner(object):
def __init__(self):
##initialize score to zero
self.score = 0
##initialize class with the types of questions
self.questiontypes = ['addition', 'subtraction', 'division', 'multiplication']
##randomly selects question type from self.questiontypes list
def random_type(self):
type = self.questiontypes[randrange(0, 4)]
return type
##question function runner, runs question function from self
def run_questions(self):
try:
question_type = self.random_type()
running_question = getattr(self, question_type)
except AttributeError:
exit(1)
else: running_question()
def multiplication(self):
print "*"
def division(self):
print "/"
def addition(self):
print "+"
def subtraction(self):
print "-"
test = QuestionRunner()
test.run_questions()
Any help on why this isn't working would be great, and I appreciate it greatly.
Any help on why this isn't working would be great, and I appreciate it greatly.
Ah, I have found out the missing concept that was causing my logic to be faulty. I assumed that I could pass the name of an object to getattr, when in reality I have to pass the object itself.

Categories