RE: How to reassign the value of the variable on runtime?
-Original Message- From: Python-list [mailto:python-list-bounces+webmailgroups=gmail@python.org] On Behalf Of Chris Angelico Sent: Saturday, August 29, 2015 19:02 Cc: python-list@python.org Subject: Re: How to reassign the value of the variable on runtime? On Sun, Aug 30, 2015 at 1:46 AM, Ivan Evstegneev wrote: > It looks like, when the module is loaded (imported) for the first > time, all the functions that are defined within it and using a global > varialbles as their defaults, they would keep the first value of this globals. That's correct. When you define a function, it snapshots the default values for its arguments; if you say "engine=engine_object", Python will evaluate the name "engine_object" at the time when the 'def' statement is executed (which in this case is module load) and save that as the default value for the argument "engine". Changing the value of engine_object won't change that. > So assumed you've already knew about this behavior and suggested to > use "lazy links". Am I right? Right. If you use "engine=None", then Python will evaluate the expression "None", which (what a surprise!) means the special object None. There's only one such object, and you'll never be replacing it. Then, whenever the function is called, you say "hey, if this thing's None, go and grab the one from the global"; and since that happens when the function's _called_ rather than when it's _defined_, it uses the value of engine_object at that time. > Still what is the difference between the way proposed: > > *** >>def current_data_export(engine=None, meta=None): >>if engine is None: engine = engine_object >> if meta is None: meta = meta_object > > > and the direct use of these globals within the function? > Like so: > > ** > def current_data_export(): > engine_object.some_method_used > meta_object.some_metheod_used > ** > > In both cases the engine and meta objects will be searched in > outerscope, what is the difference then? Correct, both will be fetched from the outer scope. The difference is that you can override them using the first form, by calling the function with arguments: current_data_export(some_other_engine, some_other_meta) which you can't do if you use the globals directly. But both forms do use the current values of the globals as at when the function is called. ChrisA -- https://mail.python.org/mailman/listinfo/python-list Thanks a lot (really). As for the globals? Each function that need to modify the globals should contain a "global bar" inside its body? Ivan. -- https://mail.python.org/mailman/listinfo/python-list
RE: How to reassign the value of the variable on runtime?
-Original Message- >From: Python-list [mailto:python-list-bounces+webmailgroups=gmail@python.org] On Behalf Of Michael Torrie >Sent: Thursday, August 27, 2015 21:50 >To: python-list@python.org >Subject: Re: How to reassign the value of the variable on runtime? >On 08/27/2015 12:25 PM, Ivan Evstegneev wrote: >> Can some please (I mean very please) explain me how do I reassign > >"engine_object" and "meta_object" variables, so they would store(point > >to) a new connection objects of my database, while other functions >>still would see those variables as their defaults? >If I understand you, the solution is fairly simple. Forgive me for not referencing your actual code. But I think you'll get the picture. >Simply don't do: >from foo import * >or even >from foo import bar >When you do the wildcard import, this puts references to all the objects in foo (or just foo.bar) into your current module's namespace. If you reassign these names, it just rebinds the name in your current module space, not in >the imported module's namespace. >So the solution is this: >import foo >foo.bar = "something" >Now in every module that imports foo, foo.bar picks up the change because the rebinding happens inside that module's namespace. Hope this makes sense. Hi Michael, Thanks for the reply, I've got your point, furthermore tried to make imports as you've told but ended up with kind of an opposite result. Maybe I've explained myself not clear enough. If you don't mind I'll bring back the piece of my code here. ))) So the package/module tree looks like that: my_proj/ __init__.py db_control(package)/ __init__.py alchemy_data_export.py some_other_module.py some_other_module_2.py The "alchemy_data_export.py" looks like this(more concise version): *** relevant import here engine_object, meta_object = db_existence_check_and_create() def rebuild(): engine_object, meta_object = db_existence_check_and_create() def current_data_export(engine=engine_object, meta=meta_object): . ...some important code here ^_^ . . print("System's Data successfully loaded into Database!") So I did the stuff your way: >>> import my_proj.control.db.alchemy_data_export as alchemy # after this line I've get the message from "db_existence_check_and_create()" that all is good # and now I can load my data into it. # The "engine_object" and "meta_object" were initialized # So I did the following >>> alchemy.current_data_export() # no arguments here, cause they've just been initialized >>> "Data has been loaded!" # Now lets say, I want to drop my old db and create new one with new data. # so I've used some function in alchemy >>alchemy.dropb_database() # This is the moment of truth. ))) # The next step was to rebuild the db and reinit the variables "engine_object" and "meta_object" # Did the following >>> alchemy.rebuild() # BUT!! now I can't write something like this: >>>alchemy.current_data_export() # Instead: >>>alchemy.current_data_export(engine=alchemy.engine_object, meta=alchemy.meta_object) # I do not want to do this. I'm looking for the (right) way of just reinit the "engine_object" and "meta_object" #so they'll be accepted by current_data_export() function as its defaults. # Another words, just want to keep on using a current_data_export() as I did it the first time, without the need of passing the arguments. How can it be done? Thanks a lot, P.S. As for the wildcard imports, I use an __all__ = [list of what to import] on the "other side" so I do limit my imports (hopefully). The reason for this, at least from my point of view (just a student with 2 min of experience ^_^), is the desire to limit background functions from being displayed in auto-complete view of my IDE. By this (again IMHO), if someone would use my API in future, he want be confused of which function to use. But, in case, there is more elegant way to achieve this, will be glad to hear. Ivan. -- https://mail.python.org/mailman/listinfo/python-list
How to reassign the value of the variable on runtime?
Hello all, I have stuck with some issue and can't solve it myself, your help will be highly appreciated. A bit of background: In my project I work with MySQL DB and SQLAlchemy. One of its tasks is to load data from excel files into database. To achieve this, I use some function that checks whether my db has been created earlier (if not, it creates a new one) and then establishes a connection to it. This function returns "db_engine_object" and "db_meta_object" variables, this allows me to reuse them when I work with other functions, instead of closing and reopening connections all the time. SO: I have package named "db_control", it consists of number ofmodules, where one of them is named "alchemy_db_export". db_control/ __init__.py alchemy_data_export.py #other modules This module looks like this (a relevant part of it): *CODE(alchemy_data_export.py ** from .alchemy_db_config import db_existence_check_and_create from ini_data_builder.main_builder import * from .db_table_names import * engine_object, meta_object = db_existence_check_and_create() def current_data_export(engine=engine_object, meta=meta_object): system_data = load_current_system_data() conn = engine.connect() for table_name in ordered_tables: conn.execute(meta.tables[table_name].insert().values(system_data[table_name] )) conn.close() print("System's Data successfully loaded into Database!") . . . . Some other functions that use "engine_object " and "meta_object" as defaults too.. . . . ** This one enables me to make such things: >>>from control_db import alchemy_data_export as alchemy >>>alchemy.current_data_export() I don't need to provide any arguments to "current_data_export()" just use a defaults (Yep me is lazy ^_^) BUT the problem begins when I want to create a fresh copy of database (using, say " create_new_db_()" function). Can some please (I mean very please) explain me how do I reassign "engine_object" and "meta_object" variables, so they would store(point to) a new connection objects of my database, while other functions still would see those variables as their defaults? I've tried couple of things, like defining these variables globally within this module (like that way): alchemy_data_export.py** from .alchemy_db_config import db_existence_check_and_create from ini_data_builder.main_builder import * from .db_table_names import * engine_object, meta_object = db_existence_check_and_create() def db_new_copy(): engine_object, meta_object = create_new_db() def current_data_export(engine=engine_object, meta=meta_object): system_data = load_current_system_data() conn = engine.connect() for table_name in ordered_tables: conn.execute(meta.tables[table_name].insert().values(system_data[table_name] )) conn.close() print("System's Data successfully loaded into Database!") ** But in this case I have some warning about "shadowing" I can know that I shadow outerscope variables but how can I achieve my goal other way? Tried __init__.py and other 10-20 things but still stuck with it, I'm sure this is because the lack of experience. Hope my situation is clear enough ^_^ Tried my best. Again thanks a lot for a help. Ivan. -- https://mail.python.org/mailman/listinfo/python-list
RE: Function Defaults - avoiding unneccerary combinations of arguments at input
> -Original Message- > From: Python-list [mailto:python-list- > bounces+webmailgroups=gmail@python.org] On Behalf Of Steven > D'Aprano > Sent: Thursday, March 26, 2015 01:49 > To: python-list@python.org > Subject: Re: Function Defaults - avoiding unneccerary combinations of > arguments at input > > On Thu, 26 Mar 2015 04:43 am, Ivan Evstegneev wrote: > > > Hello all , > > > > > > Just a little question about function's default arguments. > > > > Let's say I have this function: > > > > def my_fun(history=False, built=False, current=False, topo=None, > > full=False, file=None): > > if currnet and full: > > do something_1 > > elif current and file: > > do something_2 > > elif history and full and file: > > do something_3 > > > This is an extreme example that shows why Guido's Law "No constant > arguments" is a good design principle. (Well, it's not really so much a law as a > guideline.) > > If you have a function that looks like this: > > def spam(arg, flag=True): > if flag: > return do_this(arg) > else: > return do_that(arg) > > > then you should just use do_this and do_that directly and get rid of spam. > > In your case, its hard to say *exactly* what you should do, since you are only > showing a small sketch of "my_fun", but it looks to me that it tries to do too > much. You can probably split it into two or four smaller functions, and avoid > needing so many (or any!) flags. > > That will avoid (or at least reduce) the need to check for mutually > incompatible sets of arguments. > > Another useful design principle: if dealing with the combinations of > arguments is too hard, that's a sign that you have too many combinations of > arguments. > > If there are combinations which are impossible, there are three basic ways to > deal with that. In order from best to worst: > > > (1) Don't let those combinations occur at all. Redesign your function, or split > it into multiple functions, so the impossible combinations no longer exist. > > (2) Raise an error when an impossible combination occurs. > > (3) Just ignore one or more argument so that what was impossible is now > possible. > > > > > -- > Steven > > -- > https://mail.python.org/mailman/listinfo/python-list Hello Steven, As I said in a previous mail, main purpose of this arguments is to define what path should be chose. It is actually one xls file that could be placed into various placed within my folder tree. For instance, I have following folder tree: data_lib/ current/ history/ built/ Say I have "test.xls" that could be in one of those three folders. I wrote a function that reads it out, and its input arguments just define where it should be read. So all those "ifs" related to path definition. Still now I'm thinking to really split it out... I'll have a separate function for path definition and then it will call a common reader_fun() in order to read this file. Sincerely, Ivan -- https://mail.python.org/mailman/listinfo/python-list
RE: Function Defaults - avoiding unneccerary combinations of arguments at input
> -Original Message- > From: Python-list [mailto:python-list- > bounces+webmailgroups=gmail@python.org] On Behalf Of Rob Gaddi > Sent: Wednesday, March 25, 2015 22:07 > To: python-list@python.org > Subject: Re: Function Defaults - avoiding unneccerary combinations of > arguments at input > > On Wed, 25 Mar 2015 21:50:40 +0200, Ivan Evstegneev wrote: > > > Hello again ^_^, > > > > Googled a bit, and found only one, a "ValueError" exception, but still > > don't understand how it should be implemented in my case. > > > > Should my code look like this one: > > > > def my_fun(history=False, built=False, current=False, topo=None, > > full=False, file=None): > > try: > > if currnet and full: > > do something_1 > > elif current and file: > > do something_2 > > elif history and full and file: > > do something_3 > > > > except ValueError: > > print("No valid input! Please try again ...") > > > > > > .. some code here.. > > > > > > Or I'm just too optimistic ^_^? > > > > Thanks in advance, > > > > Ivan. > > > > A) Please don't top-post. Put your new stuff below previous context, so it > flows in readable order. > > B) You've got the concept backwards. You're not trying to catch a ValueError > because one came up below your function. Your function was called > incorrectly, and you're kicking the responsibility for dealing with it back to the > guy who got it wrong. > > def my_fun(): > if invalid_argument_combination: >raise ValueError('Hey jerk, read the documentation.') > > # otherwise you do your thing in here. > > > -- > Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email > address domain is currently out of order. See above to fix. > -- > https://mail.python.org/mailman/listinfo/python-list Ok thanks fo the answer. Got it. About top-posting... will need to tweak Outlook settings. -- https://mail.python.org/mailman/listinfo/python-list
RE: Function Defaults - avoiding unneccerary combinations of arguments at input
Hello again ^_^, Googled a bit, and found only one, a "ValueError" exception, but still don't understand how it should be implemented in my case. Should my code look like this one: def my_fun(history=False, built=False, current=False, topo=None, full=False, file=None): try: if currnet and full: do something_1 elif current and file: do something_2 elif history and full and file: do something_3 except ValueError: print("No valid input! Please try again ...") .. some code here.. Or I'm just too optimistic ^_^? Thanks in advance, Ivan. > -Original Message- > From: Python-list [mailto:python-list- > bounces+webmailgroups=gmail@python.org] On Behalf Of Terry Reedy > Sent: Wednesday, March 25, 2015 20:43 > To: python-list@python.org > Subject: Re: Function Defaults - avoiding unneccerary combinations of > arguments at input > > On 3/25/2015 1:43 PM, Ivan Evstegneev wrote: > > Hello all , > > > > > > Just a little question about function's default arguments. > > > > Let's say I have this function: > > > > def my_fun(history=False, built=False, current=False, topo=None, > > full=False, file=None): > > if currnet and full: > > do something_1 > > elif current and file: > > do something_2 > > elif history and full and file: > > do something_3 > > > > > > .. some code here.. > > > > and so on... > > > > I won't cover all the possibilities here (actually I don't use all of > > them ^_^). > > > > The question is about avoiding the response for unnecessary > combinations? > > > > For instance, if user will call function this way: > > > > > >>>> my_fun(current=True, full=True, topo='some str', file="some_file") > > > > That will lead to function's misbehavior. As a particular case it will > > choose "current and full" condition. > > > > > > What is the common accepted way to deal with such unwanted situations? > > Raise a value error for illegal combinations. There are a few instances in the > stdlib where 2 of several options are mutually incompatible. > > > -- > Terry Jan Reedy > > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: Function Defaults - avoiding unneccerary combinations of arguments at input
Hi Terry, Thanks for answer, I'll google these stdlib instances. Sincerely, Ivan. > -Original Message- > From: Python-list [mailto:python-list- > bounces+webmailgroups=gmail@python.org] On Behalf Of Terry Reedy > Sent: Wednesday, March 25, 2015 20:43 > To: python-list@python.org > Subject: Re: Function Defaults - avoiding unneccerary combinations of > arguments at input > > On 3/25/2015 1:43 PM, Ivan Evstegneev wrote: > > Hello all , > > > > > > Just a little question about function's default arguments. > > > > Let's say I have this function: > > > > def my_fun(history=False, built=False, current=False, topo=None, > > full=False, file=None): > > if currnet and full: > > do something_1 > > elif current and file: > > do something_2 > > elif history and full and file: > > do something_3 > > > > > > .. some code here.. > > > > and so on... > > > > I won't cover all the possibilities here (actually I don't use all of > > them ^_^). > > > > The question is about avoiding the response for unnecessary > combinations? > > > > For instance, if user will call function this way: > > > > > >>>> my_fun(current=True, full=True, topo='some str', file="some_file") > > > > That will lead to function's misbehavior. As a particular case it will > > choose "current and full" condition. > > > > > > What is the common accepted way to deal with such unwanted situations? > > Raise a value error for illegal combinations. There are a few instances in the > stdlib where 2 of several options are mutually incompatible. > > > -- > Terry Jan Reedy > > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Function Defaults - avoiding unneccerary combinations of arguments at input
Hello all , Just a little question about function's default arguments. Let's say I have this function: def my_fun(history=False, built=False, current=False, topo=None, full=False, file=None): if currnet and full: do something_1 elif current and file: do something_2 elif history and full and file: do something_3 .. some code here.. and so on... I won't cover all the possibilities here (actually I don't use all of them ^_^). The question is about avoiding the response for unnecessary combinations? For instance, if user will call function this way: >>>my_fun(current=True, full=True, topo='some str', file="some_file") That will lead to function's misbehavior. As a particular case it will choose "current and full" condition. What is the common accepted way to deal with such unwanted situations? Thanks a lot in advance, Ivan. -- https://mail.python.org/mailman/listinfo/python-list
Advice needed - Choosing appropriate GUI (IDE) and Data Visualization software (3D also)
Hello guys, Here is a brief description for my question: I'm currently dealing with my EE B.Sc. final project. This projects generally relates to the SDN Optical Networks. One of its goals is to build some GUI framework based on mininet software (http://mininet.org/) Mostly, I'll need expand its capabilities and add some new features for Layer 1. As a general concept I need to build something which looks like that: 1. http://www.brianlinkletter.com/wp-content/uploads/2014/01/GNS3-setup-Virtual Box-9.png or that (even better): 2. https://www.safaribooksonline.com/library/view/learning-omnet/9781849697149/ graphics/7149OT_02_03.jpg When at middle window I'll place my interactive display, which (at initial state) should look like this one: 3. http://3.bp.blogspot.com/_2bTtOorcilA/S-jVtqNy0xI/AAM/R9l6L26yAV0/s1 600/ChordIPv4.png I said 'interactive' because it need to be: scalable, zoomable, movable(and other "able") ^_^ Moreover it actually need to provide access to device properties, for instance behave (at least) like that one: 4. http://youtu.be/XAzXKnAwKxo?t=4m20s Finally I found this one : 5. http://youtu.be/L-ad0Phy0eI?t=10s This one looks awesome! ))) This is an interactive model to which I want to aspire. Furthermore, if this design: 6. https://www.youtube.com/watch?v=JsEm-CDj4qM could be implemented to the above links, this will realize my "wet dream" of blurry bubbles and shaded backgrounds Of course, as a EE student I'll tend more to the practical side rather than design. But still it could be nice to make some good looking product. In conclusion: 1. For my core GUI(IDE) I'll likely use PythonQt. I've read couple of reviews , most of them say that this one good for beginners. Of cause, if there any other frameworks that worth to consider, and seems more suitable for beginners, I would be glad to hear for your advice. Here I need most of your help: 2. The interactive "middle window", unfortunately I have no idea what is a suitable software for such kind of things. For almost a week I delve the NET for possible options, there are innumerable quantity of Python packages and tools (my Chrome is blown up with opened tabs), but still don't know what to choose or how to implement this one. (especially link's #5 model) (Python OpenGL? ) 3. For those of you who will ask: why I don't want to take something already done before: My answer will be simple: a. Unfortunately I'm not a guru of programming. My programming scope includes only some C, Matlab, and now Python. For this reason I can't take some modules from "omninet ++" software (which actually written in C++) and implement them in my project. Or for instance to use OpenDayLight software modules I know that I will mess up with this and waste a lot of time for getting it work properly. (But I'm not whining here ^_^) b. I'm short in time (as most of us). I can't afford myself to learn additional languages (at least at this moment) c. My basis software (mininet) is written on Python. d. Most of an existing software for SDN deal with Layer 3. So their models not so suitable for my purposes. I need to redefine a lot of things and build them from scratch. e. In general I think Python can handle all my needs Any advice will be highly appreciated. Sincerely, Ivan. -- https://mail.python.org/mailman/listinfo/python-list
Classes - "delegation" question.
Hello guys, I have a question about "delegation" coding pattern(I'm working with Python 3.4). In order to describe my question , I'll provide particular example: Let assume I have two classes written in module named person.py: Case 1: class Person: def __init__(self, name, job = None, pay =0): self.name = name self.job = job self.pay = pay def lastName(self): return self.name.split()[-1] def giveRaise(self, percent): self.pay = int(sel.pay * (1 + percent)) def __repr__(self): return '[Person: %s, %s]' % (self.name, self.pay) class Manager(Person): def giveRaise(self, percent, bonus = .10): Person.giveRaise(self, percent + bonus) Case 2: class Person: the same... class Manager: def __init__(self, name, pay): self.person = Person(name, 'mgr', pay) def giveRaise(self, percent, bonus = .10): self.person.giveRaise(percent + bonus) def __getattr__(self, attr): return getattr(self.person, attr) def __repr__(self): return str(self.person) I also used some test code proposed by the book: if __name__ == '__main__': bob = Person('Bob Smith') sue = Person('Sue Jones', job='dev', pay=10) print(bob) print(sue) print(bob.lastName(), sue.lastName()) sue.giveRaise(.10) print(sue) tom = Manager('Tom Jones', 5) # Job name not needed: tom.giveRaise(.10) print(tom.lastName()) print(tom) As I can understand from the above code : When code looks like in Case 1, it actually works with standard "inheritance" model. (with sub and super-class definitions). Also according to the book: *** This code leverages the fact that a class's method can always be called either through an instance (the usual way, where Python sends the instance to the self argument automatically) or through the class (the less common scheme, where you must pass the instance manually). In more symbolic terms, recall that a normal method call of this form: instance.method(args...) is automatically translated by Python into this equivalent form: class.method(instance, args...) *** Furthermore: *** Python provides it automatically only for calls made through an instance. For calls through the class name, you need to send an instance to self yourself; for code inside a method like giveRaise, self already is the subject of the call, and hence the instance to pass along. Calling through the class directly effectively subverts inheritance and kicks the call higher up the class tree to run a specific version. What is considered as a "call" in this context? Is it a code inside class method? For instance(relates to the "Case 1"): def giveRaise(self, percent, bonus = .10): Person.giveRaise(self, percent + bonus) The "call" will be : Person.giveRaise(self, percent + bonus) ? In such a case, when I create an instance: >>> tom = Manager('Tom Jones', 5) and then invoke giveRaise method >>> tom.giveRaise(.10) I essentially say this: "class.method(instance, args...) " Where class is "Person" and method is "giveRaise" and instance is "tom"? Moreover, because of how it defined (a method giveRaise), I make a "call" through the class name? What is the "call" through instance? Is it this one(according to Case 1): class Person: ... def giveRaise(self, percent): self.pay = int(sel.pay * (1 + percent)) ... and then: >>> bob = Person('Bob Smith', 'dev', 3) >>> bob.giveRaise(.10) < Is this call through instance? Questions regard to "Case 2" example: class Person: the same... class Manager: def __init__(self, name, pay): self.person = Person(name, 'mgr', pay) <--- Initialization of Manager's attribute named 'self.person" and embedding a Person object. def giveRaise(self, percent, bonus = .10):< -- Defenition of Manager's method named "giveRaise" and according to the book: self.person.giveRaise(percent + bonus) "Intercept and delegate" .. My question here is substantially the same: On the one hand we embedding "Person" into "Manager" class, On the other hand, when I write this code: >>> tom = Manager('Tom Jones', 5000) I create an instance of Manager that have an attribute named: tom.person, which in turn is a class named Person. And when typing: >>>tom.giveRaise(.10) I do kinda same thing. For my assumption I say: P
RE: Classes - converting external function to class's method.
Again Thanks for your help. I saw that there was a debate about "namespace" nature. That is what a book says about it(Learning Python 5 Ed. By Mark Lutz): * "Classes and Instances Although they are technically two separate object types in the Python model, the classes and instances we put in these trees are almost identical—each type’s main purpose is to serve as another kind of namespace—a package of variables, and a place where we can attach attributes. If classes and instances therefore sound like modules, they should; however, the objects in class trees also have automatically searched links to other namespace objects, and classes correspond to statements, not entire files." "Customization via inheritance More generally, classes can build up namespace hierarchies, which define names to be used by objects created from classes in the hierarchy. This supports multiple customizable behaviors more directly than other tools." "...classes live in modules and are namespaces as well, but they add an extra component to attribute lookup called inheritance search." "In fact, classes have just three primary distinctions. At a base level, they are mostly just namespaces, much like the modules we studied in Part V. Unlike modules, though, classes also have support for generating multiple objects, for namespace inheritance, and for operator overloading." I'm not pretending to be a "smartass" here, but as I can understand from the context: Classes are namespaces, but they also have an additional capabilities. BR, Ivan > -Original Message- > From: Python-list [mailto:python-list- > bounces+webmailgroups=gmail@python.org] On Behalf Of Steven > D'Aprano > Sent: Monday, December 15, 2014 04:01 > To: python-list@python.org > Subject: Re: Classes - converting external function to class's method. > > Thomas 'PointedEars' Lahn wrote: > > > Ivan Evstegneev wrote: > > > >> I have stuck a bit with this example(took this one from the book). > >> > >> Here are a description steps of what I've done till now: > >> > >> > >> Step 1 - creating an empty namespace: > >> > >>>>>class rec: pass > > > > IMHO that is not actually creating a namespace; it is just > > declaring/defining an empty class. > > And classes are namespaces. As are instances. > > One clue is the fact that we use exactly the same syntax for accessing names > in a > namespace regardless of whether the namespace is a package, a module, a class > or an instance: > > import collections.abc # a package namespace math.sin # a module namespace > OrderedDict.fromkeys # a class namespace mystring.upper # an instance > namespace > > I call it a "clue" rather than definitive proof because the syntax is not > quite the > same for all namespaces. Local and global variables also exist in namespaces, > but > you don't use dotted notation for them. > > Another clue is that most of these are implemented by using a __dict__ to > store > the name:value mapping. Again, that's not universal: instances can optionally > use __slots__ instead of __dict__ and packages use the file system. > > Apart from packages, one can use getattr(), setattr() and delattr() on all of > these > objects (modules, classes and instances) to manipulate their attributes. > > Wikipedia says: > > "In general, a namespace is a container for a set of identifiers (also known > as > symbols, names)." > > https://en.wikipedia.org/wiki/Namespace > > and that applies to packages, modules, classes, and instances. > > Last but not least, another clue: in some languages, such as Java, what Python > calls "attributes" are known as *variables*. So per-instance members are > called > "instance variables", per-class members are sometimes called "class variables" > (although not in Java, where I believe they are known as static variables for > technical reasons). Personally, I don't like that terminology, but I do > recognise > that it does reflect a certain connection between names in > local/global/instance/class namespaces. > > > > BTW, the recommended Python 3.x way is > > > > class Rec (object): > > pass > > > I think you mean Python 2 rather than 3. In Python 2, we have legacy "old > style" > or "classic" classes, and "new style" classes which inherit from object. In > Python > 3, classic classes are gone, and inheriting
RE: Classes - converting external function to class's method.
Dear Steven, I very appreciate your answer. You just explained a lot of background things and you did it in more explicit and simple way than it've appeared in the book. I also agree with you about the fact that there are some advanced topics spread within a book's text. It is sometimes hard to a newbie to separate essential and from non essential(I mean more advanced) topics. So I may find myself digging down too much ^_^ In order to assemble the picture I would like to refer to couple of things you mentioned: >In this case, it works as you expect. Python looks up "method" on the instance, and doesn't find anything attached to the instance. It then looks at the class "rec", >which does have something called "method". Because this is a function, Python knows to provide the instance x as the first argument. So the call > x.method() >ends up turning into this: >rec.method(x) I saw something similar to this example, but initially didn't understand what the author meant, so I skipped it Here is a quote from a book(Please see Pic1.jpg too): *** Method Calls If this I2.w reference is a function call, what it really means is "call the C3.w function to process I2." That is, Python will automatically map the call I2.w() into the call C3.w(I2), passing in the instance as the first argument to the inherited function. *** This was much confusing, till the moment I've read your explanation on live example. ))) > Looking at this, I can guess you are using Python 3, because that won't work in > Python 2. Am I right? Yes. I downloaded, Python 3.4 from python.org. Currently working with IDLE. > The important part to see here is that when you call a method from an > instance: > > instance.method() > > Python *automatically* fills in the "self" argument using the instance. (In your > case, you called that argument "obj" instead of self, but Python doesn't care > what it is called.) > > How does Python know to use x as self? Because it's written right there: > x.method uses x as the first argument for method. But this is only done for > *instances*, not classes. So, just to summarize all this stuff: A class doesn't have method __self__ by itself. I checked this on some other class provided in the book: >>> class FirstClass: # Define a class object def setdata(self, value):# Define class's methods self.data = value # self is the instance def display(self): print(self.data) And then check it with: >>>dir(FirstClass) [Yep no __self__ here] On the other side, when an instance created, it does have __self__ method. > > How does a function "uppername()" looks like, when I apply it to "rec" > > class, so it becomes a class's method? > > I don't understand this question. Well this is an embarrassing moment, it's just shows how lame my English can be ) What I tried to ask here is if there any changes applied by Python to code of function "uppername()" when it becomes class method (after using this command: rec.method = uppername) Never mind, you already answered it here: > This is almost equivalent to the following: > > class rec: > name = 'Bob' > age = 40 > def method(obj): > return obj.name.upper() Moreover, regard to the "rec.method = uppername" As I can understand, in this case Python does make some changes to the function, but they are implicit. Am I right? Sincerely, Ivan > -Original Message- > From: Python-list [mailto:python-list- > bounces+webmailgroups=gmail@python.org] On Behalf Of Steven > D'Aprano > Sent: Sunday, December 14, 2014 19:28 > To: python-list@python.org > Subject: Re: Classes - converting external function to class's method. > > Ivan Evstegneev wrote: > > > Hello Everyone, > > > > I have stuck a bit with this example(took this one from the book). > > The example you are working on (adding external functions as methods) is > actually a bit more complicated than it seems, as you have discovered. You have > this: > > class rec: pass > rec.name = 'Bob' > rec.age = 40 > > x= rec() > > def uppername(obj): > return obj.name.upper() > > rec.method = uppername > > > This is almost equivalent to the following: > > class rec: > name = 'Bob' > age = 40 > def method(obj): > return obj.name.upper() > > > You then try to use this new method, by calling i
Classes - converting external function to class's method.
Hello Everyone, I have stuck a bit with this example(took this one from the book). Here are a description steps of what I've done till now: Step 1 - creating an empty namespace: >>>class rec: pass Step 2 - adding some attributes: >>>rec.name = 'Bob' >>>rec.age = 40 Step 3 - Creating an instance: >>>x= rec() Step 4 - write down external function: >>>def uppername(obj): return obj.name.upper() Step 5 - applying this function on x: >>>uppername(x) 'BOB' Till this moment its Ok. But: Step 6 - Creating a class method: >>>rec.method = uppername Then using the "help" function I get (just checking what happened): >>>help(rec) class rec(builtins.object) | Methods defined here: | | method = uppername(obj) | | -- |omitted text.. | | Data and other attributes defined here: | | age = 40 | | name = 'Bob' Then the same about x: >>>help(x) class rec(builtins.object) | Methods defined here: | | method = uppername(obj) | --- omitted text . |- The last check I've made: >>> help(x.method) Help on method uppername in module __main__: uppername() method of __main__.rec instance >>> help(rec.method) Help on function uppername in module __main__: uppername(obj) and now to the Step 7 - using this new "method" on x: >>>x.method() 'BOB' >>>rec.method() . . TypeError: uppername() missing 1 required positional argument: 'obj' and then: >>>rec.method(rec) 'BOB' So my the question is: what is going on here? How this actually works? According to the book's downside note: ** In fact, this is one of the reasons the self argument must always be explicit in Python methods-because methods can be created as simple functions independent of a class, they need to make the implied instance argument explicit. They can be called as either functions or methods, and Python can neither guess nor assume that a simple function might eventually become a class's method. The main reason for the explicit self argument, though, is to make the meanings of names more obvious: names not referenced through self are simple variables mapped to scopes, while names referenced through self with attribute notation are obviously instance attributes. * Keeping it in mind, I wrote this code: >>> class myclass: def __init__(self, value): self.name = value def myupper(self): return self.name.upper() And then: >>> b = myclass('bob') >>>b.myupper() 'BOB' I made an assumption that this is what happens(roughly speaking) when I write this: >>>rec.method = uppername Am I right? (close enough maybe?) On the other hand, when I checked further: >>>dir(x.method) [, '__self__',...] but >>>dir(rec.method) [ list of method and '__self__' wasn't there.] I got a "bit" confused. Why actually in instance "x" >>>x.method() can auto-assign an "x" to uppername() function argument, but it doesn't work in a class "rec" itself? So I need to write down an "obj" argument manually. Why '__self__' exists only in instance "x"? (maybe because "rec", initially was created as an empty class?) How does a function "uppername()" looks like, when I apply it to "rec" class, so it becomes a class's method? So in such a case, when instance "x" receives an "update" it reads the new method as I described above(I mean the code of "myclass")? Thanks a lot in advance, Ivan. -- https://mail.python.org/mailman/listinfo/python-list
RE: Python Iterables struggling using map() built-in
Awesome Ned, Believe it or not, but I was browsing web for the answer about a half an hour ago. Guess what? I found your web page with the explanations you provided there. ))) Finally, I was ready to send this question to you directly, cause I didn't know that you subscribed to this mailing list too. ^_^ But, you was a bit faster. What a surprise. ))) ))) ))) Thanks a lot for your answer. Ivan. -Original Message- From: Python-list [mailto:python-list-bounces+webmailgroups=gmail@python.org] On Behalf Of Ned Batchelder Sent: Sunday, December 7, 2014 17:29 To: python-list@python.org Subject: Re: Python Iterables struggling using map() built-in On 12/6/14 11:44 AM, Ivan Evstegneev wrote: > And as I've promised the question section: > > 1.What actually map() trying to do in Python 3.X? > > I mean, why is this works fine: > >>>>L = [1, 2, 3, 4] > >>>> k = iter(L) > >>>> next(k) > > 1 > > and so on. > > But not this: > > >>> list(map(iter, L)) > > Traceback (most recent call last): > > File "", line 1, in > > print(list(map(iter, L))) > > TypeError: 'int' object is not iterable Let's unpack the code. You are running: map(iter, L) which is equivalent to: map(iter, [1, 2, 3, 4]) which executes: iter(1), iter(2), iter(3), iter(4) If you try iter(1), you get the error you are seeing. Integers are not iterable. What values would it produce? You ask what this is doing in Python 3, but it happens in any Python version, because integers are not iterable. > > 2.Why strings are allowed "to become" an iterators(self-iterators)? > Maybe because of files(reading from file) ? > > I mean why, is this possible: > >>>> print(list(map(iter, S))) > > [, > > , > > , > > ] > This is a confusing thing in Python: strings are iterable, they produce a sequence of 1-character strings: >>> list("hello") ['h', 'e', 'l', 'l', 'o'] This isn't because of reading from files. Open files are iterable, they produce a sequence of strings, one for each line in the file. This is why you can do: for line in file: process(line) Many times, it would be more convenient if strings were not iterable, but they are, and you need to keep it in mind when writing general-purpose iteration. > > 3.The last question > > Author says: > > " /But it falls into an infinite loop and fails in Python 3.X, because > the 3.X map returns a / > > /one-shot iterable object instead of a list as in 2.X. In 3.X, as soon > as we've run the list / > > /comprehension inside the loop once, iters will be exhausted but still > True/. /To make this / > > /work in 3.X, we need to use the list built-in function to create an > object that can support / > > /multiple iterations". /(Like:"Wat?!" ^_^)// > > Why the infinite loop would be there and why should list() to make it > finite? o_0 > OK, let's go slowly. There are a few foundational concepts to get under our belt. *** CONCEPTS 1. An iterable is an object that you can pass to iter() to get an iterator. 2. An iterator is an object that can provide you with values one after the other, by using next(). next() will either return the next value, or raise a StopIteration exception, indicating that there are no more values. 3. The only operation supported on iterators is next(). You cannot start them over, you cannot ask if there will be more values, you cannot find out how many values there will be, you can't ask what the last value was, etc. By supporting only one operation, they allow the broadest possible set of implementations. 4. You can ask an iterator for an iterator, and it will return itself. That is: iter(some_iterator) is some_iterator. 5. The "for NAME in EXPR" construct is equivalent to this: expr_iter = iter(EXPR) try: while True: NAME = next(expr_iter) ..DO_SOMETHING.. except StopIteration: pass 6. In Python 2, map() produces a list of values. Lists are iterable. In Python 3, map() produces a map object, which is an iterator. *** PYTHON 2 EXECUTION OK, now, here is the code in question: 1. def myzip(*args): 2. iters = map(iter, args) 3. while iters: 4. res = [next(i) for i in iters] 5. yield tuple(res) Let's cover the Python 2 execution first. At line 2, map produces a list of iterators. Line 3 will loop forever. Nothing ever changes the list. In fact, this is a very confusing part of this code. The code should have said "while True" here, because it would wor
RE: Tuple of lists concatenation - function vs comprehension
Hi Shiyao, Now I see, that it was kind of dumb question... >>>>x = ([1, 2], [3, 4], [5, 6]) >>>>L = [] >>>[L.extend(i) for i in x] [None, None, None] BUT when I check L itself I'll see this one >>>L [1,2,3,5,6] Ok. Thanks. -Original Message- From: Shiyao Ma [mailto:i...@introo.me] Sent: Sunday, December 7, 2014 17:18 To: Ivan Evstegneev Cc: python-list@python.org Subject: Re: Tuple of lists concatenation - function vs comprehension On 12/07, Ivan Evstegneev wrote: > Hello, > > When I have worked in Python shell (IDLE) I found this issue: > > >>>x = ([1, 2], [3, 4], [5, 6]) > >>>L = [] > >>>for I in x: > L.extend(i) > > >>>L > [1,2,3,4,5,6] > > But when I try to make comprehension using above expression, I get this: > > >>>x = ([1, 2], [3, 4], [5, 6]) > >>>L = [] > >>> [L.extend(i) for i in x] > [None, None, None] Yes. per the doc, list.extend() returns None. > > But this works fine within function: > > >>> def myfunc(): > x = ([1, 2], [3, 4], [5, 6]) > L = [] > [L.extend(i) for i in x] > print(L) > > >>>myfunc() > [1, 2, 3, 4, 5, 6] This is also so true, as you are print the var 'L'. > > The question is why I'm getting empty list while working with > comprehension in interactive console? You are also getting [None]*3 in comprenhension inside a function. -- Shiyao Ma http://introo.me -- https://mail.python.org/mailman/listinfo/python-list
Tuple of lists concatenation - function vs comprehension
Hello, When I have worked in Python shell (IDLE) I found this issue: >>>x = ([1, 2], [3, 4], [5, 6]) >>>L = [] >>>for I in x: L.extend(i) >>>L [1,2,3,4,5,6] But when I try to make comprehension using above expression, I get this: >>>x = ([1, 2], [3, 4], [5, 6]) >>>L = [] >>> [L.extend(i) for i in x] [None, None, None] But this works fine within function: >>> def myfunc(): x = ([1, 2], [3, 4], [5, 6]) L = [] [L.extend(i) for i in x] print(L) >>>myfunc() [1, 2, 3, 4, 5, 6] The question is why I'm getting empty list while working with comprehension in interactive console? Thanks for your help. Ivan. -- https://mail.python.org/mailman/listinfo/python-list
Python Iterables struggling using map() built-in
Hello everyone, I'm currently in the process of self-study journey, so I have some questions arisen from time to time. Today I would like to talk about iterables and iterators,(ask for your help actually ^_^). Before I'll continue, just wanted to draw your attention to the fact that I did some RTFM before posting. Links: 1. map() built-in definitions: https://docs.python.org/3/library/functions.html#map -for Python 3.X https://docs.python.org/2.6/library/functions.html#map - for Python 2.6.X 2. Glossary definitions of "iterable " and "iterator": https://docs.python.org/3/glossary.html?highlight=glossary 3. Iterator Types: https://docs.python.org/2/library/stdtypes.html#typeiter 4. iter() definition: https://docs.python.org/2/library/functions.html#iter 5. Some StackOverflow links, related to the topic: http://stackoverflow.com/questions/13054057/confused-with-python-lists-are-t hey-or-are-they-not-iterators http://stackoverflow.com/questions/9884132/understanding-pythons-iterator-it erable-and-iteration-protocols-what-exact http://stackoverflow.com/questions/19523563/python-typeerror-int-object-is-n ot-iterable http://stackoverflow.com/questions/538346/iterating-over-a-string 6. And of course, re-read couple of times a relevant parts of the book ('Learning Python" by Mark Lutz). But the questions still persist, maybe because those examples look too esoteric though. Another warning: Despite all my attempts to make my questions as short as possible it still looks huge. My apologies. The problem: Here is the book's example: Consider the following clever alternative coding for this chapter's zip emulation examples, adapted from one in Python's manuals at the time I wrote these words: def myzip(*args): iters = map(iter, args) while iters: res = [next(i) for i in iters] yield tuple(res) Because this code uses iter and next, it works on any type of iterable. Note that there is no reason to catch the StopIteration raised by the next(it) inside the comprehension here when any one of the arguments' iterators is exhausted-allowing it to pass ends this generator function and has the same effect that a return statement would. The while iters: suffices to loop if at least one argument is passed, and avoids an infinite loop otherwise (the list comprehension would always return an empty list). This code works fine in Python 2.X as is: >>> list(myzip('abc', 'lmnop')) [('a', 'l'), ('b', 'm'), ('c', 'n')] But it falls into an infinite loop and fails in Python 3.X, because the 3.X map returns a one-shot iterable object instead of a list as in 2.X. In 3.X, as soon as we've run the list comprehension inside the loop once, iters will be exhausted but still True (and res will be []) forever. To make this work in 3.X, we need to use the list built-in function to create an object that can support multiple iterations: >>>def myzip(*args): iters = list(map(iter, args)) # Allow multiple scans ...rest as is... Run this on your own to trace its operation. The lesson here: wrapping map calls in list calls in 3.X is not just for display! *END OF THE BOOK EXAMPLE According to the book , in order to get things work properly in Python 3.X, I should write this code: >>> def myzip(*args): iters = list(map(iter, args)) while iters: res = [next(i) for i in iters] yield tuple(res) And all seemed to be clear here, but, when I tried to run this thing: >>> k= myzip(1, 2, 3, 4) >>> next(k) I got this result: Traceback (most recent call last): File "", line 1, in next(k) File "", line 2, in myzip iters = list(map(iter, args)) TypeError: 'int' object is not iterable Finding the problem: I started to investigate further in order to catch the bug: What I've tried? 1. >>> L = [1, 2, 3, 4] >>> iter(L) is L False ---> According to the "theory" it's OK, because list doesn't have self iterators. >>> k = iter(L) >>>print(k) >>> next(k) 1 >>> print(list(map(iter, L))) Traceback (most recent call last): File "", line 1, in print(list(map(iter, L))) TypeError: 'int' object is not iterable 2. I went to strings: >>> S = 'spam' >>> iter(S) is S False --->Same about strings >>> string = iter(S) >>> string >>> next(string) 's' and so on. And then just tried this one: >>> print(list(map(iter, S))) [, , , ] -> At this moment "Wrecking Ball" song played in my head %))) >>> k = list(map(iter,S)) >>> next(k[0]) 's' >>> next(k[0]) Traceback (most recent call last): File "", line 1, in next(k[0]) StopIteration So I may admit that I found the problem, but can't explain it to myself. Finally I've che
RE: Comprehension with two variables - explanation needed
Got the main idea. Still need to "chew it up" in depth. (As I mentioned I'm a beginner EE student, so please excuse me for my "lameness" ^_^) -Original Message- From: Python-list [mailto:python-list-bounces+webmailgroups=gmail@python.org] On Behalf Of Rustom Mody Sent: Sunday, November 23, 2014 18:46 To: python-list@python.org Subject: Re: Comprehension with two variables - explanation needed On Sunday, November 23, 2014 9:27:22 PM UTC+5:30, Roy Smith wrote: > Skip Montanaro wrote: > > > > But it breaks all the picture that I've built in my head about > > > comps till now... > > > > Note that list comprehensions are little more than syntactic sugar > > for for loops. If you're having terrible writing or understanding > > one, especially a compound one like your example, it can help to > > write it as a (nested) for loop, then covert it (perhaps incrementally) to the list comp form. > > Or not. If it was complicated enough that you needed to loopify it to > understand what it's doing, have pity on the next person who has to > maintain your code and leave it as a loop :-) > > My general rule for code hygiene is, "If I have to think about whether > something is too complicated, it is". [I guess I am in the minority here... anyways... here goes] 1. I find comprehensions are harder than for-loops -- corollary to functional code is easier than imperative -- corollary to time is a major headache. If the problem does not involve time the solution should try to avoid it 2. "List comprehensions are syntactic sugar for for loops" Cannot technically quarrel with that as that is the position of the official docs. However to me it puts the cart before the horse. Its like saying that def foo(x): return x+1 is just the same as 0 LOAD_FAST0 (x) 3 LOAD_CONST 1 (1) 6 BINARY_ADD 7 RETURN_VALUE (output of dis) That may be the case but it seems (to me at least) to defeat the purpose of using an hi-level language. 3. So how should one think of list comprehensions? As a python/executable version of 'set-builder notation' http://en.wikipedia.org/wiki/Set-builder_notation 4. Finally to the OP (assuming you wanted a prime-number generator) Heres a solution for your consideration. First a one-line solution in haskell sieve (p:xs) =p:sieve [x | x <- xs, x `mod` p /= 0] Call with sieve [2..] Now a pythonification of that def n2s(): # natural nos from 2; ie [2..] i=2 while True: yield i i+=1 def sieve(l): p = next(l) yield p yield from sieve (x for x in l if x % p != 0) Call as for p in sieve(n2s()): print(p) -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: Comprehension with two variables - explanation needed
>Is this what you want? > >>>> [[j for j in range(i*2, 50, i)] for i in range(2,8)] >[[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48], [6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48], [8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], [10, >15, 20, 25, 30, 35, 40, 45], [12, 18, 24, 30, 36, 42, 48], [14, 21, 28, 35, 42, 49]] >[I am not sure what you are trying -- just making local changes to the ZF to make it work] >https://mail.python.org/mailman/listinfo/python-list Yes, awesome. Thanks. But it breaks all the picture that I've built in my head about comps till now... As I know from books and googling, the comps main idea looks approximately like this: [target <--main loop<--nested loop/s (and maybe some conditions)]Am I right? But your code looks somehow inverted to me o_0 Like: [[target with nested loop] <--- main loop with initial values for target] On the other hand, if I'm comparing to my tryouts: noprimes = [[j for i in range(2, 8)] for j in range(i*2, 50, i)] It looks same but the variables are not separated, so it definitely was not defined Sincerely, Ivan -Original Message- From: Python-list [mailto:python-list-bounces+webmailgroups=gmail@python.org] On Behalf Of Rustom Mody Sent: Sunday, November 23, 2014 17:09 To: python-list@python.org Subject: Re: Comprehension with two variables - explanation needed On Sunday, November 23, 2014 8:28:16 PM UTC+5:30, Ivan Evstegneev wrote: > Hello guys, > > I would like to ask you for some explanations on comprehensions. > (Don't be scared, it just some particular example ^_^) > > I found this little "find prime number" example over the internet: > > >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] > >>> primes = [x for x in range(2, 50) if x not in noprimes] print > >>> primes > [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] > > > It looked pretty clear to me, till the time I decided to make some > changes to it %))) > > Ok this is the case: > > As you can see the first line's comprehension produces a list, that includes all the multiplications of "i" (that range(2,8) ) in range (i*2, 50, i). > So I get this pattern: noprimes = = [4, 6, 8.48, 6, 9,12 ]. > The change that I tried to apply to this comprehension would lead to > the following pattern: noprimes = = [[4, 6,8...48], [6, 9, 12], > ,[some numbers]] > > But despite my struggling on it for the whole day, I haven't got to > the desirable result(using comprehensions only) > > Please, don't get me wrong, I'm not a lazy one (just a beginner). > > In my case, I made some googling, and found some patterns for matrices, that look this one(for example): > > Matrix = [[0 for x in range(5)] for x in range(5)] > > But when I tried to use square brackets with my code, it yields an error about definition of "i", for instance: > > File "", line 1, in noprimes = [[j for i in > range(2, 8)] for j in range(i*2, 50, i)] > NameError: name 'i' is not defined. Is this what you want? >>> [[j for j in range(i*2, 50, i)] for i in range(2,8)] [[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48], [6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48], [8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48], [10, 15, 20, 25, 30, 35, 40, 45], [12, 18, 24, 30, 36, 42, 48], [14, 21, 28, 35, 42, 49]] [I am not sure what you are trying -- just making local changes to the ZF to make it work] -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Comprehension with two variables - explanation needed
Hello guys, I would like to ask you for some explanations on comprehensions. (Don't be scared, it just some particular example ^_^) I found this little "find prime number" example over the internet: >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] >>> primes = [x for x in range(2, 50) if x not in noprimes] >>> print primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] It looked pretty clear to me, till the time I decided to make some changes to it %))) Ok this is the case: As you can see the first line's comprehension produces a list, that includes all the multiplications of "i" (that range(2,8) ) in range (i*2, 50, i). So I get this pattern: noprimes = = [4, 6, 8...48, 6, 9,12.. ]. The change that I tried to apply to this comprehension would lead to the following pattern: noprimes = = [[4, 6,8.48], [6, 9, 12..], ..,[some numbers]] But despite my struggling on it for the whole day, I haven't got to the desirable result(using comprehensions only) Please, don't get me wrong, I'm not a lazy one (just a beginner). In my case, I made some googling, and found some patterns for matrices, that look this one(for example): Matrix = [[0 for x in range(5)] for x in range(5)] But when I tried to use square brackets with my code, it yields an error about definition of "i", for instance: File "", line 1, in noprimes = [[j for i in range(2, 8)] for j in range(i*2, 50, i)] NameError: name 'i' is not defined. Then I tried to apply those brackets to "j", like this: >>> noprimes = [[j] for i in range(2, 8) for j in range(i*2, 50, i)] In this case I get, pretty predictable result, like this: [[num], [num], [num],...,[num]], and this is still not what I'm looking for.. So I moved further, and succeeded to solve my problem in a different manner: >>> noprimes=[] >>> for i in range(2,8): noprimes.append(list(range(i*2,50,i))) Which yields, in fact, the matrix I wanted from the beginning: noprimes == [[4, 6, 8, 10, 12,.., 48], [6, 9, 12, 15, 18, ., 42, 45, 48],..,[numbers]] Yep, this the "classical" way for me, on the other hand I have the feeling, that this is not, the ultimate solution. ^_^ So my questions is still persists: 1) Is it possible to realize such a thing by applying changes only to initial comprehension? If yes, it would be nice to see the solution. 2) How actually bad is my solution? I mean, after all, there are nested functions call in my code, so how much the speed is affected(if any)? Thanks a lot in advance, Ivan. -- https://mail.python.org/mailman/listinfo/python-list
RE: Understanding "help" command description syntax - explanation needed
Chris, You got my point exactly. ^_^ This is not about a "range" command itself, but those conventions. Thanks. Larry, >> That's what I'm talking about (asking actually), where do you know it from? >>I know it because I've been a programmer for 39 years. I didn't intend to offence anyone here. Just asked a questions ^_^ -Original Message- From: Python-list [mailto:python-list-bounces+webmailgroups=gmail@python.org] On Behalf Of Chris Angelico Sent: Wednesday, November 5, 2014 14:16 Cc: python-list@python.org Subject: Re: Understanding "help" command description syntax - explanation needed On Wed, Nov 5, 2014 at 10:00 PM, Ivan Evstegneev wrote: > range(start, stop[, step]) -> range object > > For instance, how do I need to understand that (start,stop[,step]) > it’s just a three numbers? > > What do those brackets--> [,] mean? The docs for range() in Python 3 do need improvement, as Mark said, although there's a bit more info than you see there. The exact text varies from one version to another, but underneath that first line should be something like: "Return a virtual sequence of numbers from start to stop by step." That should tell you a bit more, at least. As to the brackets, they're a common convention meaning "optional". This is much bigger than Python, so it's not actually explained anywhere. (I've no idea where someone would go to try to find info on these sorts of conventions. It's a little hard to do a Google search for symbols and their usages. But that's what mailing lists like this are for.) You can create a range object with two arguments (start and stop) or three (start, stop, and step). When an argument is optional, it usually has a default, and in this case, the default step is 1 - every integer will be included. Don't be afraid to ask questions. There are plenty of people here who know both Python and C (I'm one of them), and we're happy to help out. And hey, you might find you can contribute a better piece of help text for something, and then we can make it better for every future wonderer :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: Understanding "help" command description syntax - explanation needed
Firtst of all thanks for reply. >>brackets [] means that the argument is optional. That's what I'm talking about (asking actually), where do you know it from? I mean, if there are some resources, which explain all these syntax abbreviations? The general concept. Like this one(just for example): class bytearray([source[, encoding[, errors]]]) --- What does it mean? Is that I can use it in optional way? Like: class bytearray(source) or class bytearray(encoding) ? or just write down all three of them? In which format do I do so? Sincerely, Ivan. -Original Message- From: Jean-Michel Pichavant [mailto:jeanmic...@sequans.com] Sent: Wednesday, November 5, 2014 13:55 To: Ivan Evstegneev Cc: python-list@python.org Subject: Re: Understanding "help" command description syntax - explanation needed Original Message - > From: "Ivan Evstegneev" > To: python-list@python.org > Sent: Wednesday, 5 November, 2014 12:00:16 PM > Subject: Understanding "help" command description syntax - explanation > needed So here is the question itself: > > If I use the help command to check the “range” command I get this > info: > > > > range(stop) -> range object > > range(start, stop[, step]) -> range object With python 2.7, when I type help(range), I get """ Help on built-in function range in module __builtin__: range(...) range([start,] stop[, step]) -> list of integers Return a list containing an arithmetic progression of integers. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0. When step is given, it specifies the increment (or decrement). For example, range(4) returns [0, 1, 2, 3]. The end point is omitted! These are exactly the valid indices for a list of 4 elements. """ range([start,] stop[, step]) tells you how to call the range function, there's a start, stop and step argument. The purpose of these arguments are given by the longer description. brackets [] means that the argument is optional. Though there's nothing wrong with googling the function for help, I'm doing it all the time. Actually, the python documentation is a better place to get help on a particular function, just make sure you hit the correct version, for either python 2 or 3: https://docs.python.org/2/library/functions.html#range I'm using python's help function only when working offline. JM -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -- https://mail.python.org/mailman/listinfo/python-list
Understanding "help" command description syntax - explanation needed
Hello everyone, I'm a Python beginner and just getting familiar with it. (I need it for my EE B.Sc. project) For the learning purposes I use IDLE and (Learning Python by written by Mark Lutz). Let's say that I have some earlier experience with C language, but still Python is a different one ))) Anyway, the question I would like to ask is about understanding "help" contents. It may look to obvious and even a dumb question, but still I need your help. Here is a brief background with example in order to introduce my problem in more clear way: Suppose I get some list created: >>>L=[i for i in range(1,15,2)] As it can be seen, this is the odd numbers list: [1, 3, 5, 7, 9, 11, 13] Supppose I need to check the occurrence of number 7, in this case I'll just write: >>>L.index(7) The result is :3 So here is the question itself: If I use the help command to check the "range" command I get this info: range(stop) -> range object range(start, stop[, step]) -> range object As you've seen in my example I used range(1,15,2). But this knowledge I got from googling a couple of sites. I still can't understand the "help" command description. For instance, how do I need to understand that (start,stop[,step]) it's just a three numbers? What do those brackets--> [,] mean? The same about "str.replace" command, where I get this: S.replace(old, new[, count]) - using this description I can't really understand how to write the "replace" function parameters. So I googled it up and found this example in order to get more clear understanding of command use. str = "this is string examplewow!!! this is really string" print str.replace("is", "was") print str.replace("is", "was", 3) The result: thwas was string examplewow!!! thwas was really string thwas was string examplewow!!! thwas is really string But still how do I know that those "old, new" are the strings and [,count] just a number? I mean, it was more naturally(as a baginner) to me to write str.replace(is,was[,3]) and that's all. Finally, as for my opinion, this is a lame way to learn "what a command do" by constantly googling it for examples. I need to get more familiar with "help", but the main problem, is that I couldn't find any suitable explanations/tutorials about "help" syntax and etc. (maybe didn't search well). Any explanations/links will be greatly appreciated. I need some help for "help" ^_^ Thanks in advance, Ivan. -- https://mail.python.org/mailman/listinfo/python-list