RE: How to reassign the value of the variable on runtime?

2015-08-29 Thread Ivan Evstegneev


-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?

2015-08-27 Thread Ivan Evstegneev


-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?

2015-08-27 Thread Ivan Evstegneev
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

2015-03-26 Thread Ivan Evstegneev


> -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

2015-03-25 Thread Ivan Evstegneev


> -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

2015-03-25 Thread Ivan Evstegneev
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

2015-03-25 Thread Ivan Evstegneev
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

2015-03-25 Thread Ivan Evstegneev
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)

2014-12-19 Thread Ivan Evstegneev
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.

2014-12-17 Thread Ivan Evstegneev
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.

2014-12-15 Thread Ivan Evstegneev
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.

2014-12-14 Thread Ivan Evstegneev
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.

2014-12-14 Thread Ivan Evstegneev
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

2014-12-07 Thread Ivan Evstegneev
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

2014-12-07 Thread Ivan Evstegneev
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

2014-12-07 Thread Ivan Evstegneev
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

2014-12-07 Thread Ivan Evstegneev
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

2014-11-23 Thread Ivan Evstegneev
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

2014-11-23 Thread Ivan Evstegneev
>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

2014-11-23 Thread Ivan Evstegneev
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

2014-11-05 Thread Ivan Evstegneev
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

2014-11-05 Thread Ivan Evstegneev
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

2014-11-05 Thread Ivan Evstegneev
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