NameError: class name is not defined - python

I can't find why this piece of code won't work:
class Agent:
def hello(self, first_name):
return "Bien le bonjour" + first_name + "!"
agent = Agent()
print(agent.hello("Félix"))
I'm pretty sure to run it under python3 since i just follow a tutorial: https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-ubuntu-16-04
on how to create a local envirement for python3.
It return class Agent:
File "la_poo_avec_python-00_setup/model.py", line 4, in Agent
agent = Agent()
NameError: name 'Agent' is not defined
(my_env) noob#Flex:~/Noobi/prog/python3env/my_env$

Your code is correct, but I suspect there is something wrong with the indentation. This is how it should be
class Agent:
def hello(self, first_name):
return "Bien le bonjour" + first_name + "!"
agent = Agent()
print(agent.hello("Félix"))

The syntax you used sounds correct, but you need to make some corrections:
You need to separate your class from the main code as below because interpreter thinks that the line 4 and what is after that belong to your class:
class Agent:
def hello(self, first_name):
return "Bien le bonjour" + first_name + "!"
agent = Agent()
print(agent.hello("Felix"))
You may have to replace "l'accent aigu" with "e" in "Felix" as it can reflect you an error regarding using "Non-ASCII" character in the code.
Indentation is another error that I got from you code. So, please make sure it is organized properly before running.

The class needs an __init__ method. As other answers suggest, fix the indention and do this:
class Agent:
def __init__(self):
pass
def hello(self, first_name):
return "Bien le bonjour" + first_name + "!"

Related

Creating class instance based on user input

Suppose I had this class
class employee(object)
def __init__(self,name):
return self.name
def something(self):
pass
...
Leading to
if __name__== "__main__":
name = input("what is your name ")
user1 = employee(name)
user1.something()
...
I want the user1 instance to be the name inputted by the user so that I can have unique instances. How do I go about adding instances based on user input in the main section?
so if I run the program and inputted "tim", the outcome I would want is:
tim.name = "tim"
....
UPDATE
Seems like the above is unclear, let me try to explain using my actual code:
So I have this Spotify API:
class Spotify(object):
def __init__(self,user):
self.client_id = ''
self.client_secret = ''
def client_credentials(self):
pass
def get_header_token(self):
pass
...
In the end,
if __name__== "__main__":
user = input("Enter username ")
user = Spotify(user)
user.request_author()
...
I am trying to get the user variable to the input the user provides, such as if the user inputted "tim123", the user variable would also be tim123.
So I could perform:
tim123.name
Think my mind is going completely blank and there should be an easy solution for this. I am sure this is very unpractical but I don't know how I would do this in case I ever needed to.
Change
return self.name
to
self.name = name
if name== "main":
variable_name = raw_input("Enter variable name:") # User.
enters "tim123"
name = input("Enter Name")
globals()[variable_name] = employee(name)
tim123.name
Based on your comment, it sounds like you are looking for exec() or eval(). Link. My solution would be to do something like:
class employee(object):
def __init__(self,name):
self.name = name
name = input("what is your name ")
exec(f"{name} = employee('{name}')")
(and then you would access joe.name, if the user inputted joe, or bob.name, if the user inputted bob, etc.).
Alternatively, you could use locals() or globals()
Hope this helped!

Convert function into class Python

I'm having some issues regarding classes in Python because I'm in the need of refactoring some code.
The problem I'm facing is I have to refactor multiple similar scripts, so I decided to use Python classes but I have the following question
Say we have these two similar codes that need refactoring:
name = "Peter"
print(f"Bye! {name}"}
name.replace("e", "a")
print(f"Bye! {name} **replaced**"}
name = "Lisa"
print(f"Hi! {name}"}
name.replace("e", "a")
print(f"Hi! {name}"}
So a Python class:
class Greetings(object):
def __init__(self):
self.name = name
def say_hi_and_replace(self, name):
if name == "Lisa":
print(f"Hi! {name}"}
else:
print(f"Hi! {name}"}
self.name = self.name.replace("e", "a")
def say_goodbye(self, name):
if name == "Lisa":
print(f"Bye! {name}"}
else:
print(f"Bye! {name} **replaced**"}
Is there a better way to write this code? I'm sure there is.
Edit: Besides using ternary operators like Klaud suggested correctly.
def say_goodbye(self, name):
print(f"Bye! {name}"} if name == "Lisa" else print(f"Bye! {name} **replaced**"}
Edit: Sorry there was a typo in the "Bye!"
Thanks in advance.

NameError on initialization of class instance

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>

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.

Logging events in Python; How to log events inside classes?

I built (just for fun) 3 classes to help me log some events in my work.
here are them:
class logMessage:
def __init__(self,objectName,message,messageType):
self.objectName = objectName
self.message = message
self.messageType = messageType
self.dateTime = datetime.datetime.now()
def __str__(self):
return str(self.dateTime) + "\nObjeto de valor " + str(self.objectName) + " gerou uma mensagem do tipo: " + self.messageType + "\n" + self.message + "\n"
class logHandler():
def __init__(self):
self.messages = []
def __getitem__(self,index):
return self.messages[index]
def __len__(self):
return len(self.messages)
def __str__(self):
colecaoString = ""
for x in self.messages:
colecaoString += str(x) + "\n"
return colecaoString
def dumpItem(self,index):
temp = self.messages[index]
del self.messages[index]
return str(temp)
def append(self,log):
if isinstance(log,logMessage.logMessage):
self.messages.append(log)
else:
self.newLogMessage(log, "Wrong object type. Not a log message. Impossible to log.","Error")
def newLogMessage(self,objectInstance,message,messageType):
newMessage = logMessage.logMessage(objectInstance,message,messageType)
self.append(newMessage)
Here is my question:
Imagine i have other classes, such as Employee, and i want to log an event that happened INSIDE that class.
How can i do that without always passing a logHandler instance to every other class i want to log? My idea would be to pass a logHandler to every init function, and then use it inside it.
How can that be done, without doing what i specified?
How would it work with global logHandler? Is there a way to discover in runtime if there is a logHandler instance in the program, and use it to create the messages?
Thanks
Just create an instance of your classes in the module you posted. Then just import your logging module in every file you want to log from and do something like this:
yourloggingmodule.handler.newLogMessage(...)
Where handler is the name of the instance you created.
You could use the Borg pattern, meaning you can create local instances of your logger object and yet have them access the same state. Some would say that is elegant, others may say it's confusing. You decide. :)

Categories