Re: [Tutor] question about descriptors

2015-11-11 Thread Albert-Jan Roskam
> Date: Sun, 8 Nov 2015 01:24:58 +1100
> From: st...@pearwood.info
> To: tutor@python.org
> Subject: Re: [Tutor] question about descriptors
> 
> On Sat, Nov 07, 2015 at 12:53:11PM +, Albert-Jan Roskam wrote:
> 
> [...]
> > Ok, now to my question. I want to create a class with read-only 
> > attribute access to the columns of a .csv file. E.g. when a file has a 
> > column named 'a', that column should be returned as list by using 
> > instance.a. At first I thought I could do this with the builtin 
> > 'property' class, but I am not sure how. 
> 
> 90% of problems involving computed attributes (including "read-only" 
> attributes) are most conveniently solved with `property`, but I think 
> this may be an exception. Nevertheless, I'll give you a solution in 
> terms of `property` first.
> 
> I'm too busy/lazy to handle reading from a CSV file, so I'll fake it 
> with a dict of columns.
 
Actually, I want to make this work for any iterable, as long as I can get the 
header names and as long as it returns one record per iteration.

 
> class ColumnView(object):
> _data = {'a': [1, 2, 3, 4, 5, 6],
>  'b': [1, 2, 4, 8, 16, 32],
>  'c': [1, 10, 100, 1000, 1, 10],
>  }
> @property
> def a(self):
> return self._data['a'][:]
> @property
> def b(self):
> return self._data['b'][:]
> @property
> def c(self):
> return self._data['c'][:]

Interesting. I never would have thought to define a separate class for this.
 
 
> And in use:
> 
> py> cols = ColumnView()
> py> cols.a
> [1, 2, 3, 4, 5, 6]
> py> cols.a = []
> Traceback (most recent call last):
>   File "", line 1, in ?
> AttributeError: can't set attribute
> 
> 
> 
> Now, some comments:
> 
> (1) You must inherit from `object` for this to work. (Or use Python 3.) 
> It won't work if you just say "class ColumnView:", which would make it a 
> so-called "classic" or "old-style" class. You don't want that.

Are there any use cases left where one still must use old-style classes? Or 
should new code always inherit from object (unless one want to inherit from 
another "true" class, of course).

 
> (2) Inside the property getter functions, I make a copy of the lists 
> before returning them. That is, I do:
> 
> return self._data['c'][:]
> 
> rather than:
> 
> return self._data['c']
> 
> 
> The empty slice [:] makes a copy. If I did not do this, you could mutate 
> the list (say, by appending a value to it, or deleting items from it) 
> and that mutation would show up the next time you looked at the column.

These mutability problems always make me pull my hair out! :-) I like the [:] 
notation, but: 

In [1]: giant = range(10 ** 7)

In [2]: %timeit copy1 = giant[:]
10 loops, best of 3: 97 ms per loop

In [3]: from copy import copy

In [4]: %timeit copy2 = copy(giant)
10 loops, best of 3: 90 ms per loop

In [5]: import copy

In [6]: %timeit copy2 = copy.copy(giant)
10 loops, best of 3: 88.6 ms per loop

Hmmm, wicked, when I looked earlier this week the difference appear to be 
bigger.

 
> (3) It's very tedious having to create a property for each column ahead 
> of time. But we can do this instead:
> 
> 
> def make_getter(key):
> def inner(self):
> return self._data[key][:]
> inner.__name__ = key
> return property(inner)
> 
> 
> class ColumnView(object):
> _data = {'a': [1, 2, 3, 4, 5, 6],
>  'b': [1, 2, 4, 8, 16, 32],
>  'c': [1, 10, 100, 1000, 1, 10],
>  }
> for key in _data:
> locals()[key] = make_getter(key)
> del key
> 
> 
> and it works as above, but without all the tedious manual creation of 
> property getters.
> 
> Do you understand how this operates? If not, ask, and someone will 
> explain. (And yes, this is one of the few times that writing to locals() 
> actually works!)

I think so. I still plan to write several working implementations to get a 
better idea about which strategy to  choose. 
 
> (4) But what if you don't know what the columns are called ahead of 
> time? You can't use property, or descriptors, because you don't know 
> what to call the damn things until you know what the column headers are, 
> and by the time you know that, the class is already well and truly 
> created. You might think you can do this:
> 
> class ColumnView(object):
> def __init__(self):
> # read the columns from the CSV file
> self._data = ...
> # now create properties to suit
> for key in self._data:
> setattr(self, key, property( ... ))
> 
> 
> but that doesn't work. Properties only perform their "magic" when they 
> are attached to the class itself. By setting them as attributes on the 
> instance (self), they lose their power and just get treated as ordinary 
> attributes. To be technical, we say that the descriptor protocol is only 
> enacted when the attribute is found in the class, not in the instance.

Ha! That is indeed exactly 

[Tutor] Python on Android (was Re: Tutor Digest, Vol 141, Issue 11)

2015-11-11 Thread Alan Gauld

On 11/11/15 12:18, Burhan ul haq wrote:


I have already tried "pythonanywhere" but could not get it going, even for
a basic "hello world" script.


Create a beginner account and login.
Select the type of user you want - beginner Python in your case
Select which Python version - 2.7 in your case
A console will appear in the browser.

Obviously being web based not all modules will work or be available
but the bssic Python commands and modules will be fine. If your course 
gets machine specific (like the os module) then things may be less than 
ideal.


HTH

PS
Please don't reply to a digest without first changing the subject line
and deleting all the irrelevant stuff. Some people pay by the byte
and all of us have already seen the digest material at least
once already.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Tutor Digest, Vol 141, Issue 11

2015-11-11 Thread Burhan ul haq
Continuing "Run Python 2.7 on Android Tablet"

Hi,

I am constrained to install anything on my official laptop, therefore I
need to have an "online life saver" for Python Learning.

I have already tried "pythonanywhere" but could not get it going, even for
a basic "hello world" script. I could not locate any basic documentation to
help me with. The basic help tab "I want to start learning Python
" bring
you back to the main dashboard.

Can anybody share a basic how to get started ...

Many Thanks /



On Wed, Nov 11, 2015 at 1:34 PM,  wrote:

> Send Tutor mailing list submissions to
> tutor@python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
> tutor-requ...@python.org
>
> You can reach the person managing the list at
> tutor-ow...@python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
>
> Today's Topics:
>
>1. Run Python 2.7 on Android Tablet (Ken Hammer)
>2. Re: Run Python 2.7 on Android Tablet (Alan Gauld)
>3. Re: Run Python 2.7 on Android Tablet (Laura Creighton)
>4. Re: Run Python 2.7 on Android Tablet (memilanuk)
>5. Re: question about descriptors (Albert-Jan Roskam)
>6. Re: question about descriptors (Albert-Jan Roskam)
>
>
> --
>
> Message: 1
> Date: Tue, 10 Nov 2015 12:38:27 -0500
> From: "Ken Hammer"
> To: tutor@python.org
> Subject: [Tutor] Run Python 2.7 on Android Tablet
> Message-ID: 
>
>
> My MIT OCW 6.00SC course is installed on a Windows 8.1 desktop machine.
>
> I'd like to study and explore away from my office and desk on my tablet
> running Android 4.2.2.  Possible?
>
> thanks,  Ken
>
>
>
> --
>
> Message: 2
> Date: Tue, 10 Nov 2015 21:07:07 +
> From: Alan Gauld 
> To: tutor@python.org
> Subject: Re: [Tutor] Run Python 2.7 on Android Tablet
> Message-ID: 
> Content-Type: text/plain; charset=utf-8; format=flowed
>
> On 10/11/15 17:38, Ken Hammer wrote:
> >
> > My MIT OCW 6.00SC course is installed on a Windows 8.1 desktop machine.
> >
> > I'd like to study and explore away from my office and desk on my tablet
> running Android 4.2.2.  Possible?
>
> I can't comment on your course but you can install Python on Android and
> for basic programming tasks it works just like any other Python.
> I use QPython FWIW but I think there are others too.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
>
>
> --
>
> Message: 3
> Date: Tue, 10 Nov 2015 22:32:27 +0100
> From: Laura Creighton 
> To: Ken Hammer 
> Cc: tutor@python.org, l...@openend.se
> Subject: Re: [Tutor] Run Python 2.7 on Android Tablet
> Message-ID: <201511102132.taalwrtp022...@fido.openend.se>
> Content-Type: text/plain; charset="us-ascii"
>
> In a message of Tue, 10 Nov 2015 12:38:27 -0500, "Ken Hammer" writes:
> >
> >
> >My MIT OCW 6.00SC course is installed on a Windows 8.1 desktop machine.
> >
> >I'd like to study and explore away from my office and desk on my tablet
> running Android 4.2.2.  Possible?
> >
> >thanks,  Ken
>
> Yes.
> use Python Anywhere in a browser on your tablet.
>
> https://www.pythonanywhere.com/
>
> Laura
>
>
> --
>
> Message: 4
> Date: Tue, 10 Nov 2015 14:10:04 -0800
> From: memilanuk 
> To: tutor@python.org
> Subject: Re: [Tutor] Run Python 2.7 on Android Tablet
> Message-ID: 
> Content-Type: text/plain; charset=windows-1252; format=flowed
>
> On 11/10/2015 01:32 PM, Laura Creighton wrote:
> > In a message of Tue, 10 Nov 2015 12:38:27 -0500, "Ken Hammer" writes:
> >>
> >>
> >> My MIT OCW 6.00SC course is installed on a Windows 8.1 desktop machine.
> >>
> >> I'd like to study and explore away from my office and desk on my tablet
> running Android 4.2.2.  Possible?
> >>
> >> thanks,  Ken
> >
> > Yes.
> > use Python Anywhere in a browser on your tablet.
> >
> > https://www.pythonanywhere.com/
> >
>
> > https://mail.python.org/mailman/listinfo/tutor
> >
>
> Or koding.io... but PythonAnywhere is nicer for straight-up python.
>
> --
> Shiny!  Let's be bad guys.
>
> Reach me @ memilanuk (at) gmail dot com
>
>
>
> --
>
> Message: 5
> Date: Wed, 11 Nov 2015 08:08:46 +
> From: Albert-Jan Roskam 
> To: Peter Otten <__pete...@web.de>, "tutor@python.org"
> 
> 

Re: [Tutor] Tutor Digest, Vol 141, Issue 11

2015-11-11 Thread Danny Yoo
On Wed, Nov 11, 2015 at 4:18 AM, Burhan ul haq  wrote:
> Continuing "Run Python 2.7 on Android Tablet"
>
> Hi,
>
> I am constrained to install anything on my official laptop, therefore I
> need to have an "online life saver" for Python Learning.


You might look into repl.it:

https://repl.it/languages/python

For example:

https://repl.it/BZUA


You'll get a basic Python REPL that you can use from the web.  Helpful
in situations like the one you're describing.  I wouldn't use it for
important work, but for learning or exploratory programming, it's
probably good enough.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Tutor Digest, Vol 141, Issue 11

2015-11-11 Thread Danny Yoo
>> I am constrained to install anything on my official laptop, therefore I
>> need to have an "online life saver" for Python Learning.
>
>
> You might look into repl.it:
>
> https://repl.it/languages/python



As for tutorial material, you might look into:

https://wiki.python.org/moin/BeginnersGuide/NonProgrammers


Learn to Program, by Alan Gauld, is an example of a tutorial that you
might enjoy:

http://www.alan-g.me.uk/tutor/index.htm





>
> For example:
>
> https://repl.it/BZUA
>
>
> You'll get a basic Python REPL that you can use from the web.  Helpful
> in situations like the one you're describing.  I wouldn't use it for
> important work, but for learning or exploratory programming, it's
> probably good enough.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Newbie Question

2015-11-11 Thread George Henry
How do I find a site to download Python for Windows that includes a Toolbar?

I'm using Windows 8.1  Have tried installing Python 3.4.2 but notice that
the Python shell does not include a tool bar (i.e. File, Edit, Shell, Debug,
etc.).

 

Help please.

 

Thanks!

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Newbie Question

2015-11-11 Thread Mark Lawrence

On 11/11/2015 19:38, George Henry wrote:

How do I find a site to download Python for Windows that includes a Toolbar?

I'm using Windows 8.1  Have tried installing Python 3.4.2 but notice that
the Python shell does not include a tool bar (i.e. File, Edit, Shell, Debug,
etc.).

Help please.

Thanks!



So IDLE is not good enough for you?  I'll let you find it as it's part 
of the standard library, i.e. you've all ready downloaded it.


--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about descriptors

2015-11-11 Thread Peter Otten
Albert-Jan Roskam wrote:

>> class ReadColumn(object):
>> def __init__(self, index):
>> self._index = index
>> def __get__(self, obj, type=None):
>> return obj._row[self._index]
>> def __set__(self, obj, value):
>> raise AttributeError("oops")
> 
> This appears to return one value, whereas I wanted I wanted to return all
> values of a column, ie as many values as there are rows. But the logic
> probably won't change. 

Sorry, I overlooked that aspect. If you want a whole column you either have 
to iterate over the complete file and keep the data in memory or you need a 
separate file descriptor for every access of a column. Here's an 
implementation of the first:

def csv_columns(instream):
reader = csv.reader(instream, delimiter=";")

header = next(reader)
return namedtuple("Columns", header)._make(tuple(zip(*reader)))



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about descriptors

2015-11-11 Thread Peter Otten
Albert-Jan Roskam wrote:

>> From: st...@pearwood.info

>> Fortunately, Python has an mechanism for solving this problem:
>> the `__getattr__` method and friends.
>> 
>> 
>> class ColumnView(object):
>> _data = {'a': [1, 2, 3, 4, 5, 6],
>>  'b': [1, 2, 4, 8, 16, 32],
>>  'c': [1, 10, 100, 1000, 1, 10],
>>  }
>> def __getattr__(self, name):
>> if name in self._data:
>> return self._data[name][:]
>> else:
>> raise AttributeError
>> def __setattr__(self, name, value):
>> if name in self._data:
>> raise AttributeError('read-only attribute')
>> super(ColumnView, self).__setattr__(name, value)
>> def __delattr__(self, name):
>> if name in self._data:
>> raise AttributeError('read-only attribute')
>> super(ColumnView, self).__delattr__(name)
> 
> That also seems very straightforward. Why does "if name in self._data:"
> not cause a recursion? self._data calls __getattr__, which has self._data
> in it, which...etc.

__getattr__() is only invoked as a fallback when the normal attribute lookup 
fails:

>>> class A(object):
... def __getattr__(self, name):
... return self.data[name]
... 
>>> a = A()
>>> a.data = dict(foo="bar")
>>> a.foo
'bar'
>>> del a.data
>>> import sys
>>> sys.setrecursionlimit(10)
>>> a.foo
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 3, in __getattr__
  File "", line 3, in __getattr__
  File "", line 3, in __getattr__
RuntimeError: maximum recursion depth exceeded while calling a Python object

If you need to intercept every attribute lookup use __getattribute__():

>>> class B(A):
... def __getattribute__(self, name):
... print "looking for", name
... return super(B, self).__getattribute__(name)
... 
>>> b = B()
>>> b.data = dict(foo="bar")
>>> b.foo
looking for foo
looking for data
'bar'


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Newbie Question

2015-11-11 Thread Albert-Jan Roskam
Hi,

(Sorry for top-postin - I am using my phone).

You can try Spyder IDE, it is part of Anaconda and Python(x, y): 
https://pythonhosted.org/spyder/installation.html#installing-on-windows-vista-7-8-10

Regards,
Albert-Jan

> From: gfhenry1...@gmail.com
> To: tutor@python.org
> Date: Wed, 11 Nov 2015 11:38:47 -0800
> Subject: [Tutor] Newbie Question
> 
> How do I find a site to download Python for Windows that includes a Toolbar?
> 
> I'm using Windows 8.1  Have tried installing Python 3.4.2 but notice that
> the Python shell does not include a tool bar (i.e. File, Edit, Shell, Debug,
> etc.).
> 
>  
> 
> Help please.
> 
>  
> 
> Thanks!
> 
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about descriptors

2015-11-11 Thread Albert-Jan Roskam


 
> I think the basic misunderstandings are that 
> 
> (1) the __get__() method has to be implemented by the descriptor class
> (2) the descriptor instances should be attributes of the class that is 
> supposed to invoke __get__(). E. g.:
> 
> class C(object):
>x = decriptor()
> 
> c = C()
> 
> c.x # invoke c.x.__get__(c, C) under the hood.

Exactly right, that was indeed my misunderstanding! I was thinking about 
__get__ and __set__ in the same terms as e.g. __getitem__ and __setitem__

 
> As a consequence you need one class per set of attributes, instantiating the 
> same AttrAccess for csv files with differing layouts won't work.

That is no problem at all for me. One instance per file will be fine.


> Here's how to do it all by yourself:
> 
> class ReadColumn(object):
> def __init__(self, index):
> self._index = index
> def __get__(self, obj, type=None):
> return obj._row[self._index]
> def __set__(self, obj, value):
> raise AttributeError("oops")

This appears to return one value, whereas I wanted I wanted to return all 
values of a column, ie as many values as there are rows.
But the logic probably won't change. Same applies to the use of namedtuple, I 
suppose (?). I have never used namedtuple like namedtuple("Column", 
self.header)(*self.columns).

 
> def first_row(instream):
> reader = csv.reader(instream, delimiter=";")
> 
> class Row(object):
> def __init__(self, row):
> self._row = row
> 
> for i, header in enumerate(next(reader)):
> setattr(Row, header, ReadColumn(i))
> 
> return Row(next(reader))
> 
> 
> f = StringIO("a;b;c\n1;2;3\n4;5;6\n7;8;9\n")
> row = first_row(f)
> print row.a
> row.a = 42
> 
> Instead of a custom descriptor you can of course use the built-in property:
> 
> for i, header in enumerate(next(reader)):
> setattr(Row, header, property(lambda self, i=i: self._row[i]))

This seems most attractive/straightforward to me.

> In many cases you don't care about the specifics of the row class and use 
> collections.namedtuple:
> 
> 
> def rows(instream):
> reader = csv.reader(instream, delimiter=";")
> Row = collections.namedtuple("Row", next(reader))
> return itertools.imap(Row._make, reader)
> 
> 
> f = StringIO("a;b;c\n1;2;3\n4;5;6\n7;8;9\n")
> row = next(rows(f))
> print row.a
> row.a = 42

Thanks a lot for helping me!


  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor