I can't believe I am getting this error again and again ....

Here is my class:

class LANGUAGE:
    def __init__(self, val):
         self.val = val

    def Set(self):
         return self.val

Here is the function call:

if text in translate._languages:
         msg = "You have chosen the " + translate._languages[text]

         global NewLang
         newlang = LANGUAGE(text)
         NewLang = newlang.Set()
         blip.CreateChild().GetDocument().SetText(Trans.translate(msg, text,''))
         
    elif CMD_HELP in text:
         blip.CreateChild().GetDocument().SetText('''blabla bla ''')
    elif CREDITS in text:
         blip.CreateChild().GetDocument().SetText('''bla bla bla''')
    else:  
         lng = Detect(message.encode('utf-8'))
         newmsg = Trans.translate(message.encode('utf-8'), NewLang, '')
         doc.AppendText( '\n\n['+translate._languages[NewLang] + '] ' + newmsg)
         doc.AppendText( '\n\n[English] ' + Trans.translate(message.encode('utf-8'), 'en',''))

I am getting this error without using global NewLang

File "/base/data/home/apps/helloogoo/3.338280493491897811/helloogoo.py", line 83, in OnBlipSubmitted
newmsg = Trans.translate(message.encode('utf-8'), NewLang, '')
UnboundLocalError: local variable 'NewLang' referenced before assignment

And when I use global NewLang I get this error:

File "/base/data/home/apps/helloogoo/3.338280535936936291/helloogoo.py", line 83, in OnBlipSubmitted
newmsg = Trans.translate(message.encode('utf-8'), NewLang, '')
NameError: global name 'NewLang' is not defined

What should I do, it is killing me.

Edited 7 Years Ago by El Duke: n/a

I didnt test this but get rid of line 4 and replace line 6 with

global NewLang = newlang.Set()

Got this <type 'exceptions.SyntaxError'>: invalid syntax

Is the class in the same file as the function? Otherwise you need to import the module it is in:

from langFile import LANGUAGE

Or something like that.

You shouldn't need to do anything before. It depends on how the rest of the file goes, for example, where is translate._languages set? You could only need to declare it if you wanted to append to it. You certainly don't need to use 'global' because you are anyway in the globals namespace.

It seems like a strange way to assign to globals. Surely you would use globals() = "" assuming that 'text' is a string. It may just be that I am also a beginner in Python?

Is the class in the same file as the function? Otherwise you need to import the module it is in:

from langFile import LANGUAGE

Or something like that.

You shouldn't need to do anything before. It depends on how the rest of the file goes, for example, where is translate._languages set? You could only need to declare it if you wanted to append to it. You certainly don't need to use 'global' because you are anyway in the globals namespace.

It seems like a strange way to assign to globals. Surely you would use globals() = "" assuming that 'text' is a string. It may just be that I am also a beginner in Python?

I got no problems with importing, neither with the _languages set. The problem is with setting the Class member variable with a new value passed through its instance.

I have added a global variable at the beggening of the program and assigned an initial value to it

NewLang = ''

. This fixed the errors above, but the value is not being changed when calling the class member variable.

Isn't your problem down here:

#
else:
lng = Detect(message.encode('utf-8'))
newmsg = Trans.translate(message.encode('utf-8'), NewLang, '')
doc.AppendText( '\n\n['+translate._languages[NewLang] + '] ' + newmsg)
doc.AppendText( '\n\n[English] ' + Trans.translate(message.encode('utf-8'), 'en',''))

If this is called it means the first if was not true (and therefor the values were skipped) and therefor you cannot reference translate._language[NewLang]?

Isn't your problem down here:

#
else:
lng = Detect(message.encode('utf-8'))
newmsg = Trans.translate(message.encode('utf-8'), NewLang, '')
doc.AppendText( '\n\n['+translate._languages[NewLang] + '] ' + newmsg)
doc.AppendText( '\n\n[English] ' + Trans.translate(message.encode('utf-8'), 'en',''))

If this is called it means the first if was not true (and therefor the values were skipped) and therefor you cannot reference translate._language[NewLang]?

True But,

The user must go through the first if statement as part of the program, so the value entered will be passed to the class and stored into the variable var so whenever the else is proceeded, the NewLang will return the stored value in var through calling the function Set...

Or this is how I suppose its working mechanism.


Now my problem is that I get no errors BUT I get and and warning indicating that the var returns NULL. Although it passes the first if statement and show the message that "the language u are using is bla bla bla".

What do you think is the problem here? The value is not being stored into the variable var how to solve this ?

Did you try to put the global statement as the first statement in your method ?

I did, I even did have global variables file and imported it, it worked for sometime but when the number of users increased I thought using classes will keep the values unchanged, rather this method will create number of instances to all users. Am I doing wrong here ?

Ok guys, I will simplify the issue:

If we have a sample class like this:

class Test(object):
value = "Test1"

def __init__(self, value):
self.value = value

And in the main, I want to change the value "Test1" to something else - and keep it unchanged - until accessing the attribute again.

Now could someone please write down that call code, simple ain't it ?

You are writing code with random indentation. This ruins all your efforts in python. So take a standard rule like always using 4 space characters for indentation. You can set an option in your editor to do this.
Now if you want to change an attribute's value,

class Test(Object):
    start_value = "Test1" # better avoid the same name as the instances attributes
    def __init__(self):
        self.value = Test.start_value

def main():
    my_test = Test()
    print my_test.value
    my_test.value = "Something else"
    print my_test.value

if __name__ == "__main__":
    main()

Was that the question ?

Edited 7 Years Ago by Gribouillis: n/a

Are you sure that you wrote that right? You want to CHANGE the value "Test1" to something else - and keep it UNCHANGED? If you write a class:

class test:
    def __init__(self, value):
        self.value=value
    def OutPut(self):
        return self.value

The value of 'value' only changed on the next instance of the class.

For example:

w = Test(25)
x = Test(30)
strval = Test("duck")

print w.OutPut()

w.OutPut will still be 25? I am not sure that I understood what you are asking.

You are writing code with random indentation.

Don't worry about indentation, it is just ruined here.

Are you sure that you wrote that right? ....

of course I got what you mean yet here is the biggest dilemma in this (and I will use pseudo code here )


We have the class you Gribouillis or Namibnat wrote. Now I have the function that I wrote in my first post (the one that contains if elif statements),

Now as you've mentioned earlier Namibnat when checking the condition and going to the option else, there is no value to be passed to the translate function, or in other words:

If X equals 1
   Go and set Y (in the class attribute)
  elif X equals 2
    Show help
  elif X equals 3
    Show anything
  Else:
  Print ANY newly entered  number using the Y value we entered first.

You may ask what if the user's input didn't go through the first if I say the program is designed to ask the user to go through that.

Like:

Please Enter the colour:
If Variable = Colour {Go and set the class OR global variable to save that colour}:
If Variable = a word 
     If Variable = None 
          {Please Enter a valid colour}
     else :
     {Print the word with the colour stored in the class attribute or     global variable}

So my problem is that whenever the program goes through the else part, it founds nothing stored in the class attribute / global variable, although the user has entered a value previously.

So I guess it is about get/ set value ?

I hope I made it clear this time ?

My answer below is messy, but basically the questions have come up one at a time as I have tried to understand/re-write your code. Hopefully somewhere through the mess it points you to something you have not thought about.

Without a full program it is just to hard to understand what you are trying to do to clear up your issues. How does a program get to the else statement if the 'if' is true?

Globals works like a dictianary. I don't believe that you can say:
global x = 10

or even global x to mean something. Try it at the command line:

>>> global x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>>

To set a global value, you need to do something like this:

>>> print x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> globals()['x'] = 20
>>> print x
20
>>>

If/else blocks are not a namespace. You say function call, but I don't see a function. Perhaps that is why I don't understand what you are doing. Or are you referring to the reference to the method of the class instance.

You could do this:

globals()['NewLang'] = newlang.Set()

But if you wrote your code right there should be no reason at all to do that.

If all that is wrapped within a larger function, a function is a namespace, and values set, regardless of your use of global NewLang, will be within that namespace?

This may be really obvious, but why not put your code in a series of try/except blocks and debug by stepping through the code.

Where does your 'text' and 'translate._languages' come from? If text is none, your class will simply return none.

The user must go through the first if statement as part of the program, so the value entered will be passed to the class and stored into the variable var so whenever the else is proceeded, the NewLang will return the stored value in var through calling the function Set...

NO! Don't think of the class as a namepace, think of the object as a namespace. Your class is a blueprint, and therefore nothing is stored in the 'var' variable, only the class instance (the object) has a value for var.

What is 'translate.languages'? List, tuple, dict? I am just trying to invent a compete program with your issues in it. This line:

msg = 'You have choosen the " + translate._languages[text]

what is the text to the translate._languages.

And if the user will run through the 'if' block, why make an if block in the first place. Why not use try:

try:
    type(NewLang) = object...

or something like that. You could set a counter in there to check if it needs to be set later. Once set, use the counter to bypass that section.

Here is the best I could break it down to test. Just add the meat of your program in one bit at a time and see if you can keep writing tests or using try/excepts to narrow down your errors.

#! /usr/bin/python

# elduke.py

class LANGUAGE:
    def __init__(self, val):
        self.val = val
    def Set(self):
        return self.val

CMD_HELP, CREDITS = ('some', 'more stuff')


def doStuff(text):
    try:
        type(NewLang) == object
    except:
        msg = "You have choosen the " + text
        newlang = LANGUAGE(text)
        NewLang = newlang.Set()

    if CMD_HELP in text:
        blip = 'other text for testing'
    elif CREDITS in text:
        blip = 'this here text is for testing'
    else:        
        newmsg =  NewLang + " --> Just this to test"
        print newmsg


# Test cases
doStuff('here is some text')
print 'Test one done'
doStuff('here is more stuff')
print 'Test two done'
doStuff('here is other things')
print 'Test three done'

Okay, coffee time!

When you define the 'NewLang' class you have to use the exactsame cases as when you call it back later.

In my example the cases are the same. The newlang is an instance object, the Newlang is a variable build from the class method.

In my example everything works. I have tested the class, each method and checked all the variables. Now it is just a matter of El Duke building in the other stuff around it.

Namibnat, imagine that your function doStuff has to be executed more than once, actually many times. The 1st time it went through the try/except part and stored the variable. But next time is called the user didn't enter a language code, he started typing, how can I get the value I stored via the first call (try except).

In much simpler and identical example:

The program does translation so it goes like this:

1- The function called OnDocumentSubmission() This function is called everytime the user submits a document. Good so far ? OK

2- When the user submits the document, the contents of that document could be:
a- A language ID (for example fr for French)
b- or a symbol to show help (example -?)
c- or normal text to be translated IF and only IF the user has chosen a language code from step a.

So what I did is conditional statements that go like this (not a real code, so don't give attention about identations or syntax):

Class:

class LANGUAGE:
    def __init__(self):
        self.val = ''
    def Set(self, value):
      self.val = value
    def Get(self):
        return self.val

Function:

Current_Language = LANGUAGE()
def OnDocumentSubmission(text):
   if text in languages: # where languages is a list that contains all languages
      Current_Language.Set(text) # NOTE (1)
      msg = "You have chosen the " + translate._languages[text]

# here goes the other HELP condition which works perfectly

    else:
      LANG = Current_Language.Get() # NOTE (2)
      newmsg = Trans.translate(message.encode('utf-8'), LANG, '')

As I said, the function is being called EVERYTIME the user submits a document, and if we assume that he enters a language code like (fr) for example, I presumed that in NOTE (1), it will store the value in the class variable, and after that WHENEVER the user writes normal text, NOTE(2) will GET the variable from the class and assign it to LANG, then use it for translation UNTIL the user enters a new language code.

I must say an important thing here, I have tried to do it with GLOBAL variable, it worked perfectly UNTIL my application starts to receive more loads and users and then the global thing didn't work since users change the global value always, so they ruin other users' translation.

I thought to change it to classes and here I am, stuck.

P.S. I can't provide the code right now because 1) it is huge and 2) it is private and cannot be released now.

Thanks for your patience

I think it means that you should have a current language per user, and that text submission should come with a user ID, so that to each ID corresponds a language chosen by that user. It's the only way to do it if each user submits several texts.

I think it means that you should have a current language per user, and that text submission should come with a user ID, so that to each ID corresponds a language chosen by that user. It's the only way to do it if each user submits several texts.

What's the best practice to do so ? a class for user ID and another for Language for example ?

Well, how do you identify users ? may be an IP when they connect ? A good design would be something like

class User(Object):
    all_users = dict()

    def __init__(self, identity):
        User.all_users[identity] = self
        self.identity = identity
        self.language = "en"

    @staticmethod
    get(identity):
        if identity in User.all_users:
            return User.all_users[identity]
        else:
            return User(identity)

# To access a user from an identity, use User.get(identity)

def OnDocumentSubmission(identity, text):
    lang = User.get(identity).language
    # etc

Thank you Gribouillis, I might use this class design for sure but I have one more question that could solve all my problems.

In this pseudo code, how can I access the data stored in class attributes if I created an instance in one scope of a function and and tried to access from another scope of the function i.e.:

class for_language:
    language = value

Function:

Get data from document

if data = language code
    create class [U]instance[/U] to set the value in the language attribute in the class

else: 
   access the language value stored in the class from previous entry

The problem is that the IF statement is stuck in my mind as the only solution for this, I am not sure if there is another way to do it.

As I mentioned before, the first if statement is executed ONLY if the data received contained in the language set (like en, fr, it). And when it is set in the class variable, I want to access it to get the stored language code when the user enters any other data to be translated and the language code stored before.

I worked on this too much that I can't think of any solution to this, yet I guess it is simple one.

P.S. I can't create a class instance before entering the if statements because it will be re-created again and again each time he document is submitted (i.e this will reset the language value)

This will work if
1) You store the class instance in some global place
2) You don't have several users who call "Get data from document" randomly.

This will work if
1) You store the class instance in some global place
2) You don't have several users who call "Get data from document" randomly.

I do have a global place to store the class instance, but how to do so, I mean as an example, how to store a class instance ?

Nobody call get data from document, it is a robot and it uses DB to do so.

What about passing the class instance as a parameter to your function?

I can't change the parameters set in the function, I import it from the web. But my question still If I created a class instance in the first If and used it to set values in the class attributes, How can I get thoe values in another else or elif in the same function ? creating another instance is useless of course, Global variables are useless as well, it is the class and datastore method.

Now I have finished the first part which is storing to database through the class ,but getting those values is what confuses me.

Namibnat, imagine that your function doStuff has to be executed more than once, actually many times. The 1st time it went through the try/except part and stored the variable. But next time is called the user didn't enter a language code, he started typing, how can I get the value I stored via the first call (try except).

Just for this part, you should create a class, so that each instance of the class stores its own data.

Hi again, yes I am still working on it, I have used Database method to store temporary language variables, it worked but it is relatively so slow.

So I am back to normal classes, I have done some sample code to spare you the time you think what is my code about, so here is the sample that didn't work as I expected:

import xgoogle
from xgoogle.translate import *
translate = Translator().translate
_languages = { 
  'af': 'Afrikaans', 
  'sq': 'Albanian', 
  'am': 'Amharic', 
 #ETC...
};

class SUPER():
    language = None
    Text = ""

while True:
    try:
        value = raw_input("Please Enter Text to Translate: \n")
        print translate(value, lang_to=SUPER.language.encode('utf-8')
                        
    except:
        SUPER.language = ""
        newval = raw_input("Please Enter a language Value: \n")
        if newval in _languages:
           class SUB(SUPER):
               pass
        a = SUB()
        a.language = value
        print "You have chosen the: ", _languages[value]

The results I get are:

Please Enter a language Value:
 fr
You have chosen the:  French
Please Enter a language Value:
 Test
Traceback (most recent call last):
  File "/home/ma2moun/python-work/translate-test.py", line 124, in <module>
    print translate(value, lang_to=LANG).encode('utf-8')
  File "/home/ma2moun/xgoogle/translate.py", line 34, in translate
    raise TranslationError, "Language %s is not supported as lang_to." % lang_to
TranslationError: Language  is not supported as lang_to.

Check out the last line the results, this means that the new language value entered HAS NOT been stored into the SUPER.language.

This article has been dead for over six months. Start a new discussion instead.