Re: [Tutor] global variables/constants versus volatile variables/constants
On 14/06/2014 20:37, S Tareq wrote: You appear to be having problems with your keyboard. Could you please resend your message, stating precisely what you wanted to say. Thank you. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
Thank you very much Allan! 100% clear. I thank each and every one of you who contributed to all my question on the above subject. A lot of things became very clear. May you all be well. On Sun, Jun 15, 2014 at 3:15 AM, Alan Gauld wrote: > On 14/06/14 13:53, diliup gabadamudalige wrote: > > Say if I have a lot of Lists, strings and variables used to carry data >> to and from various functions why can't I have a class with all these in >> it? >> > > You can but it should also have the functions that operate on the data > too. Thats the point of classes they link function and data together > so you don't need to pass lots of parameters around. If you have a class > that jusat holds lots of disparate data items you might as well just use a > list/tuple or dictionary. The value of classes is when you add behaviour or > methods to the mix. > > > > I thought on the lines of blood carrying various things to different >> organs in the body. >> > > But even there the blood has a distinct set of related items, it doesn't > carry the food to your stomach or the video signals from > your eye to your brain. And blood has operations - it can flow, > coagulate, increase/decrease red-cell count etc. It has > behaviour as well as data. > > > class Containers(): >> def __init__(self): >> self.last_selected_scale= "" >> self.scale_notes = "" >> self.arpeggionotes = "" >> self.handplayed_notes = [] >> self.MIDIscale = [] # the MIDI scale to be played is here >> self.play_MIDIscale = False >> self.play_MIDIarpeggio = False >> self.play_MIDI_scale_note = False >> self.play_MIDI_arpeggio_note = False >> self.MIDInote_inscale = 0 >> > > Now that could be a Tune... And it might have record/play/pause operations > > > > now say if I play the MIDI keyboard, I collect the notes played which >> will be appended to the list v.hanplayednotes. This will be done from a >> function which will scan the keyboard and append played notes to that >> list. >> > > But that could be a method of the Tune sub-class, MidiTune, which knows > how to record from a MidiSequencer object. > > > This is how I have used these variables, lists and strings in this >> program. So far it has run error free. >> > > The issue is not how to make it run - you can do that in assembler. > The issue is how easy is it to read and how easy os it to modify and fix > later. 80% of the cost of commercial software is in "maintenance" > The goal of professional software engineers is to reduce maintenance > costs even if that increases the initial 20% development budget. > > > Is this not correct or bad design. I know it is not the normal way of >> using class but is it wrong? >> > > Almost certainly, because it adds a layer of complexity for little or no > gain. > > Whereas adding the methods to the class improves the maintainability and > readability (and sometimes the performance, although that's a secondary > benefit). > > HTH > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Diliup Gabadamudalige http://www.diliupg.com http://soft.diliupg.com/ ** This e-mail is confidential. It may also be legally privileged. If you are not the intended recipient or have received it in error, please delete it and all copies from your system and notify the sender immediately by return e-mail. Any unauthorized reading, reproducing, printing or further dissemination of this e-mail or its contents is strictly prohibited and may be unlawful. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions. ** ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On 14/06/14 13:53, diliup gabadamudalige wrote: Say if I have a lot of Lists, strings and variables used to carry data to and from various functions why can't I have a class with all these in it? You can but it should also have the functions that operate on the data too. Thats the point of classes they link function and data together so you don't need to pass lots of parameters around. If you have a class that jusat holds lots of disparate data items you might as well just use a list/tuple or dictionary. The value of classes is when you add behaviour or methods to the mix. I thought on the lines of blood carrying various things to different organs in the body. But even there the blood has a distinct set of related items, it doesn't carry the food to your stomach or the video signals from your eye to your brain. And blood has operations - it can flow, coagulate, increase/decrease red-cell count etc. It has behaviour as well as data. class Containers(): def __init__(self): self.last_selected_scale= "" self.scale_notes = "" self.arpeggionotes = "" self.handplayed_notes = [] self.MIDIscale = [] # the MIDI scale to be played is here self.play_MIDIscale = False self.play_MIDIarpeggio = False self.play_MIDI_scale_note = False self.play_MIDI_arpeggio_note = False self.MIDInote_inscale = 0 Now that could be a Tune... And it might have record/play/pause operations now say if I play the MIDI keyboard, I collect the notes played which will be appended to the list v.hanplayednotes. This will be done from a function which will scan the keyboard and append played notes to that list. But that could be a method of the Tune sub-class, MidiTune, which knows how to record from a MidiSequencer object. This is how I have used these variables, lists and strings in this program. So far it has run error free. The issue is not how to make it run - you can do that in assembler. The issue is how easy is it to read and how easy os it to modify and fix later. 80% of the cost of commercial software is in "maintenance" The goal of professional software engineers is to reduce maintenance costs even if that increases the initial 20% development budget. Is this not correct or bad design. I know it is not the normal way of using class but is it wrong? Almost certainly, because it adds a layer of complexity for little or no gain. Whereas adding the methods to the class improves the maintainability and readability (and sometimes the performance, although that's a secondary benefit). HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On Friday, 13 June 2014, 12:45, Steven D'Aprano wrote: On Fri, Jun 13, 2014 at 12:51:25PM +0530, diliup gabadamudalige wrote: > Hi All! > Hope everyone is well. > > In my code there are many dictionaries and lists which are used in various > functions. Is it better/pythonic/efficient to have these inside the > function itself or declared at the beginning of the program in which case > they will be global? They are all read only. I understand that global > constants and variable have memory allocated to them but when declared > inside a function are created on the fly, used and discarded. Please > enlighten me further on this and correct me if i'm wrong. A good question. Depending on the size of these dictionaries and lists, worrying about efficiency here may be premature optimization. As they say: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." -- Donald Knuth "The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet." -- Michael A. Jackson "More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity." -- W.A. Wulf If these lists and dicts are small, say, fewer than a dozen items, the time to create and destroy them is probably trivial, especially if you construct them from constant literals. In that case, it's a matter of personal taste whether you prefer them as global constants or local to a function. But if it takes a long time to build the list, then you definitely should move it outside the function and perform the initialisation step only once: # This may take a while... PRIMES = [prime(i) for i in range(1, 101)] If your lists really are read-only, then you should consider turning them into tuples: # Not this: SOME_ITEMS = ["this", "that", "another"] # Better: SOME_ITEMS = ("this", "that", "another") One advantage of the tuple is that in recent versions of Python, the tuple may be compiled as a constant instead of being built at runtime. This is from Python 2.7: py> from dis import dis py> code = compile("x = [2, 4, 8]", "", "exec") py> dis(code) 1 0 LOAD_CONST 0 (2) 3 LOAD_CONST 1 (4) 6 LOAD_CONST 2 (8) 9 BUILD_LIST 3 12 STORE_NAME 0 (x) 15 LOAD_CONST 3 (None) 18 RETURN_VALUE py> code = compile("x = (2, 4, 8)", "", "exec") py> dis(code) 1 0 LOAD_CONST 4 ((2, 4, 8)) 3 STORE_NAME 0 (x) 6 LOAD_CONST 3 (None) 9 RETURN_VALUE -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On Sat, Jun 14, 2014 at 06:23:08PM +0530, diliup gabadamudalige wrote: > Say if I have a lot of Lists, strings and variables used to carry data to > and from various functions why can't I have a class with all these in it? Of course you *can*, but you *should not*. Read on... [...] > so I declare > > class Containers(): > def __init__(self): > self.last_selected_scale= "" > self.scale_notes = "" > self.arpeggionotes = "" etc. > now i initiate the class with > v=Containers() So now you write code where everything you use starts with "v.". What does the v. do? How does it help your programming? Answer: it doesn't. It just makes an extra two characters to type. Compare the code you would write if you just defined the variables directly: # Option 1 last_selected_scale = "" scale_notes = "" arpeggionotes = "" do_something(last_selected_scale) do_another_thing(scale_notes, arpeggionotes) # Versus option 2: class Containers(): def __init__(self): self.last_selected_scale = "" self.scale_notes = "" self.arpeggionotes = "" v = Container() do_something(v.last_selected_scale) do_another_thing(v.scale_notes, v.arpeggionotes) The two options do *exactly* the same thing, but Option 2 takes much more typing and reading. For what benefit? The only benefit is if you might have multiple Containers at the same time: keyboard_a = Container() keyboard_b = Container() do_something(keyboard_a.last_selected_scale) do_another_thing(keyboard_b.scale_notes, keyboard_b.arpeggionotes) Now you can play and record with two keyboards at the same time. (Perhaps you have four arms? *smile*) In this case, the extra cost of using a class pays for itself. Otherwise, it is just wasted effort. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
Thank you all for those great clarifications. I learnt a lot from these. My roots in programming are from the early 80s and with a gap of nearly 30 years till I restarted again last year in March with Python. :) So some of the new concepts like classes are a bit alien to me but I am catching on. I made a mistake by using the word variables on variables and constants both. My design structure would most probably be quite unconventional to most like Allen Gauld says. I am still learning and I like to jump into the deep end and learn to swim there and so far have managed to stay alive! :) I have gained immensely from these few emails and hope I can gain more knowledge to write better code. Say if I have a lot of Lists, strings and variables used to carry data to and from various functions why can't I have a class with all these in it? I thought on the lines of blood carrying various things to different organs in the body. One common container class. Containers for data exchange between all classes and functions. so I declare class Containers(): def __init__(self): self.last_selected_scale= "" self.scale_notes = "" self.arpeggionotes = "" self.handplayed_notes = [] self.MIDIscale = [] # the MIDI scale to be played is here self.play_MIDIscale = False self.play_MIDIarpeggio = False self.play_MIDI_scale_note = False self.play_MIDI_arpeggio_note = False self.MIDInote_inscale = 0 now i initiate the class with v=Containers() now say if I play the MIDI keyboard, I collect the notes played which will be appended to the list v.hanplayednotes. This will be done from a function which will scan the keyboard and append played notes to that list. This is how I have used these variables, lists and strings in this program. So far it has run error free. Is this not correct or bad design. I know it is not the normal way of using class but is it wrong? Thank you all in advance. -- Diliup Gabadamudalige http://www.diliupg.com http://soft.diliupg.com/ ** This e-mail is confidential. It may also be legally privileged. If you are not the intended recipient or have received it in error, please delete it and all copies from your system and notify the sender immediately by return e-mail. Any unauthorized reading, reproducing, printing or further dissemination of this e-mail or its contents is strictly prohibited and may be unlawful. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions. ** ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On 14Jun2014 11:21, Steven D'Aprano wrote: On Fri, Jun 13, 2014 at 09:42:34PM +0530, diliup gabadamudalige wrote: 2. Lists that are read only are better off being tuples? Possibly. It depends. As a general rule, tuples may be used for heterogeneous data, lists should be used for homogeneous data. To make this less clear, I would say this is a useful rule some of the time. It certainly isn't the only criterion one might use for choosing between a tuple and a list. What do I mean by this? This is a good use for a tuple: customer = (name, address, phone_number, status, balance) You have a fixed number of fields, and each field means something different (they are hetrogeneous). You should not use a list for something like this. Were I using the "heterogeneous data" rule I would be advocaing going to whole hog and using a "namedtuple" from the "collections" module. This has the advantage of giving each element of the tuple a nice name so that you can refer to "customer.address" instead of using magic indices like "customer[1]". That makes the code easier to read and easier to write. But if you're not using namedtuple-like attributes to access the tuple elements, then I would not be considering the "heterogeneous data" rule to be as relevant in my choice of tuple or list. There are some advantages to using a tuple as a frozen list, which can't have its values modified nor have its size changed. Specificly, if that is your intent and your code later tried to change the values (because it is buggy) then Python will raise an exception immediately, making it easier to find your mistake. If you stick to a list for this situation then the buggy changes will go ahead and the error will only be apparent much later when you get the wrong results. Fail early, fail often! Conversely, there are downsides to using tuples as frozen lists. The most obvious is that you can't add lists and tuples together, just lists and lists. If you need to add tuples and lists all the time then the surround fiddliness required may be enough to push you back to using lists throughout. Finally, another argument against mixing tuples and lists is simply that it may be early optimisation. Unless you're benefiting from the "you can't accidentally modify a tuple later" effect, just write it all with lists; it will be simpler. You can always come back later after the code is functioning correctly and think about tuples. Cheers, Cameron Simpson ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
Albert-Jan, I've been meaning to ask for a long time... I don't suppose you're hitting "Forward" rather than "Reply" in your posts are you? Because I've never seen replies from anyone else use the same style as your replies. Further comments below. On Fri, Jun 13, 2014 at 10:14:46AM -0700, Albert-Jan Roskam wrote: > Hmm, if I create the namedtuple with 'verbose=True' it *really* makes clear > why it took so much longer. > (what's '_property' btw? I know 'property' and the newer decorator wih the > same name, but not _property). _property is just property renamed. If you read the source code to namedtuple, you will see something like the line: _property = property or possibly: from builtins import property as _property That's likely done to make it a local variable, and so a little faster (although I don't know why the author bothered, it will make so little difference), or possibly to prevent clashes in case the caller defines a field name called "property". I'm not sure, but they are my guesses. [...] > v000 = _property(_itemgetter(0), doc='Alias for field number 0') > > v001 = _property(_itemgetter(1), doc='Alias for field number 1') > > v002 = _property(_itemgetter(2), doc='Alias for field number 2') [snip 97 more lines] Yes, thank you, we get the picture. No need to show 100 examples. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On Fri, Jun 13, 2014 at 09:42:34PM +0530, diliup gabadamudalige wrote: > Thank you all for these elaborate explanations. > so would it be wrong to assume that, > 1. the list or dict if 'large' and not mutated is better declared once in a > Class and used throughout the program? There is *no* advantage to writing this: class Foo: data = ['a', 'large', 'list'] result = function(Foo.data) instead of this: data = ['a', 'large', 'list'] result = function(data) Just dumping things into a class is not very helpful. You should ask yourself: * Does my code represent a "thing", like a string, or a web server, or a customer record? Then a class might be a good solution. * Does this thing have data and functions that go together? For example, a customer record might have data like Account Balance, and a function like update_account_balance. Then a class might be a good solution. * Could I have more than one of these "things" at the same time? For example, you obviously could have more than one string or customer record. Then a class is probably a good solution. If none of these things are true, then a class is probably a bad solution. > or > 2. Lists that are read only are better off being tuples? Possibly. It depends. As a general rule, tuples may be used for heterogeneous data, lists should be used for homogeneous data. What do I mean by this? This is a good use for a tuple: customer = (name, address, phone_number, status, balance) You have a fixed number of fields, and each field means something different (they are hetrogeneous). You should not use a list for something like this. This is a good use for a list: [value, another_value, a_third_value, ...] There is an arbitrary number of items, and each item represents the same kind of thing (they are homogeneous). Don't think of types, like "all the items are floats", but instead think "all the items are a person's height". As a micro-optimization, you might treat tuple as a frozen-list. That's not so unusual that you will confuse people by it, but it is a little unusual, and a matter of personal taste. > or > 3.the list or dict if 'large' and not mutated is better declared once as a > global variable and used throughout the program? If it's not mutated, it isn't really a *variable* is it? But yes, I would consider this the simplest thing that can work. This would be my preference. > The variables, lists carrying variables, and dict. carrying variables are > declared as a class. So why not include all above in the same class? > Varables and constans which are used throughout the program in one class > declared beofr the program enters the main executing loop? > wouldn't this be fast and the memory usage static up to a point (for all > declared items in the variables class)? I'm afraid I don't understand this paragraph. Can you try explaining more carefully please? (By the way: please trim unnecessary quoted text. Your email contained dozens of lines of double-quoted > > comments that had nothing to do with the questions you asked. If the comments aren't relevant, please delete them. Thank you.) -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On 13/06/14 19:20, diliup gabadamudalige wrote: I declare the following dict at the beginning of the program. KEY_SIGNATURES = {"C": [], "G": ["F"], "D": ["F", "C"], "A": ["F", "C", "G"], "E": ["F", "C", "G", "D"], "B": ["F", "C", "G", "D", "A"], "F#": now in the functions when ever I need to access i just use it. eg: sharps_or_flats = KEY_SIGNATURES[key] or I can create it like this class Variables(): def __init__(self, adv): self.KEY_SIGNATURES = {"C": [], "G": ["F"], now I call the class with v=Variables() now the same dict is v.Key_SIGNATURES my questions: which is better to use and why? As always there is no absolute answer. It depends on what you are doing in a wider context. However from your message you may be missing the point of the class solution. The pointy of a class is to bring together the variables *and the functions* that operate on those variables. So you should not be doing v.Key_SIGNATURES from functions outside the class, rather you should be defining your functions as methods of the class and inside those methods using self.Key_SIGNATURES Also a class called 'variables' is usually a bad design smell. The class should be called something meaningful in the context of your program. Something that represents the data and operations that you have captured within it. If you discover you have captured two unrelated concepts then split the class into two. That will encourage reuse but also make your code much more readable. Do both remain in memory(separately of course) till I exit the program once I run it? Will memory usage be the same? For data this small what happens in memory should be the least of your worries. Its much more important to get a design that is readable, maintainable and reliable. Only when you have proved there is a memory issue to solve do you need to start worrying about it. will the creation of the dict take the same time in both above? But if you are really worried about it use the timeit module or the profiler to find out, don't guess or rely on others guesses. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
Thank you all for these elaborate explanations. so would it be wrong to assume that, 1. the list or dict if 'large' and not mutated is better declared once in a Class and used throughout the program? or 2. Lists that are read only are better off being tuples? or 3.the list or dict if 'large' and not mutated is better declared once as a global variable and used throughout the program? The variables, lists carrying variables, and dict. carrying variables are declared as a class. So why not include all above in the same class? Varables and constans which are used throughout the program in one class declared beofr the program enters the main executing loop? wouldn't this be fast and the memory usage static up to a point (for all declared items in the variables class)? On Fri, Jun 13, 2014 at 6:38 PM, Steven D'Aprano wrote: > On Fri, Jun 13, 2014 at 05:10:28AM -0700, Albert-Jan Roskam wrote: > > > The other day I used collections.namedtuple and I re-initialized > > Record (see below) with every function*) call. Bad idea! It looks > > nicer because I did not need a global (and globals are baaad, mkay?), > > but it was *much* slower. I processed a log of a few million lines, I > > think. > > > > # bad --> time-consuming > > import collections > > > > def do_something_with(raw_record): > >Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in > range(100))) > >return Record(*raw_record.split()) > > Look at how much work you do here. First, you create a long string of > the form: > > "v000 v001 v002 v003 ... v099" > > representing 1000 v-digits names. Then you create a brand new Record > class that takes those 100 v-digits names as arguments. Creating that > class requires building a string, parsing it as Python code, and then > running it. (You're not expected to know that, but if you read the > source code for namedtuple you will see that's how it works.) So > creating that class is slow. Every time you call the function, it builds > a new "v000 ... v099" string, from scratch, then builds a new class, > also from scratch, and finally populates an instance of that class with > 100 values from the raw_record. > > Only that last step needs to be done inside the function. > > > > # better --> even though it uses a global variable > > import collections > > > > Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in > range(100))) > > [Aside: you may find it easier to debug problems with this if you give > the namedtuple class a sensible name, like "Record", rather than "_".] > > How is that a global *variable*? It's a global name, "Record", but it is > no more a "variable" than it would be if you did: > > class Record(tuple): > def __new__(cls, v000, v001, v002, ... , v099): > # code goes here > > @property > def v000(self): > return self[0] > > # likewise for v001, v002, ... v099 > # plus additional methods > > > namedtuple is a factory function which creates a class. Buried deep > within it is a class statement, just as if you had written the class > yourself. Normally, when you create a class, you don't treat it as a > variable, you treat it as a constant, like functions. That is no > different from classes you create with the class keyword. So "global > variables are bad" doesn't apply because it's not a variable. > > Even if it were a variable, what really matters is not that it gets > stored in the global scope, but whether or not it gets explicitly passed > to functions as arguments, or implicitly modified secretly behind the > scenes. For example: > > # Not bad > data = ["put", "stuff", "here"] > process(data) > do_things_with(data) > > > # Bad, for various reasons > data = ["put", "stuff", "here"] > process() # process what? > do_things_with() # What are we doing things with? > > > > In the first case, "data" may be stored in the global scope, but inside > each function it is treated as a regular local variable. Let's contrast > how one might operate on a second set of data in each case: > > # Too easy > process(some_other_data) > > > # Ouch, this is painful > save_data = data > data = some_other_data > process() > data = save_data # restore the previous value > > > Global variables aren't bad because Moses came down from the mountains > with a stone tablet that declares that they are bad. They're bad because > they cause excessive coupling, they operate by side-effect, they spoil > idepotent code, and they are implicit instead of explicit. > > > > > > def do_something_with(raw_record): > >return Record(*raw_record.split()) > > Much more sensible! > > > > -- > Steven > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Diliup Gabadamudalige http://www.diliupg.com http://soft.diliupg.com/ ** Th
Re: [Tutor] global variables/constants versus volatile variables/constants
Thank you all for these elaborate explanations. so would it be wrong to assume that, 1. the list or dict if 'large' and not mutated is better declared once in a Class and used throughout the program? or 2. Lists that are read only are better off being tuples? or 3.the list or dict if 'large' and not mutated is better declared once as a global variable and used throughout the program? The variables, lists carrying variables, and dict. carrying variables are declared as a class. So why not include all above in the same class? Variables and constants which are used throughout the program in one class declared before the program enters the main executing loop? wouldn't this be fast and the memory usage static up to a point (for all declared items in the variables class)? On Fri, Jun 13, 2014 at 9:42 PM, diliup gabadamudalige wrote: > Thank you all for these elaborate explanations. > so would it be wrong to assume that, > 1. the list or dict if 'large' and not mutated is better declared once in > a Class and used throughout the program? > or > 2. Lists that are read only are better off being tuples? > or > 3.the list or dict if 'large' and not mutated is better declared once as a > global variable and used throughout the program? > > The variables, lists carrying variables, and dict. carrying variables are > declared as a class. So why not include all above in the same class? > Varables and constans which are used throughout the program in one class > declared beofr the program enters the main executing loop? > wouldn't this be fast and the memory usage static up to a point (for all > declared items in the variables class)? > > > On Fri, Jun 13, 2014 at 6:38 PM, Steven D'Aprano > wrote: > >> On Fri, Jun 13, 2014 at 05:10:28AM -0700, Albert-Jan Roskam wrote: >> >> > The other day I used collections.namedtuple and I re-initialized >> > Record (see below) with every function*) call. Bad idea! It looks >> > nicer because I did not need a global (and globals are baaad, mkay?), >> > but it was *much* slower. I processed a log of a few million lines, I >> > think. >> > >> > # bad --> time-consuming >> > import collections >> > >> > def do_something_with(raw_record): >> >Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in >> range(100))) >> >return Record(*raw_record.split()) >> >> Look at how much work you do here. First, you create a long string of >> the form: >> >> "v000 v001 v002 v003 ... v099" >> >> representing 1000 v-digits names. Then you create a brand new Record >> class that takes those 100 v-digits names as arguments. Creating that >> class requires building a string, parsing it as Python code, and then >> running it. (You're not expected to know that, but if you read the >> source code for namedtuple you will see that's how it works.) So >> creating that class is slow. Every time you call the function, it builds >> a new "v000 ... v099" string, from scratch, then builds a new class, >> also from scratch, and finally populates an instance of that class with >> 100 values from the raw_record. >> >> Only that last step needs to be done inside the function. >> >> >> > # better --> even though it uses a global variable >> > import collections >> > >> > Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in >> range(100))) >> >> [Aside: you may find it easier to debug problems with this if you give >> the namedtuple class a sensible name, like "Record", rather than "_".] >> >> How is that a global *variable*? It's a global name, "Record", but it is >> no more a "variable" than it would be if you did: >> >> class Record(tuple): >> def __new__(cls, v000, v001, v002, ... , v099): >> # code goes here >> >> @property >> def v000(self): >> return self[0] >> >> # likewise for v001, v002, ... v099 >> # plus additional methods >> >> >> namedtuple is a factory function which creates a class. Buried deep >> within it is a class statement, just as if you had written the class >> yourself. Normally, when you create a class, you don't treat it as a >> variable, you treat it as a constant, like functions. That is no >> different from classes you create with the class keyword. So "global >> variables are bad" doesn't apply because it's not a variable. >> >> Even if it were a variable, what really matters is not that it gets >> stored in the global scope, but whether or not it gets explicitly passed >> to functions as arguments, or implicitly modified secretly behind the >> scenes. For example: >> >> # Not bad >> data = ["put", "stuff", "here"] >> process(data) >> do_things_with(data) >> >> >> # Bad, for various reasons >> data = ["put", "stuff", "here"] >> process() # process what? >> do_things_with() # What are we doing things with? >> >> >> >> In the first case, "data" may be stored in the global scope, but inside >> each function it is treated as a regular local variable. Let's contrast >> how one might operate on a second set of data in ea
Re: [Tutor] global variables/constants versus volatile variables/constants
- Original Message - > From: Steven D'Aprano > To: tutor@python.org > Cc: > Sent: Friday, June 13, 2014 3:08 PM > Subject: Re: [Tutor] global variables/constants versusvolatile > variables/constants > > On Fri, Jun 13, 2014 at 05:10:28AM -0700, Albert-Jan Roskam wrote: > >> The other day I used collections.namedtuple and I re-initialized >> Record (see below) with every function*) call. Bad idea! It looks >> nicer because I did not need a global (and globals are baaad, mkay?), >> but it was *much* slower. I processed a log of a few million lines, I >> think. >> >> # bad --> time-consuming >> import collections >> >> def do_something_with(raw_record): >> Record = collections.namedtuple("_", " > ".join("v%%03d" % i for i in range(100))) >> return Record(*raw_record.split()) > > Look at how much work you do here. First, you create a long string of > the form: > > "v000 v001 v002 v003 ... v099" > > representing 1000 v-digits names. Then you create a brand new Record > class that takes those 100 v-digits names as arguments. Creating that > class requires building a string, parsing it as Python code, and then > running it. (You're not expected to know that, but if you read the > source code for namedtuple you will see that's how it works.) So > creating that class is slow. Every time you call the function, it builds > a new "v000 ... v099" string, from scratch, then builds a new class, > also from scratch, and finally populates an instance of that class with > 100 values from the raw_record. > > Only that last step needs to be done inside the function. Hmm, if I create the namedtuple with 'verbose=True' it *really* makes clear why it took so much longer. (what's '_property' btw? I know 'property' and the newer decorator wih the same name, but not _property). In [1]: import collections In [2]: Record = collections.namedtuple("_", " ".join("v%03d" % i for i in range(100)),verbose=True) class _(tuple): '_(v000, v001, v002, v003, v004, v005, v006, v007, v008, v009, v010, v011, v012, v013, v014, v015, v016, v017, v018, v019, v020, v021, v022, v023, v024, v025, v026, v027, v028, v029, v030, v031, v032, v033, v034, v035, v036, v037, v038, v039, v040, v041, v042, v043, v044, v045, v046, v047, v048, v049, v050, v051, v052, v053, v054, v055, v056, v057, v058, v059, v060, v061, v062, v063, v064, v065, v066, v067, v068, v069, v070, v071, v072, v073, v074, v075, v076, v077, v078, v079, v080, v081, v082, v083, v084, v085, v086, v087, v088, v089, v090, v091, v092, v093, v094, v095, v096, v097, v098, v099)' __slots__ = () _fields = ('v000', 'v001', 'v002', 'v003', 'v004', 'v005', 'v006', 'v007', 'v008', 'v009', 'v010', 'v011', 'v012', 'v013', 'v014', 'v015', 'v016', 'v017', 'v018', 'v019', 'v020', 'v021', 'v022', 'v023', 'v024', 'v025', 'v026', 'v027', 'v028', 'v029', 'v030', 'v031', 'v032', 'v033', 'v034', 'v035', 'v036', 'v037', 'v038', 'v039', 'v040', 'v041', 'v042', 'v043', 'v044', 'v045', 'v046', 'v047', 'v048', 'v049', 'v050', 'v051', 'v052', 'v053', 'v054', 'v055', 'v056', 'v057', 'v058', 'v059', 'v060', 'v061', 'v062', 'v063', 'v064', 'v065', 'v066', 'v067', 'v068', 'v069', 'v070', 'v071', 'v072', 'v073', 'v074', 'v075', 'v076', 'v077', 'v078', 'v079', 'v080', 'v081', 'v082', 'v083', 'v084', 'v085', 'v086', 'v087', 'v088', 'v089', 'v090', 'v091', 'v092', 'v093', 'v094', 'v095', 'v096', 'v097', 'v098', 'v099') def __new__(_cls, v000, v001, v002, v003, v004, v005, v006, v007, v008, v009, v010, v011, v012, v013, v014, v015, v016, v017, v018, v019, v020, v021, v022, v023, v024, v025, v026, v027, v028, v029, v030, v031, v032, v033, v03
Re: [Tutor] global variables/constants versus volatile variables/constants
On Fri, Jun 13, 2014 at 05:10:28AM -0700, Albert-Jan Roskam wrote: > The other day I used collections.namedtuple and I re-initialized > Record (see below) with every function*) call. Bad idea! It looks > nicer because I did not need a global (and globals are baaad, mkay?), > but it was *much* slower. I processed a log of a few million lines, I > think. > > # bad --> time-consuming > import collections > > def do_something_with(raw_record): > Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in > range(100))) > return Record(*raw_record.split()) Look at how much work you do here. First, you create a long string of the form: "v000 v001 v002 v003 ... v099" representing 1000 v-digits names. Then you create a brand new Record class that takes those 100 v-digits names as arguments. Creating that class requires building a string, parsing it as Python code, and then running it. (You're not expected to know that, but if you read the source code for namedtuple you will see that's how it works.) So creating that class is slow. Every time you call the function, it builds a new "v000 ... v099" string, from scratch, then builds a new class, also from scratch, and finally populates an instance of that class with 100 values from the raw_record. Only that last step needs to be done inside the function. > # better --> even though it uses a global variable > import collections > > Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in > range(100))) [Aside: you may find it easier to debug problems with this if you give the namedtuple class a sensible name, like "Record", rather than "_".] How is that a global *variable*? It's a global name, "Record", but it is no more a "variable" than it would be if you did: class Record(tuple): def __new__(cls, v000, v001, v002, ... , v099): # code goes here @property def v000(self): return self[0] # likewise for v001, v002, ... v099 # plus additional methods namedtuple is a factory function which creates a class. Buried deep within it is a class statement, just as if you had written the class yourself. Normally, when you create a class, you don't treat it as a variable, you treat it as a constant, like functions. That is no different from classes you create with the class keyword. So "global variables are bad" doesn't apply because it's not a variable. Even if it were a variable, what really matters is not that it gets stored in the global scope, but whether or not it gets explicitly passed to functions as arguments, or implicitly modified secretly behind the scenes. For example: # Not bad data = ["put", "stuff", "here"] process(data) do_things_with(data) # Bad, for various reasons data = ["put", "stuff", "here"] process() # process what? do_things_with() # What are we doing things with? In the first case, "data" may be stored in the global scope, but inside each function it is treated as a regular local variable. Let's contrast how one might operate on a second set of data in each case: # Too easy process(some_other_data) # Ouch, this is painful save_data = data data = some_other_data process() data = save_data # restore the previous value Global variables aren't bad because Moses came down from the mountains with a stone tablet that declares that they are bad. They're bad because they cause excessive coupling, they operate by side-effect, they spoil idepotent code, and they are implicit instead of explicit. > def do_something_with(raw_record): > return Record(*raw_record.split()) Much more sensible! -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
- Original Message - > From: Steven D'Aprano > To: tutor@python.org > Cc: > Sent: Friday, June 13, 2014 1:45 PM > Subject: Re: [Tutor] global variables/constants versus volatile > variables/constants > > On Fri, Jun 13, 2014 at 12:51:25PM +0530, diliup gabadamudalige wrote: >> Hi All! >> Hope everyone is well. >> >> In my code there are many dictionaries and lists which are used in various >> functions. Is it better/pythonic/efficient to have these inside the >> function itself or declared at the beginning of the program in which case >> they will be global? They are all read only. I understand that global >> constants and variable have memory allocated to them but when declared >> inside a function are created on the fly, used and discarded. Please >> enlighten me further on this and correct me if i'm wrong. > > A good question. > > Depending on the size of these dictionaries and lists, worrying about > efficiency here may be premature optimization. As they say: > > > "We should forget about small efficiencies, say about 97% of > the time: premature optimization is the root of all evil." > -- Donald Knuth The other day I used collections.namedtuple and I re-initialized Record (see below) with every function*) call. Bad idea! It looks nicer because I did not need a global (and globals are baaad, mkay?), but it was *much* slower. I processed a log of a few million lines, I think. # bad --> time-consuming import collections def do_something_with(raw_record): Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in range(100))) return Record(*raw_record.split()) # better --> even though it uses a global variable import collections Record = collections.namedtuple("_", " ".join("v%%03d" % i for i in range(100))) def do_something_with(raw_record): return Record(*raw_record.split()) *) the function contained more code, of course! Albert-Jan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On Fri, Jun 13, 2014 at 12:51:25PM +0530, diliup gabadamudalige wrote: > Hi All! > Hope everyone is well. > > In my code there are many dictionaries and lists which are used in various > functions. Is it better/pythonic/efficient to have these inside the > function itself or declared at the beginning of the program in which case > they will be global? They are all read only. I understand that global > constants and variable have memory allocated to them but when declared > inside a function are created on the fly, used and discarded. Please > enlighten me further on this and correct me if i'm wrong. A good question. Depending on the size of these dictionaries and lists, worrying about efficiency here may be premature optimization. As they say: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." -- Donald Knuth "The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet." -- Michael A. Jackson "More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity." -- W.A. Wulf If these lists and dicts are small, say, fewer than a dozen items, the time to create and destroy them is probably trivial, especially if you construct them from constant literals. In that case, it's a matter of personal taste whether you prefer them as global constants or local to a function. But if it takes a long time to build the list, then you definitely should move it outside the function and perform the initialisation step only once: # This may take a while... PRIMES = [prime(i) for i in range(1, 101)] If your lists really are read-only, then you should consider turning them into tuples: # Not this: SOME_ITEMS = ["this", "that", "another"] # Better: SOME_ITEMS = ("this", "that", "another") One advantage of the tuple is that in recent versions of Python, the tuple may be compiled as a constant instead of being built at runtime. This is from Python 2.7: py> from dis import dis py> code = compile("x = [2, 4, 8]", "", "exec") py> dis(code) 1 0 LOAD_CONST 0 (2) 3 LOAD_CONST 1 (4) 6 LOAD_CONST 2 (8) 9 BUILD_LIST 3 12 STORE_NAME 0 (x) 15 LOAD_CONST 3 (None) 18 RETURN_VALUE py> code = compile("x = (2, 4, 8)", "", "exec") py> dis(code) 1 0 LOAD_CONST 4 ((2, 4, 8)) 3 STORE_NAME 0 (x) 6 LOAD_CONST 3 (None) 9 RETURN_VALUE -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
diliup gabadamudalige Wrote in message: > there are many dictionaries and lists which are used in various functions. Is it better/pythonic/efficient to have these inside the function itself or declared at the beginning of the program in which case they will be global? They are all read only. I understand that global constants and variable have memory allocated to them but when declared inside a function are created on the fly, used and discarded. > (Please use text mail to post here, not html. Html messages can cause several kinds of problems in a text mailing list. ) If they are read-only, you don't want to waste time recreating them over and over. Neither do you want to be repeating the code that initializes them. So make them either global or a class member, and be sure to name them all caps to signify they shouldn't be altered. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
CCing the tutor list. Please use ReplyAll when responding to the list. Alan Gauld Author of the Learn To Program website http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos > > From: diliup gabadamudalige >To: Alan Gauld >Sent: Friday, 13 June 2014, 9:32 >Subject: Re: [Tutor] global variables/constants versus volatile >variables/constants > > > >thanks Alan! > >in the program that i am writing i used a class called variables and declare >all variables i use in the program in the def __init__ section. >so all variables which otherwise would have to be declared as global so that >they can be modified by other functions are in a class. >Is this ok? >The strings, lists and dictionaries which are not read only are used as locals >in functions and classes. >If there is a string, list or dict. which is used in several functions is it >better to use a global or several locals? > > > >On Fri, Jun 13, 2014 at 1:25 PM, Alan Gauld wrote: > >On 13/06/14 08:21, diliup gabadamudalige wrote: >> >> >>In my code there are many dictionaries and lists which are used in >>>various functions. Is it better/pythonic/efficient to have these inside >>>the function itself or declared at the beginning of the program in which >>>case they will be global? >>> >> If you are sharing a set of data structures between several functions thats often a sign they should be in a class. The data then becomes the class instance attributes and the functions become the methods. >> >> >> >>global constants and variable have memory allocated to them but when >>>declared inside a function are created on the fly, used and discarded. >>> >> That's not usually the main issue when deciding for global/local. >>Its more about the maintainability of the code and the over >>use of side effects which makes the code difficult to read. >>If the data is read only then things are not so bad and globals >>can be an OK solution. >> >>hth >>-- >>Alan G >>Author of the Learn to Program web site >>http://www.alan-g.me.uk/ >>http://www.flickr.com/photos/alangauldphotos >> >>___ >>Tutor maillist - Tutor@python.org >>To unsubscribe or change subscription options: >>https://mail.python.org/mailman/listinfo/tutor >> > > > >-- > >Diliup Gabadamudalige > >http://www.diliupg.com >http://soft.diliupg.com/ > >** >This e-mail is confidential. It may also be legally privileged. If you are not >the intended recipient or have received it in error, please delete it and all >copies from your system and notify the sender immediately by return e-mail. >Any unauthorized reading, reproducing, printing or further dissemination of >this e-mail or its contents is strictly prohibited and may be unlawful. >Internet communications cannot be guaranteed to be timely, secure, error or >virus-free. The sender does not accept liability for any errors or omissions. >** > > > >___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables/constants versus volatile variables/constants
On 13/06/14 08:21, diliup gabadamudalige wrote: In my code there are many dictionaries and lists which are used in various functions. Is it better/pythonic/efficient to have these inside the function itself or declared at the beginning of the program in which case they will be global? If you are sharing a set of data structures between several functions thats often a sign they should be in a class. The data then becomes the class instance attributes and the functions become the methods. global constants and variable have memory allocated to them but when declared inside a function are created on the fly, used and discarded. That's not usually the main issue when deciding for global/local. Its more about the maintainability of the code and the over use of side effects which makes the code difficult to read. If the data is read only then things are not so bad and globals can be an OK solution. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
Steve, Thanks for all of this information. It seems the OP has sparked the kind of discussion that I had hopped for when I posted http://thread.gmane.org/gmane.comp.python.tutor/83251 Luckily though I did get an excellent response from Alan. http://thread.gmane.org/gmane.comp.python.tutor/83251/focus=83252 Still what you have posted here has been a good read, so, thank you. -- Jordan On Thu, Aug 22, 2013 at 12:18 PM, Steven D'Aprano wrote: > On 23/08/13 00:59, Andy McKenzie wrote: >> >> Isn't object orientation kind of the whole POINT of Python? From >> python.org: >> "Python is an interpreted, object-oriented, high-level programming >> language >> with dynamic semantics." > > > > Well, yes and no. > > Python is an object-oriented language in the sense that all of Python is > built using objects. Everything, including modules, functions, ints, > strings, yes, even classes themselves, are objects. > > But also no, in the sense that the code you write doesn't have to be written > using OOP techniques. Python is a multi-paradigm language in the sense that > you can write code using any of these styles: > > - object-oriented > > - functional > > - procedural > > - imperative > > - or a mix of all of the above. > > > -- > Steven > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On Thu, Aug 22, 2013 at 4:35 PM, Steven D'Aprano wrote: > Good question! And one that needs a long answer. Hey i just checked mail again... A big thank you for your responses, i will read all of them now.. im pretty my programs/designs will be much cleaner by the time i done. And yes i was talking about freenode:) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 23/08/13 00:59, Andy McKenzie wrote: Isn't object orientation kind of the whole POINT of Python? From python.org: "Python is an interpreted, object-oriented, high-level programming language with dynamic semantics." Well, yes and no. Python is an object-oriented language in the sense that all of Python is built using objects. Everything, including modules, functions, ints, strings, yes, even classes themselves, are objects. But also no, in the sense that the code you write doesn't have to be written using OOP techniques. Python is a multi-paradigm language in the sense that you can write code using any of these styles: - object-oriented - functional - procedural - imperative - or a mix of all of the above. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 23/08/13 00:12, Matthew Ngaha wrote: On Thu, Aug 22, 2013 at 2:52 PM, Chris Down wrote: I would doubt that anyone has told you "don't ever use classes", because that's nonsense; you've probably misread a dissuasion from that path in a single instance as applying more broadly than was intended. I am being totally honest here. I was very confused at the time and i said i didn't agree because it's what i had put so much effort into learning. They went on to say at some well known Python talks speakers have stated why using OOP (especially inheritance, but not excluding any others) is very bad design and the same thing can always be achieved without it. To be clear they said every use case OOP is the worst option. I asked what about GUIs which their design is strongly based around OOP? and they sad GUIs are badly designed to begin with so it proves the point about OOP. Well I agree with that last point. As far as "avoid OOP", I suspect they were thinking about this (in)famous video: http://pyvideo.org/video/880/stop-writing-classes Here is a counter-viewpoint: http://lucumr.pocoo.org/2013/2/13/moar-classes/ I think both have excellent advice. Many people do write unnecessary, complicated classes, and many people do unnecessarily lock up the inner workings of their code. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 22/08/13 23:52, Chris Down wrote: On 2013-08-22 14:43, Matthew Ngaha wrote: I don't feel my program needs a class. Also i have been told to stop using classes by some very experienced Python programmers on irc even though i don't see why. It's confusing being told different things. Well, if you want to store state, you should really be using a class. Depends on how much state and what you do with it. But fundamentally, if you want to store state, you should try very, very hard to *avoid* storing state unless you really need to. Or at least, make sure that there is a very strict demarcation between functions (or methods) which change that state, and those which do not. The ultimate aim is to avoid the bad parts of storing state, without necessarily going all the way to strict functional code: - reduce or eliminate side-effects wherever possible; - functions that have side-effects should do so only in well-understood and innocuous ways; - eliminate coupling between unrelated parts of code; - reduce coupling within related parts of code; - avoid action at a distance whenever possible. If you keep these aims in mind, the problem of global variables will solve itself. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 22/08/13 22:36, Matthew Ngaha wrote: My question is how many global variables did your last decent sized program have? Also please share any insight you have about them. I do try to avoid them, but is this always possible? Eiffel is another language that aims to eliminate global variables entirely. Here is an excellent article by the creator of Eiffel explaining why and how: http://archive.eiffel.com/doc/manuals/technology/bmarticles/joop/globals.html -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 22/08/13 22:36, Matthew Ngaha wrote: I'm always told to avoid using them. I read discussions on the python irc channel about them but honestly i feel there are some times where i can't avoid using them. Like where i want to keep track of a state variable in many different functions that may or may not alter its value and also not wanting any of the functions to return it to the caller. My question is how many global variables did your last decent sized program have? Also please share any insight you have about them. I do try to avoid them, but is this always possible? Good question! And one that needs a long answer. Yes, it is possible to avoid global variables. The proof of this, if you need any, is programming languages like Haskell which are purely functional languages, which means they don't have variables at all! Everything is a fixed value, usually created on the fly as needed, and thrown away when no longer required, but never modified[1]. Need to change something? You create a new value rather than modify an existing one. Haskell programmers are capable of writing large programs, and they do it without global variables. Functional programming is a very different paradigm, and one which takes a while to get used to. Haskell, which is pure functional, can be hard to wrap your head around, but Python is strongly influenced by Haskell and Lisp and could be considered a semi-functional language. If you've ever used list comprehensions or generator expressions, you've got a small taste of functional programming. Truth be told, you *could* write a large, non-trivial Python program in entirely functional style, but without a clever Lisp or Haskell compiler behind it, it would probably be just as slow to run as it would be hard to write. In Python, you should consider global variables to be something to be minimized rather than entirely avoided. In my experience, global variables are well-suited to dealing with user preferences and command-line options, and otherwise best avoided. But notice that user prefs and cmd line options aren't exactly *variables*, since they are typically set once, when the program starts up, and then never -- or at least hardly ever -- changed. Your functions may read their value, but they will not usually change their value. That brings us to why global variables are unsafe. They're not unsafe because they are global. Global constants, or almost-constants, are perfectly fine. They're unsafe because they vary unpredictably. They introduce coupling between functions which otherwise should be independent. For example, suppose we have a global variable and three functions, f, g, h, all of which read and write to the global under various situations. Now suppose you call f() -- the result you get depends on whether or not g() or h() have been called first, since they may change the global. And likewise, the result g() gives depends on whether or not f() or h() have been called, and similarly for h(). So instead of the result of f() depending in a nice clean way only on the arguments passed to it, instead it depends in a messy, convoluted, confusing way on the history of calls to separate functions that may have nothing to do with f(). You now have a tangle of couplings between functions: f depends on g and h g depends on f and h h depends on f and g Now imagine ten globals and twenty functions. Globals introduce "action at a distance". A function in one part of your program can reach out over a great distance and effect another function's result, just by changing a global. That's a bad thing and should be minimized or eliminated. So the real problem here is *state*. If your functions didn't depend on mutable state, but only on arguments passed to them, the problem of action at a distance would go away. This is where functional programming comes in: they eliminate mutable state altogether. Once a value is created, you can't change it, only throw it away and create a new one. In Python we don't necessarily go quite to that extreme, but it's still a good ideal to work towards. One mistake people have is to create a class just to hold global variables, and then think that they are virtuous because "it's not a global". So then they end up with something like this: class Everything_I_Need: def __init__(self): self.a = 1 self.b = 2 self.c = 3 # etc. everything = Everything_I_Need() f(everything) g(everything) h(everything) but of course this is just global variables in disguise, and still suffers from the same problem with strong coupling and action at a distance. [1] Never say never. Haskell actually does have a way to create modifiable values, but to get an idea of how people consider it, it is often called the "unsafePerformIO hack". -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail
Re: [Tutor] global variables
On 22/08/13 23:43, Matthew Ngaha wrote: On Thu, Aug 22, 2013 at 1:40 PM, Chris Down wrote: It sounds like you want to use a class. Why would you not just use a class if you want to store state? I don't feel my program needs a class. Also i have been told to stop using classes by some very experienced Python programmers on irc even though i don't see why. It's confusing being told different things. If you're talking about #python on Freenode, in my experience, they are rude and unpleasant people with an inflated sense of their own intelligence. But they possibly think the same about me ;-) -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On Thu, Aug 22, 2013 at 10:12 AM, Matthew Ngaha wrote: > On Thu, Aug 22, 2013 at 2:52 PM, Chris Down wrote: > >I would doubt that anyone has told you "don't ever use classes", because > > that's nonsense; you've probably misread a dissuasion from that path in a > > single instance as applying more broadly than was intended. > > I am being totally honest here. I was very confused at the time and i > said i didn't agree because it's what i had put so much effort into > learning. They went on to say at some well known Python talks speakers > have stated why using OOP (especially inheritance, but not excluding > any others) is very bad design and the same thing can always be > achieved without it. To be clear they said every use case OOP is the > worst option. I asked what about GUIs which their design is strongly > based around OOP? and they sad GUIs are badly designed to begin with > so it proves the point about OOP. > OK, I'm not a fantastic programmer in any language, but this strikes me as someone with an axe to grind giving bad advice to new programmers. Here are a few of the things that I see wrong with their statements: 1) For almost every option in programming, there's at least one case where it's a good idea, design-wise. Saying "in every use case OOP is the worst option" is absurd. Of course there are cases where it's not the worst option. There are also cases where it is. That goes for just about everything. 2) If they think OOP is always a bad idea, WHY are they using Python? Isn't object orientation kind of the whole POINT of Python? From python.org: "Python is an interpreted, object-oriented, high-level programming language with dynamic semantics." If they honestly believe that object oriented programming is always a bad idea, they really need to pick a different language. Perl, maybe, although even in Perl people are doing object oriented work. I have trouble believing that someone who believes OOP is inherently bad is a current high-level programmer in Python, unless they're trapped in a job they don't want to be doing. 3) Bad design in a product does not mean bad design in the tool used to build it. I've built some really terrible things out of wood with really nice tools. I've watched people use really nice drafting tools to design houses that would have been unusable for living in. Saying badly designed GUIs prove that OOP is bad is, frankly, illogical at best and stupid at worst. I strongly suspect that either the speaker they were listening to wasn't clear, or they weren't clear. Either that, or the speaker or whoever you were talking to mis-represented their ability level. Andy ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On Thu, Aug 22, 2013 at 10:12 AM, Matthew Ngaha wrote: > On Thu, Aug 22, 2013 at 2:52 PM, Chris Down wrote: >>I would doubt that anyone has told you "don't ever use classes", because >> that's nonsense; you've probably misread a dissuasion from that path in a >> single instance as applying more broadly than was intended. > > I am being totally honest here. I was very confused at the time and i > said i didn't agree because it's what i had put so much effort into > learning. They went on to say at some well known Python talks speakers > have stated why using OOP (especially inheritance, but not excluding > any others) is very bad design and the same thing can always be > achieved without it. To be clear they said every use case OOP is the > worst option. I asked what about GUIs which their design is strongly > based around OOP? and they sad GUIs are badly designed to begin with > so it proves the point about OOP. > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor Discussions among developers concerning the suitability of global variables have been going on at least since the 1970s. In my view they are the data equivalent of the 'goto' statement which has pretty much disappeared from acceptable coding practice. Think of them this way: Take a group of housemates who all use the same refrigerator. They all work different hours, spend time with different friends, and never talk to each other. When Bob buys beer, and later comes home to find there is no beer in the refrigerator it frustrates him. He doesn't even know who to complain to because anyone in the house could have taken it -- even a visitor. So, globals seem like a great idea to start with. But over time they cause trouble. I think you should write your code with globals if you think its best. Probably your code isn't that important, and it won't matter what you did in this program in a year or two. Anyway you will be learning. If your code is important for work, or some other purpose, over time it will be changed, and expanded, and problems will arise. Then you, or worse some one else, will have to figure out what is going wrong. That's where you will rue the day you sprinkled globals here and there. -- Joel Goldstick http://joelgoldstick.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 2013-08-22 15:12, Matthew Ngaha wrote: > I am being totally honest here. I was very confused at the time and i said i > didn't agree because it's what i had put so much effort into learning. They > went on to say at some well known Python talks speakers have stated why using > OOP (especially inheritance, but not excluding any others) is very bad design > and the same thing can always be achieved without it. To be clear they said > every use case OOP is the worst option. I asked what about GUIs which their > design is strongly based around OOP? and they sad GUIs are badly designed to > begin with so it proves the point about OOP. Were these "expert Python programmers" smoking crack cocaine at the time? pgpQLd06_zYdS.pgp Description: PGP signature ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On Thu, Aug 22, 2013 at 3:04 PM, Alan Gauld wrote: > On 22/08/13 13:36, Matthew Ngaha wrote: > Global variables in themselves are not the problem. > It's how they tend to get used that causes problems. > Globals that are only changed via a set of > dedicated functions are not topo much of a > problem - although they should probably be > bundled as a class (or module) > > Usually that should be in a class. A class represents > a set of operations using common data. Therefore shared > state would naturally fit in a class along with the > operations which depend on/modify that state. > Oh this makes a lot of sense. Sorry about disagreeing with Chris i now see that perhaps a class is definately the best choice for keeping a state variable. > Thats more problematic and usually a sign of a bad design. > Even if using global variables you should modify them > explicitly via return values of functions rather than > as hidden side-effects inside other functions. > > mystate = changestate(mystate, some, other, args) Yeah i have to agree about the bad design now i think about it. I didn't see the issues before reading this > It is possible but only by playing silly games with > semantics such as: > > class MyProgram >global1 = 0 >global2 = True > > [Or alternatively you can hide them inside a database.] > > Now technically there are no globals but in fact we are > just moving them inside the meaningless class and have > all the same potential issues with global side effects > etc. About the class variables, i have used them a lot without realising they had all the same side effects as global variables. Something i now have to try a different approach with. > In my experience there are usually a few globals required > for any meaningful program. It's not avoiding globals > completely that's important, it's being careful to use > them sensibly and with good adherence to the principles > of coupling and cohesion in the design. Thanks alot! This is definately a lot of food for choice and will help in my future decisions. I'm happy i asked this question as i can honestly say i had been developing some bad habbits. The responses have definately been helpful about program design and not just global variables. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On Thu, Aug 22, 2013 at 2:52 PM, Chris Down wrote: >I would doubt that anyone has told you "don't ever use classes", because > that's nonsense; you've probably misread a dissuasion from that path in a > single instance as applying more broadly than was intended. I am being totally honest here. I was very confused at the time and i said i didn't agree because it's what i had put so much effort into learning. They went on to say at some well known Python talks speakers have stated why using OOP (especially inheritance, but not excluding any others) is very bad design and the same thing can always be achieved without it. To be clear they said every use case OOP is the worst option. I asked what about GUIs which their design is strongly based around OOP? and they sad GUIs are badly designed to begin with so it proves the point about OOP. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 22/08/13 14:43, Matthew Ngaha wrote: On Thu, Aug 22, 2013 at 1:40 PM, Chris Down wrote: It sounds like you want to use a class. Why would you not just use a class if you want to store state? Local coding conventions or programmer skill levels may preclude it. I don't feel my program needs a class. But in this case it sounds like a class is the best solution. Why would you "feel" that you don't need a class when you have a situation where several functions share common state? That's almost the definition of a class. Also i have been told to stop using classes by some very > experienced Python programmers on irc Really? What reasons did they give. Unless they are talking about very specific circumstances that doesn't sound like good advice! It's confusing being told different things. Software engineering, like any branch of engineering, is about learning to use many different tools and selecting the best set for a problem. There are cases where classes are not in the best set, there are cases where many global variables are a good fit. But both of these are the exceptions to the rule and the engineer's job is to identify when a genuine exception exists and make the right choice. There is never a single right answer. Sorry, but that's life. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 22/08/13 13:36, Matthew Ngaha wrote: I'm always told to avoid using them. Global variables in themselves are not the problem. It's how they tend to get used that causes problems. Read-only global values - aka constants (so not really variables!) - are not an issue. Globals that are only changed via a set of dedicated functions are not topo much of a problem - although they should probably be bundled as a class (or module) if you have such features available. i can't avoid using them. Like where i want to > keep track of a state variable in many different functions Usually that should be in a class. A class represents a set of operations using common data. Therefore shared state would naturally fit in a class along with the operations which depend on/modify that state. You may then have a single global variable which is the instance of that class. also not wanting any of the functions to return it to the caller. Thats more problematic and usually a sign of a bad design. Even if using global variables you should modify them explicitly via return values of functions rather than as hidden side-effects inside other functions. mystate = changestate(mystate, some, other, args) My question is how many global variables did your last decent sized program have? I usually have not more than a half dozen plus one per thousand lines of code. So in a 10,000 line program I'd expect to have less than 16 in total (actually I'd hope less than 10!). And many of those would be instances of classes. I would not expect to have more than one or two fundamental typed globals (ints, strings, bools etc), if any. Also please share any insight you have about them. I do try to avoid them, but is this always possible? It is possible but only by playing silly games with semantics such as: class MyProgram global1 = 0 global2 = True def __init__(self, lots, of, args, self.inst1 = # initialise program runtime vars def run(self) # my program code all goes here # and accesses the class level globals and instance # level runtime and state values if __name__ = __main__": MyProgram(args).run() [Or alternatively you can hide them inside a database.] Now technically there are no globals but in fact we are just moving them inside the meaningless class and have all the same potential issues with global side effects etc. In my experience there are usually a few globals required for any meaningful program. It's not avoiding globals completely that's important, it's being careful to use them sensibly and with good adherence to the principles of coupling and cohesion in the design. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 2013-08-22 14:43, Matthew Ngaha wrote: > I don't feel my program needs a class. Also i have been told to stop > using classes by some very experienced Python programmers on irc even > though i don't see why. It's confusing being told different things. Well, if you want to store state, you should really be using a class. What has made you think that your program doesn't "need a class"? There's no "need", there's just what's best suited to your problem case (which you have not made clear, so nobody can comment on it). No experienced Python programmers are going to universally tell you not to use classes, likewise, no experienced Python programmers are going to universally tell you to use them all the time. It's a matter of context and suitability, which is entirely dependent on what it is that you are coding in the first place. I would doubt that anyone has told you "don't ever use classes", because that's nonsense; you've probably misread a dissuasion from that path in a single instance as applying more broadly than was intended. pgpKOAYswETAY.pgp Description: PGP signature ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On Thu, Aug 22, 2013 at 1:40 PM, Chris Down wrote: > It sounds like you want to use a class. > Why would you not just use a class if you want to store state? I don't feel my program needs a class. Also i have been told to stop using classes by some very experienced Python programmers on irc even though i don't see why. It's confusing being told different things. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] global variables
On 2013-08-22 13:36, Matthew Ngaha wrote: > I'm always told to avoid using them. I read discussions on the python > irc channel about them but honestly i feel there are some times where > i can't avoid using them. Like where i want to keep track of a state > variable in many different functions that may or may not alter its > value and also not wanting any of the functions to return it to the > caller. It sounds like you want to use a class. > My question is how many global variables did your last decent sized > program have? Also please share any insight you have about them. I do > try to avoid them, but is this always possible? I don't have any global variables in any of my projects, and I've been programming Python in some capacity for almost 8 years now. Why would you not just use a class if you want to store state? pgp8g3wmh7NcT.pgp Description: PGP signature ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global Variables
On 22/06/13 18:09, Jack Little wrote: Is there a way to keep a global throughout multiple def statements? Oh, a further thought! Perhaps you mean something like this? x = 42 # Global value. def function_one(): global x # Define it once. code using global x goes here... def function_two(): # x is already declared global, so no need to do it again code using global x goes here... # Run the code. function_one() function_two() If that's what you mean, the answer is, thank goodness, no, there is no way to do this! Relying on global variables is, as a general rule, a good way to end up with unmaintainable, buggy code that cannot easily be tested and is frustrating to debug. Sixty years of experience in programming has lead to the conclusion that global variables are best avoided. To be precise, it is not so much the *global variable* part that is harmful, but the reliance on side-effects in the code: calling a function invisibly gets input from a global, and outputs to a global. We can get better, safer, easier to understand code by using explicit input arguments and a return result: def function_one(arg): code using argument "arg" goes here... return result of calculation def function_two(arg): code using "arg" goes here... return result of calculation # Run the code. x = 42 x = function_one(x) y = function_two(x) In this case, we can see that the value of x is passed to function_one as input. There's no need to guess that it magically uses some global variable. We can also see that the result of that calculation is stored back into x. Then in the next line, the new value of x is passed to function_two as input, and the result is stored in a different variable, y. Although there is a very slight increase in the amount of typing, with practice and experience this leads to more maintainable, more easily debugged code. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global Variables
On 22/06/13 18:09, Jack Little wrote: Is there a way to keep a global throughout multiple def statements? I don't understand the question. The only way to *not* keep a global through multiple def statements is if you delete the global: x = 1 # Global. def function_one(): code goes here... def function_two(): code goes here... del x def function_three(): code goes here... But I suspect that this is not what you mean. Can you explain in more detail what you mean? -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global Variables
> > This looks for or creates an nl in your module. > Beg to differ- global will not create it. > > def f():global a > What it does is alert the compiler that assignment to the > variable will make it global. Thats what I meant, that an assignment to a variable marked as global inside a function will create the variable in the global namespace rather than in the local one, if it does not already exist. But I didn't explain it very well... Alan G.___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global Variables
Alan Gauld wrote: dname() def dname(): global nl This looks for or creates an nl in your module. Beg to differ- global will not create it. def f():global a ... >>> a Traceback (most recent call last): File "", line 1, in NameError: name 'a' is not defined What it does is alert the compiler that assignment to the variable will make it global. -- Bob Gailer Chapel Hill NC 919-636-4239 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global Variables
On Fri, Nov 20, 2009 at 4:44 PM, Joseph Fennell wrote: > My apologies yes these are in seperate files, > -- > main.py > --- > cHandler.execute("SELECT * FROM table") > > #sets results from above to nl > > nl = cHandler.fetchall() > > dn = raw_input("User input: ") > > nl2 = [] > > modules.py > -- > dname() > > def dname(): > global nl > for ndc in nl: > if ndc[1] == dn: > nl2.append(ndc,) > else: > continue > # > > main.py > > tuple(nl2) = nl2 > Just FYI, this line does nothing. In fact I think that it is invalid syntax. What you probably mean to say is nl2 = tuple(nl2) I.E. turn nl2 into a tuple and assign it back to nl2. > > > modules.py > > qtysrch() > # > def qtysrch(): > global nl2 > for ndc in nl2: > if ndc[7] == 0: > continue > else: > print ndc > > and the major problem I'm having is in both modules when the code is ran, > an error is returned when it attempts to pass 'dname()' that 'nl' is not > defined. > > Yes, that is because this is not how you are supposed to code in Python. In general, using global variables should be avoided. There are specific cases where it's acceptable, but you should assume your case is not one of them. You should read through a tutorial such as Alan Gauld's tutorial, so you can understand the 'functionality' of functions (pardon the pun.) Essentially, what you're doing now is using functions to modify variables DIRECTLY. What you need to to is use functions that take in a value or values, and output a value or values, but do not modify variables in the global scope. Also, if a function prints anything or modifies any outside sources, it should not have a return value. For example, list.sort() returns None because it sorts the list in-place. However, list.split() returns the splitted list, and does not modify the original. You should try to come up with more descriptive variable names. It should be clear to me what your code does even though I have never seen it before. What do 'nl' and 'ndc' and 'nl2' refer to? I've changed your variable names to more descriptive versions, but it may not be completely accurate as I'm not sure of your code intent. Here's a cheat sheet of how you should rewrite these functions (also take note of the way I modified your 'if' statements. Your 'continue' branches are not necessary): -- order.py -- def display_qtys(order): for lineitem in order: if lineitem[7] != 0: #check for a nonzero quantity print lineitem def search(order, query): results = [] for lineitem in order: if lineitem [1] == query: results.append(lineitem) return results -- Note that I personally would actually write the search function like this: -- def search(order, query): return [lineitem for lineitem in order if lineitem[1] == query] -- List comprehensions can be a bit scary when you're first starting out. Once you get used to them, you really start to like them though. Then your main program will look like this: --- main.py -- import order # some import for the cHandler routine, wherever that comes from... cHandler.execute("SELECT * FROM table") results = cHandler.fetchall() query = raw_input("Please enter item to search for: ") filtered_results = order.search(results, query) #display the results order.display_qtys(filtered_results) -- I strongly recommend reading more tutorials about proper function definition, in the long run (and whenever you have a large scale project to work on, or even a medium-scale one, at that) handling values between functions in global variables is going to soon become a huge headache. Hope that helps, and let me know if anything is unclear! -Luke P.S. please use the REPLY-ALL because when you use regular reply it does not send to the list as well, it just sends it directly to me. Sorry I can't be more specific with the exact error returned as I'm not near > a machine that I have python on. > > > Thanks. > > > > On Fri, Nov 20, 2009 at 3:52 PM, Luke Paireepinart > wrote: > >> >> >> On Fri, Nov 20, 2009 at 2:51 PM, Joseph Fennell < >> josephfennells...@gmail.com> wrote: >> >>> Quick introduction, I'm Joseph Fennell, and I've been playing with >>> python for the past 6 years (primarily in the interpreter) and have finally >>> gotten started on a full project and I've run into a small problem. I have >>> defined some modules, and when I import them into the page I want to use >>> them on after I run the program it tells me the variable I'm trying to pass >>> through them is not defined. >>> >>> I assume that it's because the variable is considered local and the >>> imported functions are not technical
Re: [Tutor] Global Variables
"Joseph Fennell" wrote I assume that it's because the variable is considered local and the imported functions are not technically local to that document. global in Python means "in the same module" not global across all modules You are best to pass data into functions as arguments and to pass it back out as return values. cHandler.execute("SELECT * FROM table") nl = cHandler.fetchall() dn = raw_input("User input: ") nl2 = [] dname() def dname(): global nl This looks for or creates an nl in your module. But you don't need the statement because you are not assigning to nl, merely reading it so Python would find the global variable if it existed. for ndc in nl: if ndc[1] == dn: nl2.append(ndc,) else: continue You don't need the else: continue. Python will do that by default. You could abbreviate your code usuing a list comprehension: def dname(nl, dn): return [ ndc for ndc in nl if ncd[1] == dn ] and call it with nl2 = dname(nl, dn) # tuple(nl2) = nl2 I think you are confused here. You could(should?) just do nl2 = tuple(nl2) Assuming you want to convert the list in nl2 into a tuple and store the result in nl2? If not then I am confused! qtysrch() # def qtysrch(): global nl2 for ndc in nl2: if ndc[7] == 0: continue else: print ndc Again you don't need the global since you are only rading nl2. And again it would be better practice to pass nl2 into the function as an argument. Any help I can get with this problem would be greatly appreciated. HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global Variables
On Fri, Nov 20, 2009 at 2:51 PM, Joseph Fennell wrote: > Quick introduction, I'm Joseph Fennell, and I've been playing with python > for the past 6 years (primarily in the interpreter) and have finally gotten > started on a full project and I've run into a small problem. I have defined > some modules, and when I import them into the page I want to use them on > after I run the program it tells me the variable I'm trying to pass through > them is not defined. > > I assume that it's because the variable is considered local and the > imported functions are not technically local to that document. > > The code is to pass the contents of a database through to filter by name > and quantity and as follows > The example code you provided is very confusing. > > = > > cHandler.execute("SELECT * FROM table") > > #sets results from above to nl > > nl = cHandler.fetchall() > > dn = raw_input("User input: ") > > nl2 = [] > > dname() > > def dname(): > global nl > for ndc in nl: > if ndc[1] == dn: > nl2.append(ndc,) > else: > continue > # > tuple(nl2) = nl2 > > qtysrch() > # > def qtysrch(): > global nl2 > for ndc in nl2: > if ndc[7] == 0: > continue > else: > print ndc > Are you saying these are in separate files? Please repost the code in a more logical fashion. Eg. --- ~~~ somemodule.py --- def foobar(): print "foobar!" --- ~~~ main.py --- import somemodule somemodule.foobar() --- This will make it much easier to understand your question, because I don't see how the code sample you provided applies to your question whatsoever. Also, if you have a lot of code post it on pastebin (I wouldn't consider this a lot of code). Just for future reference. -Luke ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
From: Alan Gauld Date: 08/15/06 03:37:21 To: Kermit Rose; [EMAIL PROTECTED] Cc: tutor@python.org; [EMAIL PROTECTED] Subject: Re: [Tutor] Global variables . The names have very little to do with it, the danger of global variable use is the reliance on side-effects and the tight coupling that you introduce between the calling module and the called module. Changes to the state of the calling module in an unpredictable manner lead to subtle bugs which are extremely hard to see and fix. * Huh??? What side effects do you have in mind? I certainly did not know any side effects existed. What do you mean by tight coupling? The only change I can see that would lead to a bug would be if I changed the name of the global variable in the calling routine and not in the function it called. I would know not to do that. >>>>>>>>>>> Confusion of names is of very little import, that really isn't the issue. ** Is it that global variables are no implemented correctly? I can't imagine what the issue would be if it isn't confusion of names. >>>>>>>>>> I'd be very very doubtful that its a bug in Python. Python is very well tested and while occasionally bugs do surface, the type of bug you are describing is extremely unl;ikely to have remained hidden. It is far more likely to be an error in the code or in the data. *** I understand your skepiticism. I would be too in if I were in your position. I've just sent the documentation to the list, in my message to Luke. >>>>> All of which points to an error in the code not in Python. The way Python is written it is virtually never going to result in that kind of error dependant on data values. ** Which is why it surprised me. >>>>>>>>>>> That might happen is if the values are very close to zero and a type conversion occurs, but otherwise I'm very dubious about a Python bug of that type. * Indeed. Errors of this type would be found by chance, like I found it. It would be impractical to search for this type of error. It is not a type conversion. The error is occuring between the return statement in the called function and the picking up of that value in the calling function. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
From: Bob Gailer Date: 08/14/06 20:24:00 To: [EMAIL PROTECTED]; tutor@python.org Subject: RE: [Tutor] Global variables A while back you attached factor34.py. Is that the program you are having trouble with? Yes! And you said it misbehaves "consistently with certain numbers to be factored." What are these numbers? * One of the numbers for which strongfac fails to return factors which it correctly calculates is Search for a factor of 137 Kermit < [EMAIL PROTECTED] > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
> That may be true but you will make your code much less reusable > and much more error propne in the process. There are good reasons > why global variables are considered evil... > > But in fact I use the same variable names in the subroutine > parameter list > as in the calling routine for every function in the module. The names have very little to do with it, the danger of global variable use is the reliance on side-effects and the tight coupling that you introduce between the calling module and the called module. Changes to the state of the calling module in an unpredictable manner lead to subtle bugs which are extremely hard to see and fix. > increase errors due to confusion of global and local variables. Confusion of names is of very little import, that really isn't the issue. > I would never have a local variable with the same name as the global > variable. Again thats not a problem. > But in this case, it's only because of an apparent bug in Python > that want > to bypass that I'm considering the use of global variables. I'd be very very doubtful that its a bug in Python. Python is very well tested and while occasionally bugs do surface, the type of bug you are describing is extremely unl;ikely to have remained hidden. It is far more likely to be an error in the code or in the data. > My routine strongfac calculates a value for fac in the subroutine, > and the > calling routine picks up a different vaalue. > > An illustration. > > In strong fac: > > fac = [1,2,3] > print fac > return fac > > in fermat: > > fac = strongfac(z) > print fac > > prints [0,0,0] > > And most of the time it does not misbehave like this. > > It is only occasionally, and consistently with certain numbers to be > factored. All of which points to an error in the code not in Python. The way Python is written it is virtually never going to result in that kind of error dependant on data values. That might happen is if the values are very close to zero and a type conversion occurs, but otherwise I'm very dubious about a Python bug of that type. Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
A while back you attached factor34.py. Is that the program you are having trouble with? And you said it misbehaves "consistently with certain numbers to be factored." What are these numbers? -- Bob Gailer 510-978-4454 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
Kermit Rose wrote: > > > From: Alan Gauld > Date: 08/14/06 18:42:41 > To: Kermit Rose; Luke Paireepinart > Cc: tutor@python.org; Danny Yoo > Subject: Re: [Tutor] Global variables > > > That may be true but you will make your code much less reusable > and much more error propne in the process. There are good reasons > why global variables are considered evil... > > > * > > I know that global variable usage can be abused. > > But in fact I use the same variable names in the subroutine parameter list > as in the calling routine for every function in the module. > > So I believe that in this case global variables would be useful and not > likely to > increase errors due to confusion of global and local variables. > > I would never have a local variable with the same name as the global > variable. > > It sounds like you should make a Factoring class and have whichever variables are similar for all functions be variables specific to the class instance (I forgot the word for this) Something like: # Class Factoring(object): def __init__(self): self.var1 = ['a','b','c'] self.var2 = 5 self.var3 = (0) def method1(self): print self.var1,self.var2 def method2(self): print self.var2,self.var3 fac = Factoring() fac.method1() fac.method2() #- the output would be ['a','b','c']5 5(0) Thus you prevent global namespace pollution. > But in this case, it's only because of an apparent bug in Python that want > to > bypass that I'm considering the use of global variables. > You probably shouldn't claim there's a bug in Python unless you're sure (I.E. have a snippet of code that reproduces the bug that you'll share with us) > > > My routine strongfac calculates a value for fac in the subroutine, and the > calling routine picks up a different vaalue. > do you think you could use more conventional terminology like 'function' and such? I don't understand what you mean by the subroutine of the routine. def routine(): def subroutine(): print 'hi' subroutine() Is that what you mean? or by 'subroutine' do you mean 'loop inside of function'? By your terminology, if there's a routine that calls strongfac, doesn't that mean strongfac is a subroutine? which would mean that the value for fac is calculated in the subroutine of the subroutine of the calling routine? > > An illustration. > > In strong fac: > > fac = [1,2,3] > print fac > return fac > > in fermat: > > fac = strongfac(z) > print fac > > prints [0,0,0] > what is 'z'? a random parameter? can you give us a cut-down version of your code that just reproduces this erratic behavior you're having a problem with? > > And most of the time it does not misbehave like this. > if random.randint(0,5) < 3: malfunction() > > It is only occasionally, and consistently with certain numbers to be > factored. > so with certain numbers it always occurs, with other numbers it sometimes occurs? > > > Kermit < [EMAIL PROTECTED] > > > Luke ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
On 15/08/06, Kermit Rose <[EMAIL PROTECTED]> wrote: > My routine strongfac calculates a value for fac in the subroutine, and the > calling routine picks up a different vaalue. > > An illustration. > > In strong fac: > > fac = [1,2,3] > print fac > return fac > > in fermat: > > fac = strongfac(z) > print fac > > prints [0,0,0] > > And most of the time it does not misbehave like this. Can you post actual code to illustrate the problem? Don't post your entire module; just show us the functions involved, the input that causes the problem, and what output you expect to get. -- John. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
From: Alan Gauld Date: 08/14/06 18:42:41 To: Kermit Rose; Luke Paireepinart Cc: tutor@python.org; Danny Yoo Subject: Re: [Tutor] Global variables That may be true but you will make your code much less reusable and much more error propne in the process. There are good reasons why global variables are considered evil... * I know that global variable usage can be abused. But in fact I use the same variable names in the subroutine parameter list as in the calling routine for every function in the module. So I believe that in this case global variables would be useful and not likely to increase errors due to confusion of global and local variables. I would never have a local variable with the same name as the global variable. But in this case, it's only because of an apparent bug in Python that want to bypass that I'm considering the use of global variables. My routine strongfac calculates a value for fac in the subroutine, and the calling routine picks up a different vaalue. An illustration. In strong fac: fac = [1,2,3] print fac return fac in fermat: fac = strongfac(z) print fac prints [0,0,0] And most of the time it does not misbehave like this. It is only occasionally, and consistently with certain numbers to be factored. Kermit < [EMAIL PROTECTED] > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
From: Luke Paireepinart Date: 08/14/06 17:17:13 To: Kermit Rose Cc: Danny Yoo; tutor@python.org Subject: Re: [Tutor] Global variables > From: Luke Paireepinart > > are you asking a question? > > > Kermit Rose wrote: > > > Yes. How can I make a package of functions declare global variables for > passing information between > the functions in the package? > > a 'package' meaning a module? Yes. I mean a module. >>>>> If you think you need global variables you're probably going about the problem the wrong way. What are you trying to do? * In my module I have several functions which work together to factor integers One function, called testrange is the main calling routine. It generates Tables and and passes their values to the main factoring subroutine, named fermat. Fermat calls a routine named strongfac. There seems to be some type of bug in Python because I observe that strongfac, depending on the number being factored, will sometimes return 0 instead of the factors it found. I believe that if I can get my main function, testrange, to declare a global variable to hold the caculated factor list, then I can bypass the apparent bug in Python that actualizes only for a few particular numbers to be factored. Also, if I can get testrange to create global variables, then I can shorten the parameter list of many of the functions in the module. Kermit < [EMAIL PROTECTED] > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
>> If I can figure out how to make my main function subroutine declare >> global >> variables then I won't need to pass parameters most parameters to >> the other >> subroutines, That may be true but you will make your code much less reusable and much more error propne in the process. There are good reasons why global variables are considered evil... >> and will bypass the problem I'm having that sometimes the function > strongfac SOMETIMES does not return the value it has in the > subroutine, > back to the calling routine. I'm not sure how you work that out. If the function uis getting bad data it will still return it regardless of whether you use golobals or return values. > Yes. How can I make a package of functions declare global > variables for > passing information between the functions in the package? just use the global keyword: ### x,y = 42,27 def f(): global x,y x = 66 y = 42 print x+y print x,y f() print x,y But its very bad practice and ## x,y = 42,27 def f(x,y): x = 66 y = 42 print x+y return x,y print x,y x,y = f(x,y) print x,y ## is much better. Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
> From: Luke Paireepinart > > are you asking a question? > > > Kermit Rose wrote: > > > Yes. How can I make a package of functions declare global variables for > passing information between > the functions in the package? > > a 'package' meaning a module? If you think you need global variables you're probably going about the problem the wrong way. What are you trying to do? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
From: Luke Paireepinart Date: 08/13/06 22:28:50 To: Kermit Rose Cc: Danny Yoo; tutor@python.org Subject: Re: [Tutor] Global variables Kermit Rose wrote: > > > From: Danny Yoo > Date: 08/09/06 16:23:35 > To: Kermit Rose > Cc: tutor@python.org > > > If I can figure out how to make my main function subroutine declare global > variables > then I won't need to pass parameters most parameters to the other > subroutines, > > and will bypass the problem I'm having that sometimes the function strongfac > SOMETIMES does not return the value it has in the subroutine, back to the > calling routine. > From: Luke Paireepinart are you asking a question? Kermit Rose wrote: Yes. How can I make a package of functions declare global variables for passing information between the functions in the package? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Global variables
Kermit Rose wrote: > > > From: Danny Yoo > Date: 08/09/06 16:23:35 > To: Kermit Rose > Cc: tutor@python.org > > > If I can figure out how to make my main function subroutine declare global > variables > then I won't need to pass parameters most parameters to the other > subroutines, > > and will bypass the problem I'm having that sometimes the function strongfac > SOMETIMES does not return the value it has in the subroutine, back to the > calling routine. > are you asking a question? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor