This problem has been bugging me for the past few days. I've tried all sorts of different things to get it to work, studied my books, but nothing.

It goes like this:
Let's say I want my robot to recite the three laws of robotics. I can say, "Recite the three laws of robotics," and the computer will recognize my speech and recite them perfectly via TTS. Now, let's say that this time I want to ask my robot if it knows the three laws? My robot will say "Yes, I know them well. Would you like me to recite them for you?"
Right after it says this a variable in the script called LawRecite changes to True. I know it is changing to True in my script because I have this code snipet:

speaker.Speak ('Yes, I know them well. Would you like me to recite them for you?')
LawRecite = True
if LawRecite == True:
print 'Lets talk about the three laws of Robotics'

and that string in the end is coming up, so I know nothing's wrong there.

The problem is, when I say "Yes please," which has this code snipet attatched to it:

while LawRecite == True:
speaker.Speak(LOR1)
speaker.Speak(LOR2)
speaker.Speak(LOR3)
speaker.Speak(random.choice(LOR4))
else:
speaker.Speak('Yes please what?')

my robot just keeps asking, "Yes please what?" as if the value to LawRecite is still False (or something else).

Logically, if the value for LawRecite is True, it should recite strings LOR1-LOR4.
Anyone have any idea what's going on? Thanks.

Recommended Answers

All 9 Replies

Shouldn't it be ...

if LawRecite == True:
    speaker.Speak(LOR1)
    speaker.Speak(LOR2)
    speaker.Speak(LOR3)
    #speaker.Speak(random.choice(LOR4))
else:
    speaker.Speak('Yes please what?')

You may have more than one block of memory named "LawRecite". If you assign True in a loop or function then it is local to that loop/function and will be destroyed when you exit unless you return the value from the function. Change any variable names that are in a function and are the same as any outside the function/loop. That should clear things up. Also, "if True" and "while True" are redundant as vegaseat already pointed out. It should be

if LawRecite == True:
    print 'Lets talk about the three laws of Robotics'
    ## while LawRecite == True:   redundant
    speaker.Speak(LOR1)
    speaker.Speak(LOR2)
    speaker.Speak(LOR3)
    speaker.Speak(random.choice(LOR4))
else:
    speaker.Speak('Yes please what?')

If this doesn't help, please post more of the code in context.

Edit: This should definitely be a class. Then you can use self.LawRecite throughout and it will be the same variable. If the program is not using a class, someone here will probably help rearrange the code into the class structure.

Okay, I arranged it into a class, which I think I did right...

ThreeLaws = False

class LawRecite:
def Recite(self):
speaker.Speak(LOR1)
speaker.Speak(LOR2)
speaker.Speak(LOR3)
speaker.Speak(random.choice(LOR4))

LR = LawRecite()

Now if I ask my robot via speech recognition "Do you know the three laws of robotics?" it replies:

speaker.Speak ('Yes, I know them well. Would you like me to recite them for you?')
ThreeLaws = True

That part works fine. However, I've noticed that when I try to print if ThreeLaws is True, like so:

speaker.Speak ('Yes, I know them well. Would you like me to recite them for you?')
ThreeLaws = True
if ThreeLaws == True:
print 'Let's talk about the three laws of robotics'
else:
print 'Not right now'

I get an attribute error that says that 'NoneType' object has no attribute 'tb_lineno'.

Hmm...I think I understand what wooee meant by two blocks of memory with the same name. What I'm trying to do here is change the variable of ThreeLaws from True to False, but because I mention ThreeLaws = .... twice, that's causing it to be destroyed. Am I right? If so, what's the proper way to change a variable's value? Like a switch, I mean?

If it is a self.variable_name, then it is global throughout the class. I'm too tired to test this snippet so if there are other problems, post back.

class LawRecite:
   def __init__(self):
      self.ThreeLaws = False
      self.Recite()

   def Recite(self):
      ##speaker.Speak(LOR1)
      ##speaker.Speak(LOR2)
      ##speaker.Speak(LOR3)
      ##speaker.Speak(random.choice(LOR4))
      print "ThreeLaws original =", self.ThreeLaws

      self.ThreeLaws=True
      print "ThreeLaws changed =", self.ThreeLaws

      self.ThreeLaws=3
 
LR = LawRecite()
print "after changing to 3 =", LR.ThreeLaws

Thanks, wooee, I added the snippet in. I've encountered a problem though:

after changing to 3 =
Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\Users\Loren\Desktop\My Robots\Nina Verbal Raw Input.py", line 135, in <module>
    print "after changing to 3 =",  LR.ThreeLaws
AttributeError: LawRecite instance has no attribute 'ThreeLaws'

Is the program searching for a definition for "ThreeLaws"?

AttributeError: LawRecite instance has no attribute 'ThreeLaws'
Is the program searching for a definition for "ThreeLaws"?

It is searching for self.ThreeLaws in the LawsRecite class. I just ran the test snippet that I posted and it works fine so check the spellings for self.ThreeLaws and LawRecite on your end. Also, you will avoid potential problems if you don't use spaces in directory or file names. "C:\Users\Loren\Desktop\My Robots\Nina Verbal Raw Input.py",

Okay, guys, its starting to work. One last thing I'm trying to fix for this issue: The moment I start my script my robot recites the three laws without me saying anything. At first the script wouldn't start up because it said (LOR1) was not defined, so I moved the class LawRecite further down the script and the then the program would run.

My robot recites the three laws on its own the first time I start the script, but after that its working like I want it to.

Is there a way the class can be adjusted so that my robot will not speak the three laws until I ask it?

By the way, I just want to say thanks to all of you on Daniweb in my quest to learn Python and programming. You guys are teaching me a lot!

You are probably calling self.Recite without an if statement. An example

class LawRecite:
   def __init__(self):
      self.ThreeLaws = False
      ## only if ThreeLaws is True
      if self.ThreeLaws:
         self.Recite()

Thanks guys. I added the code snippet, tinkered around a bit, and it works great!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.