global variable increment problem

This is the place for queries that don't fit in any of the other categories.

global variable increment problem

Postby lovecodecakes » Mon Feb 11, 2013 8:26 pm

Hi I'm trying my hands at python & I'm very very new to python. I'm trying to write an embedded c like code in python for a user I/p event based service as part of a bigger module. this one is called cobbler service for a shoe polish service.
After entering the code, it gives this:
O/P error

File "<ipython-input-47-1cb65066a5d4>", line 7
global inc+=1
^
SyntaxError: invalid syntax


Is this possible?:
Code: Select all
n=0
inc=0
def word():
    print 'Enter polish,skip s or done command:\t'
    command=raw_input()
    if command=='polish':
            global inc+=1


What is wrong?

Code: Select all
 n=0
inc=0
def word():
    print 'Enter polish,skip s or done command:\t'
    command=raw_input()
    if command=='polish':
            global inc+=1
            if global inc==1:
                return 'polish'
            else:
                return 'polish_again'
    elif command=='s': #for skip
            continue
    else:
            if command=='done':
                global inc-=1
                return 'done'
           
def chk_start():
    print 'continue start?:y/n \t'
    comm=raw_input()
    if comm=='y':
        return 'start'
    else:
        return 'stop'

def check_shoes():
    print 'Enter how many shoes?:\t'
    shoes=raw_input()
    while shoes<=0:
        print 'Enter min shoes.you entered 0'
        print 'Enter how many shoes?:\t'
        shoes=raw_input()
    if shoes>0:
        global n=shoes

def main(): #polish_main       
    total_cust=0
    cust=0
    cust_que=0
    pay=0   
    print 'Enter per shoes cost\n'
    x=raw_input
    chk_start()
    while(1):
        word()               
        if chk_start()=='start':
            if word()=='polish': #polish pressed by 1st twit
                check_shoes()
                cust+=1
            elif word()=='polish_again': #polish pressed by next twit while prev 1 gets finished
                check_shoes()
                cust_que+=cust
                print 'You are in Queue# '+str(cust_que)
            else:
                if word()=='done':
                    print 'to be paid by cust#'+str(cust_que)
                    cust_que-=1
                    pay=global n * x
                    print 'payment: '+str(pay)
                    pay=0
        elif chk_start()=='brk':
            total_cust=cust
            cust=0
            print 'Total customers: '+str(total)
            break
        else:
            if chk_start()=='stop':
                total_cust=cust
                cust=0
                print 'Total customers: '+str(total)
            break
        chk_start()
if __name__ == '__main__':
            main()
 

  File "<ipython-input-47-1cb65066a5d4>", line 7
    global inc+=1
               ^
SyntaxError: invalid syntax
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby stranac » Mon Feb 11, 2013 8:36 pm

Yes, it's possible.
But you can't declare your variable as a global and increase it at the same time.

Something like this should work:
Code: Select all
n=0
inc=0

def word():
    global inc
    print 'Enter polish,skip s or done command:\t'
    command=raw_input()
    if command=='polish':
        inc += 1


Using globals is generally not a good idea though.
It is much more common to pass the variable as an argument to the function, and return the modified value.
But I guess there are some cases where globals are acceptable...

Btw, I can't see from your code why you're modifying that global.
If you can explain, maybe we can suggest a better solution.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1245
Joined: Thu Feb 07, 2013 3:42 pm

Re: global variable increment problem

Postby metulburr » Mon Feb 11, 2013 8:39 pm

well the proper way is to declare the variable a global. At that point the variable in the function is accessing the global variable, and changes it accordinglly.

Code: Select all
...
def word():
    global inc
    print 'Enter polish,skip s or done command:\t'
    command=raw_input()
    if command=='polish':
            inc+=1
...



However not sure beacuse I never use global keyword.

The better way is to use classes or at least giving the function word() an argument and returning if needed
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1560
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: global variable increment problem

Postby lovecodecakes » Mon Feb 11, 2013 8:46 pm

@stranac Hey Thanks. Not intended to use global.
What is the way to access a variable from another function. like static in c, I want the variable to be accessed by other functions as well.
I had studied that there's something nonlocal, Im not sure but that is what I mean.

Modifying global because one function's condition makes some other condition that return value changes.
Is it possible & is it the way to like check say, "if chk_start()=='start':" where in chk_start function whatever it returns, say a string, this condition can check it??

Code: Select all
global inc+=1
            if global inc==1:
                return 'polish'
            else:
                return 'polish_again'


stranac wrote:Yes, it's possible.
But you can't declare your variable as a global and increase it at the same time.

Something like this should work:
Code: Select all
n=0
inc=0

def word():
    global inc
    print 'Enter polish,skip s or done command:\t'
    command=raw_input()
    if command=='polish':
        inc += 1


Using globals is generally not a good idea though.
It is much more common to pass the variable as an argument to the function, and return the modified value.
But I guess there are some cases where globals are acceptable...

Btw, I can't see from your code why you're modifying that global.
If you can explain, maybe we can suggest a better solution.
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby lovecodecakes » Mon Feb 11, 2013 8:48 pm

@metul how can I use classes here?

metulburr wrote:
The better way is to use classes or at least giving the function word() an argument and returning if needed
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby metulburr » Mon Feb 11, 2013 8:53 pm

keyword: global applies to changing vars in the modules namespace, whereas nonlocal changes vars in the enclosing "def's" local scope
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1560
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: global variable increment problem

Postby metulburr » Mon Feb 11, 2013 9:02 pm

@metul how can I use classes here?


I didnt really look at much of the code other than the "global" problem and word() function, but here would be a small example of converting that global keyword to a class

Code: Select all
class MyClass:
   def __init__(self):
      self.n = 0
      self.inc = 0
   def word(self, command):
      if command == 'polish':
         self.inc += 1
         
obj = MyClass()
print obj.inc
obj.word('polish')
print obj.inc
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1560
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: global variable increment problem

Postby stranac » Mon Feb 11, 2013 9:04 pm

Ok, a few more things to note after taking a closer look at your code:

You only have to make a variable global if you're changing it within a function.
You can access global functions normally, but assignment makes a local variable, unless told differently.

The raw_input() function takes an argument, which allows you to specify a prompt line which will be shown when the user is asked to print a value.
So instead of 'print whatever; raw_input()', you can write 'raw_input(whatever)'

Code: Select all
def chk_start():
    print 'continue start?:y/n \t'
    comm=raw_input()
    if comm=='y':
        return 'start'
    else:
        return 'stop'


This should probably be a function returning a boolean value(True/False)
You might write it like this:
Code: Select all
def chk_start():
    comm = raw_input('continue start?:y/n \t')
    return comm == 'y'


Also, you're calling word() and chk_start() all over the place, and this is definitely not something you want.
Only call the functions when you actually need to, and store the result.

You have 'x=raw_input' on one line, which doesn't actually call the function, but assigns it a new name.

It seems to me you only have that global there to check if it's the first time the function is called.
If that's the case, I'd call it outside of the loop for the first time, passing an argument, which will tell it it is indeed the first time it's called.
Then you could check for that argument, and not have to use a global.


That much from me for now.
There might be something I missed, so if something is still not clear, go ahead and post again.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1245
Joined: Thu Feb 07, 2013 3:42 pm

Re: global variable increment problem

Postby lovecodecakes » Mon Feb 11, 2013 9:15 pm

@stranac yea I forgot to erase that line
You have 'x=raw_input' on one line, which doesn't actually call the function, but assigns it a new name.


Also, you're calling word() and chk_start() all over the place, and this is definitely not something you want.
Only call the functions when you actually need to, and store the result.

I need to check in the while that's why I called those functions there. That's why I defined them in the first place to call them. Is there another way around?

stranac wrote:
Code: Select all
def chk_start():
    print 'continue start?:y/n \t'
    comm=raw_input()
    if comm=='y':
        return 'start'
    else:
        return 'stop'


This should probably be a function returning a boolean value(True/False)
You might write it like this:
Code: Select all
def chk_start():
    comm = raw_input('continue start?:y/n \t')
    return comm == 'y'




.
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby lovecodecakes » Mon Feb 11, 2013 9:16 pm

Thanks for that again, I'd totally forgotten, jumping from C to python makes skip classes!
So with classes I can access that particular variable from a different def func:??

metulburr wrote:
@metul how can I use classes here?


I didnt really look at much of the code other than the "global" problem and word() function, but here would be a small example of converting that global keyword to a class

Code: Select all
class MyClass:
   def __init__(self):
      self.n = 0
      self.inc = 0
   def word(self, command):
      if command == 'polish':
         self.inc += 1
         
obj = MyClass()
print obj.inc
obj.word('polish')
print obj.inc
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby metulburr » Mon Feb 11, 2013 9:23 pm

So with classes I can access that particular variable from a different def func:??

a different function inside the class, yes, via self.variable_name

However if you mean a global function, then no, you would have to plug it in via argument. Depends on your code.

If you go the class route: It would be advisable to read the docs on classes http://docs.python.org/2/tutorial/classes.html
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1560
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: global variable increment problem

Postby lovecodecakes » Mon Feb 11, 2013 9:34 pm

Thanks that helps, with everything. classes is what I should implement.

metulburr wrote:
So with classes I can access that particular variable from a different def func:??

a different function inside the class, yes, via self.variable_name

However if you mean a global function, then no, you would have to plug it in via argument. Depends on your code.

If you go the class route: It would be advisable to read the docs on classes http://docs.python.org/2/tutorial/classes.html
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby stranac » Mon Feb 11, 2013 10:36 pm

lovecodecakes wrote:I need to check in the while that's why I called those functions there. That's why I defined them in the first place to call them. Is there another way around?


Let's take a closer look at your while loop:
Code: Select all
while(1):
    word()               
    if chk_start()=='start':
        if word()=='polish': #polish pressed by 1st twit
            check_shoes()
            cust+=1
        elif word()=='polish_again': #polish pressed by next twit while prev 1 gets finished
            check_shoes()
            cust_que+=cust
            print 'You are in Queue# '+str(cust_que)
        else:
            if word()=='done':
                print 'to be paid by cust#'+str(cust_que)
                cust_que-=1
                pay=global n * x
                print 'payment: '+str(pay)
                pay=0
    elif chk_start()=='brk':
        total_cust=cust
        cust=0
        print 'Total customers: '+str(total)
        break
    else:
        if chk_start()=='stop':
            total_cust=cust
            cust=0
            print 'Total customers: '+str(total)
        break
    chk_start()


In this code, you're making 4 calls to both word() and chk_start() (the last call to chk_start() does nothing, btw)
You can do the same thing by only calling each function once, something like this:
Code: Select all
# a more common way to write 'while(1):'
while True:
    word_result = word()
    chk_start_result = chk_start()
    # now use the *_result values in the rest of your code

Of course, you would come up with better names for those variables.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1245
Joined: Thu Feb 07, 2013 3:42 pm

Re: global variable increment problem

Postby lovecodecakes » Tue Feb 12, 2013 7:50 am

No what you are doing is calling them once. if I need to call them again...and again..and again..? That's the reason it's made sequential. and in checking one of the conditions inside the loop, if' it's not executed, it gets executed again. The end function check_start() should call what is defined inside it again then again loop back to while(1)

stranac wrote:
lovecodecakes wrote:I need to check in the while that's why I called those functions there. That's why I defined them in the first place to call them. Is there another way around?


Let's take a closer look at your while loop:
Code: Select all
while(1):
    word()               
    if chk_start()=='start':
        if word()=='polish': #polish pressed by 1st twit
            check_shoes()
            cust+=1
        elif word()=='polish_again': #polish pressed by next twit while prev 1 gets finished
            check_shoes()
            cust_que+=cust
            print 'You are in Queue# '+str(cust_que)
        else:
            if word()=='done':
                print 'to be paid by cust#'+str(cust_que)
                cust_que-=1
                pay=global n * x
                print 'payment: '+str(pay)
                pay=0
    elif chk_start()=='brk':
        total_cust=cust
        cust=0
        print 'Total customers: '+str(total)
        break
    else:
        if chk_start()=='stop':
            total_cust=cust
            cust=0
            print 'Total customers: '+str(total)
        break
    chk_start()


In this code, you're making 4 calls to both word() and chk_start() (the last call to chk_start() does nothing, btw)
You can do the same thing by only calling each function once, something like this:
Code: Select all
# a more common way to write 'while(1):'
while True:
    word_result = word()
    chk_start_result = chk_start()
    # now use the *_result values in the rest of your code

Of course, you would come up with better names for those variables.
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby stranac » Tue Feb 12, 2013 11:18 am

Ok, then I guess I misunderstood something.
It just doesn't make sense(to me at least) to ask the user about heir choice repeatedly like this(in every loop):
  • Choose start, stop, or brk.
  • User says 'brk'.
  • Ok, that's not 'start'. Choose start, stop, or brk again.
  • Once again, the user says 'brk'.
  • Ok, that's not 'stop'. Choose start, stop, or brk again.
  • Once again, the user says 'brk'.
  • Ah, ok, you want to break
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1245
Joined: Thu Feb 07, 2013 3:42 pm

Re: global variable increment problem

Postby lovecodecakes » Tue Feb 12, 2013 2:14 pm

Code: Select all
elif chk_start()=='brk':

in
Code: Select all
def chk_start():
comm=raw_input('continue start?:y/n \t')
if comm=='y':
return 'start'
elif comm=='brk': NOTE: THIS I forgot to add!!
return 'brk'

else:
return 'stop'


applied here:
Code: Select all
elif chk_start()=='brk':
total_cust=cust
cust=0
print 'Total customers: '+str(total)
break

should make it break out ofthe while(1) loop, right?

also where can i learn more about things like:
if __name__ == '__main__':
main()
and other attributes??


stranac wrote:Ok, then I guess I misunderstood something.
It just doesn't make sense(to me at least) to ask the user about heir choice repeatedly like this(in every loop):
  • Choose start, stop, or brk.
  • User says 'brk'.
  • Ok, that's not 'start'. Choose start, stop, or brk again.
  • Once again, the user says 'brk'.
  • Ok, that's not 'stop'. Choose start, stop, or brk again.
  • Once again, the user says 'brk'.
  • Ah, ok, you want to break
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm

Re: global variable increment problem

Postby stranac » Tue Feb 12, 2013 6:11 pm

Yes, a break statement always breaks the loop nearest to it.
In your case, that is the while loop

lovecodecakes wrote:also where can i learn more about things like:
if __name__ == '__main__':
main()
and other attributes??

Well, that is just a trick to make a file that can be both imported and ran alone.
__name__ equals '__main__' only inside the file that was ran directly, otherwise it is the name of the module it is in.

For other things, the official python docs are a good resource, along with the official tutorial.
But some stuff you just have to learn through writing and reading code.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1245
Joined: Thu Feb 07, 2013 3:42 pm

Re: global variable increment problem

Postby lovecodecakes » Wed Feb 13, 2013 4:15 pm

Thanks, still requires lot of python practice....

stranac wrote:Yes, a break statement always breaks the loop nearest to it.
In your case, that is the while loop

lovecodecakes wrote:also where can i learn more about things like:
if __name__ == '__main__':
main()
and other attributes??

Well, that is just a trick to make a file that can be both imported and ran alone.
__name__ equals '__main__' only inside the file that was ran directly, otherwise it is the name of the module it is in.

For other things, the official python docs are a good resource, along with the official tutorial.
But some stuff you just have to learn through writing and reading code.
lovecodecakes
 
Posts: 56
Joined: Mon Feb 11, 2013 8:19 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 2 guests