Re: [Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Arup Rakshit

On 23/04/19 10:08 PM, Steven D'Aprano wrote:

On Tue, Apr 23, 2019 at 08:27:15PM +0530, Arup Rakshit wrote:


You probably want:

      def __init__(self, list=None):
  if list is None:
      list = []
  self.list = list

That is really a new thing to me. I didn't know. Why list=None in the
parameter list is different than in the body of __init__ method? Can you
elaborate this?

Try running this code and see what happens:

def make_default():
 print("creating a new list")
 return []


def function(arg=make_default()):
 arg.append(1)
 return arg


Now call:


function()
function()
function()


and see if you can work out what is happening.

Hint: how many new lists are created? when are they created?




Hello,

You are right. I didn't think on it, as it feels to me very natural as 
per the experiences from other language like Ruby, JS. It works 
differently there.


A similar Ruby code gives different output than Python does.

def make_default()
  print("creating a new list")
  return []
end

def function(arg=make_default())
  arg.push(1)
  return arg
end

# Now call:

p(function())
p(function())
p(function())

And on run:

ruby -v sample.rb
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]
creating a new list[1]
creating a new list[1]
creating a new list[1]

But python gives to me:

creating a new list
[1]
[1, 1]
[1, 1, 1]

Python being an interpreted language works so differently than its other 
2 siblings Ruby, JS. Surprised.


--
Thanks,

Arup Rakshit

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


Re: [Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Steven D'Aprano
On Tue, Apr 23, 2019 at 08:27:15PM +0530, Arup Rakshit wrote:

> >You probably want:
> >
> >      def __init__(self, list=None):
> >  if list is None:
> >      list = []
> >  self.list = list
> 
> That is really a new thing to me. I didn't know. Why list=None in the 
> parameter list is different than in the body of __init__ method? Can you 
> elaborate this?

Try running this code and see what happens:

def make_default():
print("creating a new list")
return []


def function(arg=make_default()):
arg.append(1)
return arg


Now call:


function()
function()
function()


and see if you can work out what is happening.

Hint: how many new lists are created? when are they created? 



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


Re: [Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Mats Wichmann
On 4/23/19 8:57 AM, Arup Rakshit wrote:
> On 23/04/19 3:40 PM, Steven D'Aprano wrote:
>> Watch out here, you have a mutable default value, that probably doesn't
>> work the way you expect. The default value is created ONCE, and then
>> shared, so if you do this:
>>
>> a = MyCustomList()  # Use the default list.
>> b = MyCustomList()  # Shares the same default list!
>> a.append(1)
>> print(b.list)
>> # prints [1]
>>
>> You probably want:
>>
>>       def __init__(self, list=None):
>>   if list is None:
>>       list = []
>>   self.list = list
> 
> That is really a new thing to me. I didn't know. Why list=None in the
> parameter list is different than in the body of __init__ method? Can you
> elaborate this?
> 

It arises because a function definition is an executable statement, run
right then.  So a default value in the parameter list is created right
then, and then used as needed, and if that default is a mutable (list,
dictionary, etc) you get surprises.  When an empty list is created in
the body, it happens each time the function object is called (it's a
method, but it's still just a function object). You can write some
experiments to show yourself this in action, it usually makes it sink in
more than someone telling you.

And don't worry, this is one of the most famous of all Python beginner
traps, we've all fallen in it.


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


Re: [Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Arup Rakshit

On 23/04/19 3:40 PM, Steven D'Aprano wrote:

Watch out here, you have a mutable default value, that probably doesn't
work the way you expect. The default value is created ONCE, and then
shared, so if you do this:

a = MyCustomList()  # Use the default list.
b = MyCustomList()  # Shares the same default list!
a.append(1)
print(b.list)
# prints [1]

You probably want:

      def __init__(self, list=None):
  if list is None:
      list = []
  self.list = list


That is really a new thing to me. I didn't know. Why list=None in the 
parameter list is different than in the body of __init__ method? Can you 
elaborate this?


--
Thanks,

Arup Rakshit

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


Re: [Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Steven D'Aprano
On Tue, Apr 23, 2019 at 11:46:58AM +0530, Arup Rakshit wrote:
> Hi,
> 
> I wrote below 2 classes to explore how __getitem__(self,k) works in 
> conjuection with list subscriptions. Both code works. Now my questions 
> which way the community encourages more in Python: if isinstance(key, 
> slice): or if type(key) == slice: ?

In general, we should normally use `isinstance`, because it works with 
subclasses.

But `slice` can't be subclassed:

py> class S(slice):
... pass
...
Traceback (most recent call last):
  File "", line 1, in 
TypeError: type 'slice' is not an acceptable base type


so there is no advantage to using `isinstance`. (There is no 
disadvantage either.)

I would use `type(key) is slice` to guarantee[1] that the key is 
certainly a slice.

Why use `is` instead of `==`?

The `is` operator will be a tiny bit faster than `==`, but more 
importantly, you could have a class designed to pretend to be a slice. 
It isn't easy to do (you would have to write a metaclass, which makes it 
an advanced technique) but by using `is` we can eliminate even that slim 
chance.


> How should I implement this if I 
> follow duck typing, because none of the code currently I wrote using 
> duck typing techiniqe IMO.


Why bother? Duck-typing is good for *data* values, but a slice is not a 
data value, it is a way of specifying a range of indexes.


> class MyCustomList:
>     def __init__(self, list = []):
>     self.list = list

Watch out here, you have a mutable default value, that probably doesn't 
work the way you expect. The default value is created ONCE, and then 
shared, so if you do this:

a = MyCustomList()  # Use the default list.
b = MyCustomList()  # Shares the same default list!
a.append(1)
print(b.list)
# prints [1]

You probably want:

     def __init__(self, list=None):
 if list is None:
     list = []
 self.list = list


>     def __getitem__(self, key):
>     if isinstance(key, slice):
>     return self.list[key]
>     else:
>     return self.list[key]


The "isinstance" check is useless, because you do precisely the same 
thing in both branches.

    def __getitem__(self, key):
 return self.list[key]


will do exactly the same, and more efficiently.






[1] Not actually a guarantee.


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


Re: [Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Alan Gauld via Tutor
On 23/04/2019 07:16, Arup Rakshit wrote:
> which way the community encourages more in Python: if isinstance(key, 
> slice): or if type(key) == slice: ?

I think isinstance is usually preferred although I confess
that I usually forget and use type()... But isinstance covers
you for subclasses too.

> class MyCustomList:
>      def __init__(self, list = []):
>      self.list = list
> 
>      def __getitem__(self, key):
>      if isinstance(key, slice):
>      return self.list[key]
>      else:
>      return self.list[key]

The if/else test is meaningless since you return self.list[key]
in both cases. You would be better off just calling it directly
(and maybe wrapping that in a try block?)

  def __getitem__(self, key):
  try:
  return self.list[key]
  except :

Assuming you can think of something useful to put in the
except clause. Otherwise just let Python raise the exception
and leave the user of the class to worry about what to do.


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


[Tutor] Question on implmenting __getitem__ on custom classes

2019-04-23 Thread Arup Rakshit

Hi,

I wrote below 2 classes to explore how __getitem__(self,k) works in 
conjuection with list subscriptions. Both code works. Now my questions 
which way the community encourages more in Python: if isinstance(key, 
slice): or if type(key) == slice: ? How should I implement this if I 
follow duck typing, because none of the code currently I wrote using 
duck typing techiniqe IMO.


class MyCustomList:
    def __init__(self, list = []):
    self.list = list

    def __getitem__(self, key):
    if isinstance(key, slice):
    return self.list[key]
    else:
    return self.list[key]

class MyCustomListV1:
    def __init__(self, list = []):
    self.list = list

    def __getitem__(self, key):
    if type(key) == slice:
    return self.list[key]
    else:
    return self.list[key]

if __name__ == '__main__':
    list = MyCustomList(list=[1, 2, 3, 4, 5, 6])
    print(list[1:3])
    print(list[3])
    print("===\n")
    list = MyCustomListV1(list=[1, 2, 3, 4, 5, 6])
    print(list[1:3])
    print(list[3])

If run it, I get the output:

[2, 3]
4
===

[2, 3]
4

--
Thanks,

Arup Rakshit

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


Re: [Tutor] Question about the object.__del__(self) method

2019-04-22 Thread Arup Rakshit

On 22/04/19 3:35 PM, Alan Gauld via Tutor wrote:

On 22/04/2019 10:18, Arup Rakshit wrote:

Consider the below in simple class:

class RandomKlass:
 def __init__(self, x):
 self.x = x
 
 def __del__(self):

 print("Deleted…")

Now when I delete the object created from RandomKlass using `del` operator I 
see the output “Deleted…”. That means `del` operator calls the __del__ method 
if available.

No it doesn't, it just means that is what seemed to
happen in this specific scenario.

Now try:



from python_methods import RandomKlass
o1 = RandomKlass(10)
o2 = o1
oblist = [o1,o2]
del(o1)
del(o2)
del(oblist)

Deleted...

So your __del__() is only called once, after all the
references to the instance have been deleted.


Also what the reference count here means?
I know that x can hold only one reference at a time.

Remember that variables in Python are just names that
refer to objects. So, while the name 'x' can only refer
to one object at a time, many other names can also refer
to that same object, as in the example above.
o1, o2 and oblist[0] and oblist[1] all refer to
the same original instance of your class.

Each time a new variable references the instance an
internal "reference count" is incremented. When a referring
name is deleted the reference count is decremented.
Once the count reaches zero the instance is deleted
and its __del__() method, if it exists, is called.
So, only when all the names referring to the instance
have been deleted is the __del__() method called. (And it
is important to realise that there are cases where
__del__() is never called. Do not rely on __del__()
for any critical actions - such as saving instance
data or shutting down the nuclear reactor.)


Hello Alan,

Nice explanation. I completly got what is going on. Closing the question 
here. :)


--
Thanks,

Arup Rakshit

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


Re: [Tutor] Question about the object.__del__(self) method

2019-04-22 Thread Alan Gauld via Tutor
On 22/04/2019 10:18, Arup Rakshit wrote:
> Consider the below in simple class:
> 
> class RandomKlass:
> def __init__(self, x):
> self.x = x
> 
> def __del__(self):
> print("Deleted…")
> 
> Now when I delete the object created from RandomKlass using `del` operator I 
> see the output “Deleted…”. That means `del` operator calls the __del__ method 
> if available.

No it doesn't, it just means that is what seemed to
happen in this specific scenario.

Now try:


>>> from python_methods import RandomKlass
>>> o1 = RandomKlass(10)
>>> o2 = o1
>>> oblist = [o1,o2]
>>> del(o1)
>>> del(o2)
>>> del(oblist)
Deleted...

So your __del__() is only called once, after all the
references to the instance have been deleted.

> Also what the reference count here means? 
> I know that x can hold only one reference at a time.

Remember that variables in Python are just names that
refer to objects. So, while the name 'x' can only refer
to one object at a time, many other names can also refer
to that same object, as in the example above.
o1, o2 and oblist[0] and oblist[1] all refer to
the same original instance of your class.

Each time a new variable references the instance an
internal "reference count" is incremented. When a referring
name is deleted the reference count is decremented.
Once the count reaches zero the instance is deleted
and its __del__() method, if it exists, is called.
So, only when all the names referring to the instance
have been deleted is the __del__() method called. (And it
is important to realise that there are cases where
__del__() is never called. Do not rely on __del__()
for any critical actions - such as saving instance
data or shutting down the nuclear reactor.)

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


[Tutor] Question about the object.__del__(self) method

2019-04-22 Thread Arup Rakshit
Consider the below in simple class:

class RandomKlass:
def __init__(self, x):
self.x = x

def __del__(self):
print("Deleted…")

Now when I delete the object created from RandomKlass using `del` operator I 
see the output “Deleted…”. That means `del` operator calls the __del__ method 
if available.

from python_methods import RandomKlass
obj = RandomKlass(10)
del obj
# Deleted...
obj = RandomKlass(10)
obj1 = RandomKlass(10)
del obj
# Deleted...
del obj1
# Deleted...

Now why then the doc 
https://docs.python.org/3/reference/datamodel.html#object.__del__ says:

>   `del x` doesn’t directly call `x.__del__()` — the former decrements the 
> reference count for `x`  by one, and the latter is only called when `x`’s 
> reference count reaches zero.

Also what the reference count here means? I know that x can hold only one 
reference at a time.

Thanks,

Arup Rakshit
a...@zeit.io



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


Re: [Tutor] Question for tutoring page

2019-03-16 Thread Albert-Jan Roskam



On 13 Mar 2019 18:14, Alan Gauld via Tutor  wrote:

On 11/03/2019 16:10, Diana Katz wrote:
> What is the best way to ..program using python - that could recognize
> a 3D object and then rank drawings of the object as to which are more
> accurate.

===>> check this out: 
https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html

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


Re: [Tutor] Question for tutoring page

2019-03-13 Thread Abdur-Rahmaan Janhangeer
I'll outline what you need


those types of recognition are done by machine learning, just some maths
using computation.

You normally give your program some images to train. Instead of letting the
program to figure out by itself, you give it some realistic drawings, the
best of the bunch and a picture of the real thing. It will then compare the
difference between the real picture and the drawings and get an idea of
what good drawings are. If you have some 40 pics, you use 30 to train and
some 10 to test.

Now when you use the program, when you throw at it a new drawing, it will
rank it based on what it learnt.

For the raspberry pi part i think it's convenient to move around but not
really needed.

>From my experience with these kinds of projects, google "image recognition
with python" maybe you'll see opencv etc. before that just make sure to
learn at least some basic python. Then you google concepts you don't know.
little by little, you'll understand what's going on. like take an image
recognition tutorial with image set provided and complete it. That approach
is better than taking a machine learning tutorial etc.

Should you need any help, please tell! I don't promise but i'll try to
write such a project as a tutorial.

Yours,

Abdur-Rahmaan Janhangeer
http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ
Mauritius
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question for tutoring page

2019-03-13 Thread Alan Gauld via Tutor
On 11/03/2019 16:10, Diana Katz wrote:
> What is the best way to ..program using python - that could recognize 
> a 3D object and then rank drawings of the object as to which are more 
> accurate. 

I notice nobody has responded so I thought I'd let you
know your mail was received.

Unfortunately what you ask is extremely specialised and
quite advanced so I suspect nobody on the list feels
competent to advise you - I certainly don't!

> It was suggested to us to use raspberry pi and python 

The type of computer is unlikely to make much difference.
But how do you plan on "recognising" these shapes? Do
you have image files or are you expecting it to do some
optical scanning from a camera or similar?

> and perhaps tweak existing apps. 

That's good advise if you can find any suitable apps to tweak
that are both open source and written in Python. Personally
I don't know of anything remotely like what you suggest!

I assume you are already a competent programmer in some kind
of language (Python, PHP, Javascript, Java, VB, C++?)already?
If not, this is an extremely challenging first project!
(Even assuming you can find a starting point and don't have
to write it from scratch.)

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


[Tutor] Question for tutoring page

2019-03-11 Thread Diana Katz
Hi,

What is the best way to create an artificial intelligence program using python 
- that could recognize a 3D object and then rank drawings of the object as to 
which are more accurate. It was suggested to us to use raspberry pi and python 
and perhaps tweak existing apps. Any help as to how to start this project and 
the best method would be greatly appreciated.

Best,
Diana 

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


Re: [Tutor] Question

2018-08-21 Thread Alan Gauld via Tutor
On 21/08/18 12:16, Jacob Braig wrote:
> I am just starting out coding and decided on python. 

It looks like you are using Python v2 (maybe v2.7?) but
the latest version is 3.7 and for beginners we normally
recommend adopting v3. It doesn't change anything much
in this case but it saves you relearning too much later
if you decide to switch.

> python better but the code I have now keeps popping up an error 

Always include the full error text so we don't
need to guess. It contains a lot of useful information.

> AMMO = " This is how much ammo remains for .40 pistol %s. "
> 
> print "Program has started."
> 
> ammopistol = raw_input("Enter total ammo before use. ")

raw_input() does what it says, it reads the raw characters
typed at the keyboard. It does not try to guess what they
are - in this case numbers - it just stores them as a
character string.

You need to convert them to the type of data you need.

ammopistol = int( raw_input("Enter total ammo before use. ") )

> ammopused = raw_input("Enter total ammo used. ")

same here

> ammopleft = ammopistol - ammopused

You cannot subtract character strings so you got an
error, but once you convert the data it should work.

> print AMMO % (ammopistol, ammopused,) ammoleft

This won't work however.
Your AMMO string has one % placeholder in it so it
expects exactly 1 value on the right of the % sign.
You are providing a tuple of two values. Then you add
a third value that's not in the tuple and is invalid
syntax in Python. Python won't know what to do and
you will get another error.

You really want something like

print AMMO % ammoleft

HTH

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

2018-08-21 Thread Steven D'Aprano
On Tue, Aug 21, 2018 at 05:16:35AM -0600, Jacob Braig wrote:

> I am having issues with " ammopleft = ammopistol - ammopused "  any idea
> where I have gone wrong?

What sort of issues? Should we try to guess, or would you like to tell 
us?

I'm reminded of a joke... 

A man goes to the doctor.

Doctor: "So what seems to be the problem?"

Man: "You're the doctor, you tell me."



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


Re: [Tutor] Question

2018-08-21 Thread Timo

Op 21-08-18 om 13:16 schreef Jacob Braig:

I am just starting out coding and decided on python. I am confused with
something I go shooting a lot so i wanted to make some stupid easy
calculator for ammo and slowly build the program up when I understand
python better but the code I have now keeps popping up an error and I don't
understand where i went wrong a little help please.
Here is the code like I said very simple stuff.

"""
  This is a simple program for ammo calculation.
  Created by Jacob
"""
AMMO = " This is how much ammo remains for .40 pistol %s. "

print "Program has started."

ammopistol = raw_input("Enter total ammo before use. ")
ammopused = raw_input("Enter total ammo used. ")
ammopleft = ammopistol - ammopused

print AMMO % (ammopistol, ammopused,) ammoleft

I am having issues with " ammopleft = ammopistol - ammopused "  any idea
where I have gone wrong?

Always include the full traceback (error message).

The problem is that raw_input() returns a string, so you are doing 
something like "10" - "2" instead of 10 - 2 for example. The error 
message should have told you so:

    TypeError: unsupported operand type(s) for -: 'str' and 'str'

The solution is to cast these inputs to integers, either directly during 
input:

    ammopistol = int(raw_input("Enter total ammo before use. "))
    ammopused = int(raw_input("Enter total ammo used. "))
Or during calculation:
    ammopleft = int(ammopistol) - int(ammopused)

Next issue will be your print statement. See the following website on 
how to properly format strings: https://pyformat.info/



___
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


[Tutor] Question

2018-08-21 Thread Jacob Braig
I am just starting out coding and decided on python. I am confused with
something I go shooting a lot so i wanted to make some stupid easy
calculator for ammo and slowly build the program up when I understand
python better but the code I have now keeps popping up an error and I don't
understand where i went wrong a little help please.
Here is the code like I said very simple stuff.

"""
 This is a simple program for ammo calculation.
 Created by Jacob
"""
AMMO = " This is how much ammo remains for .40 pistol %s. "

print "Program has started."

ammopistol = raw_input("Enter total ammo before use. ")
ammopused = raw_input("Enter total ammo used. ")
ammopleft = ammopistol - ammopused

print AMMO % (ammopistol, ammopused,) ammoleft

I am having issues with " ammopleft = ammopistol - ammopused "  any idea
where I have gone wrong?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question Regarding startswith()

2018-06-04 Thread Peter Otten
Jeremy Ogorzalek wrote:

> Not sure this is how this is done, but here goes.
> 
> When I try to run the code in the SGP4 module, I get the following error,
> and it originates in the io.py script:
> 
> 
>   File "C:\ProgramData\Anaconda3\lib\site-packages\sgp4\io.py", line 131,
> in twoline2rv
> assert line.startswith('1 ')
> 
> TypeError: startswith first arg must be bytes or a tuple of bytes, not str
> 
> But as far as I can tell in the documentation online (multiple sources)
> the first argument of startswith() is indeed supposed to be a string! It
> should be the string of text you are searching for! So, what gives? I've
> also tried to make the code happy by converting the string to bytes,
> tuple, etc and still get the same error. Any help would be much
> appreciated. Thanks!

Do you read the first two arguments of the twoline2rv() function from a 
file? If so you probably open that file binary mode, but you have to open it 
in text mode to get strings. If that's not possible because the file 
contains other binary data you may convert the byte strings to unicode 
explicitly:

>>> line = b"1 some bytes"
>>> line.startswith("1 ")
Traceback (most recent call last):
  File "", line 1, in 
TypeError: startswith first arg must be bytes or a tuple of bytes, not str
>>> line = line.decode()
>>> line.startswith("1 ")
True


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


Re: [Tutor] Question Regarding startswith()

2018-06-04 Thread Alan Gauld via Tutor
On 04/06/18 16:57, Jeremy Ogorzalek wrote:
> Not sure this is how this is done, but here goes.
> 
> When I try to run the code in the SGP4 module, I get the following error,
> and it originates in the io.py script:

I have no idea what you are talking about and do not know what the SGP4
or io.py files are.
However...

>   File "C:\ProgramData\Anaconda3\lib\site-packages\sgp4\io.py", line 131,
> in twoline2rv
> assert line.startswith('1 ')
> 
> TypeError: startswith first arg must be bytes or a tuple of bytes, not str
> 
> But as far as I can tell in the documentation online (multiple sources) the
> first argument of startswith() is indeed supposed to be a string! 

It depends on which startswith() method you are looking at.

If line is a string you are correct but... if line is a bytes
object then its startwith() method expects a bytes argument.

So I suspect that line is of type bytes(*) and you must convert
it to a string or use a bytes first argument.

(*)You can check by adding a

print("type of line: ", type(line))

in your code.


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


[Tutor] Question Regarding startswith()

2018-06-04 Thread Jeremy Ogorzalek
Not sure this is how this is done, but here goes.

When I try to run the code in the SGP4 module, I get the following error,
and it originates in the io.py script:


  File "C:\ProgramData\Anaconda3\lib\site-packages\sgp4\io.py", line 131,
in twoline2rv
assert line.startswith('1 ')

TypeError: startswith first arg must be bytes or a tuple of bytes, not str

But as far as I can tell in the documentation online (multiple sources) the
first argument of startswith() is indeed supposed to be a string! It should
be the string of text you are searching for! So, what gives? I've also
tried to make the code happy by converting the string to bytes, tuple,
etc and still get the same error. Any help would be much appreciated.
Thanks!

Jeremy Ogorzalek
M.S., Aerospace Engineering
Virginia Tech
443-812-3121
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question about a python finction

2018-05-12 Thread Alan Gauld via Tutor
On 12/05/18 06:40, peter wrote:
> range does not work the same for 2.7 and my 3.6.5. Seems they have 
> changed the nature of range. It is a built in listed along with lists 
> and tuples

You are correct in that it has changed slightly and now returns
a range object. but you can convert it to a list(or tuple) easily

> 
 list(range(10))
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> 
>  >>> tuple(range(10))
> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Just as you have done here.

And if you don;t mneed the explicot list you can use it in a for loop
etc exactly as before:

for n in range(10):...

> ...range(10) will not work with python3.6.5

Yes it will, it just returns a slightly different value that
you must explicitly convert to a list if needed.


-- 
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] Question about a python finction

2018-05-12 Thread peter
range does not work the same for 2.7 and my 3.6.5. Seems they have 
changed the nature of range. It is a built in listed along with lists 
and tuples



list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> tuple(range(10))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

seems they have changed range for python3.6.5 I do not know about the 
earlier python3 versions.  range(10) will not work with python3.6.5


check out https://docs.python.org/3.6/library/stdtypes.html#typesseq

On 05/11/2018 12:58 PM, David Rock wrote:

On May 9, 2018, at 07:14, kevin hulshof  wrote:

Hello,

Is there a function that allows you to grab the numbers between two numbers?

Eg. If you input the numbers 1 and 4
To make a list like this [1,2,3,4]

One option is range

range(1,5)


range(1,5)

[1, 2, 3, 4]

https://docs.python.org/2/library/functions.html#range

—
David Rock
da...@graniteweb.com




___
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 a python finction

2018-05-11 Thread David Rock

> On May 9, 2018, at 07:14, kevin hulshof  wrote:
> 
> Hello,
> 
> Is there a function that allows you to grab the numbers between two numbers?
> 
> Eg. If you input the numbers 1 and 4
> To make a list like this [1,2,3,4]

One option is range

range(1,5)

>>> range(1,5)
[1, 2, 3, 4]

https://docs.python.org/2/library/functions.html#range

— 
David Rock
da...@graniteweb.com




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


Re: [Tutor] Question about a python finction

2018-05-11 Thread Mark Lawrence

On 09/05/18 13:14, kevin hulshof wrote:

Hello,

Is there a function that allows you to grab the numbers between two numbers?

Eg. If you input the numbers 1 and 4
To make a list like this [1,2,3,4]

Thank you for you’re time




Seems like 'range' should fit your needs 
https://docs.python.org/3/library/stdtypes.html#typesseq


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


[Tutor] Question about a python finction

2018-05-11 Thread kevin hulshof
Hello,

Is there a function that allows you to grab the numbers between two numbers?

Eg. If you input the numbers 1 and 4
To make a list like this [1,2,3,4]

Thank you for you’re time


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


Re: [Tutor] question about metaclasses

2018-01-21 Thread Steven D'Aprano
On Thu, Jan 18, 2018 at 05:14:43PM +, Albert-Jan Roskam wrote:

> Is a metaclass the best/preferred/only way of doing this? Or is a 
> class decorator an alternative route?

I haven't thought deeply about this, but I suspect a class decorator 
should do the job too.

The general advice is to use the simplest thing that does the job. The 
deeper you have to go into Python's scary internals, the better reason 
you should have:

- ordinary Python code is simpler than...
- code using decorators, which is simpler than...
- classes using custom descriptors, which is simpler than...
- classes with __init_subclass__, which is simpler than...
- code with metaclasses.

So in general you should pick the first technique (starting at the top) 
which solves your problem in a satisfactory manner.

The __init_subclass__ method is new to Python 3.6:

https://docs.python.org/3/reference/datamodel.html#object.__init_subclass__


Remember the excellent advice:

Debugging is harder than programming, so if you write the trickiest and 
most clever code you are capable of, by definition you won't be able to 
debug it.

Having said that, I applaud you for investigating metaclasses!


> Is the following analogy for doing stuff when a class is created ('born') 
> correct?
> Metaclass --> prenatal surgery
> __new__ --> perinatal surgery
> Class decorator --> postnatal surgery


The last one is certainly correct: a class decorator gets called with 
the fully created class object, and then has the opportunity to modify 
it as needed.

It isn't clear to me what you mean by __new__. Do you mean the *class* 
__new__ method or the *metaclass* __new__ method?

If I write this:

class MetaC(type):
def __new__(meta, *args):
# pretend this does something useful

class C(metaclass=MetaC):
def __new__(cls, *args):
...


then MetaC.__new__ and C.__new__ are called at very different times.

MetaC.__new__ is called as part of the process of creating C in the 
first place; so at the beginning of MetaC.__new__, C does not exist. 

C.__new__ on the other hand doesn't get called when creating C, it gets 
called when creating instances of C. Think of __new__ as the twin of 
__init__, with the following differences:

* __new__ is called before the instance ("self") exists, 
  and gets to customise the creation of the instance;

* __init__ is called after the instance is created, and
  gets to modify self provided self is mutable.


So writing an __init__ method for (say) a string subclass is usually a 
waste of time, since the string is already set and cannot be changed. 
This does not work:

class UpperString(str):
# make strings uppercase
def __init__(self):
self = self.upper()

But this does:

class UpperString(str):
def __new__(cls, arg):
arg = str(arg).upper()
return super().__new__(cls, arg)


Metaclasses are both extremely powerful *and* mind-blowing (back in 
Python 1.5, they were known as "the Killer Joke") because they can 
customise (nearly?) any part of the class operation. So you can think of 
a metaclass as all of the following:

- prenatal surgery (metaclass.__new__);

- postnatal surgery (metaclass.__init__);

- cybernetic implants (metaclass.__getattribute__, __getattr__ etc);

- mind-meld or telepathy between otherwise unrelated classes 
  (define methods in the metaclass as a kind of alternative to
  inheritence);

- gene therapy (all of the above?);

- (I can't think of a good analogy for this one): metaclass.__call__
  lets you customized what happens when you call your class, allowing 
  you to manipulate the arguments or the returned instance.

For example:

class Meta(type):
def __call__(self, *args):
print("called by", self)
instance = super().__call__(*args)
instance.foo = 1
return instance


prints a message and adds a "foo" attribute to every instance of every 
class that belongs to it.

Oh, and just to make it more fun... metaclasses don't have to be a 
class! See if you can predict what this will do:


def meta(*args):
print("Hi there, I'm your metaclass for today, how can I blow your mind?")
return 42

class A(metaclass=meta):
pass


See also The Killer Joke:
https://www.python.org/doc/essays/metaclasses/

That was written back in Python 1.5 days, so a lot of the information in 
it is now obsolete. But the basic techniques should more or less work 
today.



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


Re: [Tutor] question about metaclasses

2018-01-18 Thread Steven D'Aprano
On Thu, Jan 18, 2018 at 05:31:24PM +, Albert-Jan Roskam wrote:

> > Don't make the mistake of doing this:
> >
> > from collections import namedtuple
> > a = namedtuple('Bag', 'yes no dunno')(yes=1, no=0, dunno=42)
> > b = namedtuple('Bag', 'yes no dunno')(yes='okay', no='no way', dunno='not a 
> > clue')
> 
> But if I do:
> Bag = namedtuple('Bag', 'yes no dunno')
> ... and then I create hundreds of Bag instances, this doesn't have a 
> large memory footprint, right? (Because of __slots__) Or is a regular 
> tuple still (much) less wasteful?

Correct.

namedtuple instances are *nearly* as compact as regular tuples. Making 
many instances of the one named tuple class is efficient; making many 
named tuple classes, with one instance each, is slow and wasteful of 
memory.



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


Re: [Tutor] question about metaclasses

2018-01-18 Thread Albert-Jan Roskam

On Jan 10, 2018 19:32, Peter Otten <__pete...@web.de> wrote:
>
> Albert-Jan Roskam wrote:
>
> > Why does following the line (in #3)
>
> > # 3-
> > class Meta(type):
> > def __new__(cls, name, bases, attrs):
> > for attr, obj in attrs.items():
> > if attr.startswith('_'):
> > continue
> > elif not isinstance(obj, property):
> > import pdb;pdb.set_trace()
> > #setattr(cls, attr, property(lambda self: obj))  #
> > #incorrect!
> > raise ValueError("Only properties allowed")
> > return super().__new__(cls, name, bases, attrs)
> >
> > class MyReadOnlyConst(metaclass=Meta):
> > __metaclass__ = Meta
> > YES = property(lambda self: 1)
> > NO = property(lambda self: 0)
> > DUNNO = property(lambda self: 42)
> > THROWS_ERROR = 666
> >
> >
> > c2 = MyReadOnlyConst()
> > print(c2.THROWS_ERROR)
> > #c2.THROWS_ERROR = 777
> > #print(c2.THROWS_ERROR)
>
> > not convert the normal attribute int > a property?
> >
> > setattr(cls, attr, property(lambda self: obj))  # incorrect!
>
> cls is Meta itself, not MyReadOnlyConst (which is an instance of Meta).
> When the code in Meta.__new__() executes MyReadOnlyConst does not yet exist,
> but future attributes are already there, in the form of the attrs dict.
> Thus to convert the integer value into a read-only property you can
> manipulate that dict (or the return value of super().__new__()):
>
> class Meta(type):
> def __new__(cls, name, bases, attrs):
> for attr, obj in attrs.items():
> if attr.startswith('_'):
> continue
> elif not isinstance(obj, property):
> attrs[attr] = property(lambda self, obj=obj: obj)
>
> return super().__new__(cls, name, bases, attrs)
>
> class MyReadOnlyConst(metaclass=Meta):
> YES = property(lambda self: 1)
> NO = property(lambda self: 0)
> DUNNO = property(lambda self: 42)
> THROWS_ERROR = 666
>
> c = MyReadOnlyConst()
> try:
> c.THROWS_ERROR = 42
> except AttributeError:
> pass
> else:
> assert False
> assert c.THROWS_ERROR == 666

Thanks all for your replies!

Awesome, this is exactly what I want. I think I'll also override __setattr__  
so that each newly added attribute is automatically converted into a property
Is a metaclass the best/preferred/only way of doing this? Or is a class 
decorator an alternative route?

Is the following analogy for doing stuff when a class is created ('born') 
correct?
Metaclass --> prenatal surgery
__new__ --> perinatal surgery
Class decorator --> postnatal surgery

> PS: If you don't remember why the obj=obj is necessary:
> Python uses late binding; without that trick all lambda functions would
> return the value bound to the obj name when the for loop has completed.
> A simplified example:
>
> >>> fs = [lambda: x for x in "abc"]
> >>> fs[0](), fs[1](), fs[2]()
> ('c', 'c', 'c')
> >>> fs = [lambda x=x: x for x in "abc"]
> >>> fs[0](), fs[1](), fs[2]()
> ('a', 'b', 'c')
>
>
> ___
> 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 metaclasses

2018-01-18 Thread Albert-Jan Roskam

On Jan 10, 2018 18:57, Steven D'Aprano  wrote:
>
> On Wed, Jan 10, 2018 at 04:08:04PM +, Albert-Jan Roskam wrote:
>
> > In another thread on this list I was reminded of
> > types.SimpleNamespace. This is nice, but I wanted to create a bag
> > class with constants that are read-only.
>
> If you expect to specify the names of the constants ahead of time, the
> best solution is (I think) a namedtuple.

Aaah *slaps forehead*, for some reason I didn't think about this, though I use 
namedtuples quite often. Using a metaclass for the very first time was great 
fun though :-)

> from collections import namedtuple
> Bag = namedtuple('Bag', 'yes no dunno')
> a = Bag(yes=1, no=0, dunno=42)
> b = Bag(yes='okay', no='no way', dunno='not a clue')
>
> ought to do what you want.
>
> Don't make the mistake of doing this:
>
> from collections import namedtuple
> a = namedtuple('Bag', 'yes no dunno')(yes=1, no=0, dunno=42)
> b = namedtuple('Bag', 'yes no dunno')(yes='okay', no='no way', dunno='not a 
> clue')

But if I do:
Bag = namedtuple('Bag', 'yes no dunno')
... and then I create hundreds of Bag instances, this doesn't have a large 
memory footprint, right? (Because of __slots__) Or is a regular tuple still 
(much) less wasteful?

> because that's quite wasteful of memory: each of a and b belong to a
> separate hidden class, and classes are rather largish objects.
>
>
> If you expect to be able to add new items on the fly, but have them
> read-only once set, that's a different story.
>
>
> --
> Steve
> ___
> 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 metaclasses

2018-01-15 Thread Peter Otten
Steven D'Aprano wrote:

> On Wed, Jan 10, 2018 at 07:29:58PM +0100, Peter Otten wrote:
> 
> [...]
>> elif not isinstance(obj, property):
>> attrs[attr] = property(lambda self, obj=obj: obj)
> 
>> PS: If you don't remember why the obj=obj is necessary:
>> Python uses late binding; without that trick all lambda functions would
>> return the value bound to the obj name when the for loop has completed.
> 
> This is true, but I think your terminology is misleading. For default
> values to function parameters, Python uses *early* binding, not late
> binding: the default value is computed once at the time the function is
> created, not each time it is needed.

You are right; I should have stated clearly where I was talking about the 
closure.

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


Re: [Tutor] question about metaclasses

2018-01-13 Thread Steven D'Aprano
On Wed, Jan 10, 2018 at 07:29:58PM +0100, Peter Otten wrote:

[...]
> elif not isinstance(obj, property):
> attrs[attr] = property(lambda self, obj=obj: obj)

> PS: If you don't remember why the obj=obj is necessary:
> Python uses late binding; without that trick all lambda functions would 
> return the value bound to the obj name when the for loop has completed.

This is true, but I think your terminology is misleading. For default 
values to function parameters, Python uses *early* binding, not late 
binding: the default value is computed once at the time the function is 
created, not each time it is needed.

So in this case, each of those property objects use a function that sets 
the default value of obj to the current value of obj at the time that 
the property is created.

Without the obj=obj parameter, Python creates a *closure*. A closure is 
a computer-science term for something like a snap shot of the 
environment where the function was created.

If we had written this instead:

attrs[attr] = property(lambda self: obj)

the name "obj" doesn't refer to a local variable of the lambda function. 
Nor does it refer to a global variable, or a builtin function. It refers 
to a "non-local variable": it belongs to the function that surrounds the 
lambda function, not the lambda itself.

And so Python would create a *closure* for the lambda function so that 
when it eventually gets called, it knows where to find the value of obj.

And *that* process, of looking up the value of obj from a closure, uses 
late binding: all the lambda functions will refer to the same 
environment, which means they will also see the same value for obj.

Namely the last value obj received when the outer function (the one 
that the closure refers back to) completed.

Here's another example to show the difference. Rather than use lambda, 
I'm going to use regular "def" to prove that this has nothing to do with 
lambda itself, the rules apply every time you create a function.

Start with the closure version:

# --- cut here %< ---

def factory_closure():
# Create many new functions, each of which refer to i in its
# enclosing scope.
functions = []
for i in range(5):
def f():
return i  # << this i is a NONLOCAL variable
functions.append(f)
return functions

functions = factory_closure()

# All the closures refer to the same thing.
for f in functions:
print(f.__closure__)

# And the functions all see the same value for i
print([f() for f in functions])

# --- cut here %< ---


And here is a version which avoids the closure issue by using the 
function parameter default value trick:


# --- cut here %< ---

def factory_no_closure():
# Create many new functions, each of which refer to i using
# a parameter default value.
functions = []
for i in range(5):
def f(i=i):
return i  # << this i is a LOCAL variable
functions.append(f)
return functions

functions = factory_no_closure()

# None of the functions need a closure.
for g in functions:
print(g.__closure__)

# And the functions all see different values for i
print([g() for g in functions])

# --- cut here %< ---


In practice, this is generally only an issue when single invocation of a 
factory function creates two or more functions at once, and that 
generally means inside a loop:


def factory():
for i in something:
create function referring to i


If your factory only returns one function at a time, like this:


def factory(i):
create function referring to i

for n in something:
factory(n)


then each function still uses a closure, but they are *different* 
closures because each one is created on a different invocation of the 
factory. That's another way to avoid this "early/late binding" problem.


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


Re: [Tutor] question about metaclasses

2018-01-10 Thread Peter Otten
Albert-Jan Roskam wrote:

> Why does following the line (in #3) 

> # 3-
> class Meta(type):
> def __new__(cls, name, bases, attrs):
> for attr, obj in attrs.items():
> if attr.startswith('_'):
> continue
> elif not isinstance(obj, property):
> import pdb;pdb.set_trace()
> #setattr(cls, attr, property(lambda self: obj))  #
> #incorrect!
> raise ValueError("Only properties allowed")
> return super().__new__(cls, name, bases, attrs)
> 
> class MyReadOnlyConst(metaclass=Meta):
> __metaclass__ = Meta
> YES = property(lambda self: 1)
> NO = property(lambda self: 0)
> DUNNO = property(lambda self: 42)
> THROWS_ERROR = 666
> 
> 
> c2 = MyReadOnlyConst()
> print(c2.THROWS_ERROR)
> #c2.THROWS_ERROR = 777
> #print(c2.THROWS_ERROR)

> not convert the normal attribute into
> a property?
> 
> setattr(cls, attr, property(lambda self: obj))  # incorrect!

cls is Meta itself, not MyReadOnlyConst (which is an instance of Meta).
When the code in Meta.__new__() executes MyReadOnlyConst does not yet exist,
but future attributes are already there, in the form of the attrs dict.
Thus to convert the integer value into a read-only property you can 
manipulate that dict (or the return value of super().__new__()):

class Meta(type):
def __new__(cls, name, bases, attrs):
for attr, obj in attrs.items():
if attr.startswith('_'):
continue
elif not isinstance(obj, property):
attrs[attr] = property(lambda self, obj=obj: obj)

return super().__new__(cls, name, bases, attrs)

class MyReadOnlyConst(metaclass=Meta):
YES = property(lambda self: 1)
NO = property(lambda self: 0)
DUNNO = property(lambda self: 42)
THROWS_ERROR = 666

c = MyReadOnlyConst()
try:
c.THROWS_ERROR = 42
except AttributeError:
pass
else:
assert False
assert c.THROWS_ERROR == 666

PS: If you don't remember why the obj=obj is necessary:
Python uses late binding; without that trick all lambda functions would 
return the value bound to the obj name when the for loop has completed.
A simplified example:

>>> fs = [lambda: x for x in "abc"]
>>> fs[0](), fs[1](), fs[2]()
('c', 'c', 'c')
>>> fs = [lambda x=x: x for x in "abc"]
>>> fs[0](), fs[1](), fs[2]()
('a', 'b', 'c')


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


Re: [Tutor] question about metaclasses

2018-01-10 Thread Zachary Ware
On Wed, Jan 10, 2018 at 10:08 AM, Albert-Jan Roskam
 wrote:
> Hi,
>
>
> In another thread on this list I was reminded of types.SimpleNamespace. This 
> is nice, but I wanted to create a bag class with constants that are 
> read-only. My main question is about example #3 below (example #2 just 
> illustrates my thought process). Is this a use case to a metaclass? Or can I 
> do it some other way (maybe a class decorator?). I would like to create a 
> metaclass that converts any non-special attributes (=not starting with '_') 
> into properties, if needed. That way I can specify my bag class in a very 
> clean way: I only specify the metaclass, and I list the attributes as normal 
> attrbutes, because the metaclass will convert them into properties.

You appear to be reimplementing Enum.

> Why does following the line (in #3) not convert the normal attribute into a 
> property?
>
> setattr(cls, attr, property(lambda self: obj))  # incorrect!

Because `cls` is `Meta`, not `MyReadOnlyConst`; `__new__` is
implicitly a classmethod and `MyReadOnlyConst` doesn't actually exist
yet.  When `MyReadOnlyConst` is created by `type.__new__` it will be
filled with the contents of `attrs`, so instead of `setattr` you want
`attrs[attr] = property(...)`.

But once you're past the learning exercise that this is, just use
enum.Enum or collections.namedtuple :)

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


Re: [Tutor] question about metaclasses

2018-01-10 Thread Steven D'Aprano
On Wed, Jan 10, 2018 at 04:08:04PM +, Albert-Jan Roskam wrote:

> In another thread on this list I was reminded of 
> types.SimpleNamespace. This is nice, but I wanted to create a bag 
> class with constants that are read-only.

If you expect to specify the names of the constants ahead of time, the 
best solution is (I think) a namedtuple.

from collections import namedtuple
Bag = namedtuple('Bag', 'yes no dunno')
a = Bag(yes=1, no=0, dunno=42)
b = Bag(yes='okay', no='no way', dunno='not a clue')

ought to do what you want.

Don't make the mistake of doing this:

from collections import namedtuple
a = namedtuple('Bag', 'yes no dunno')(yes=1, no=0, dunno=42)
b = namedtuple('Bag', 'yes no dunno')(yes='okay', no='no way', dunno='not a 
clue')

because that's quite wasteful of memory: each of a and b belong to a 
separate hidden class, and classes are rather largish objects.


If you expect to be able to add new items on the fly, but have them 
read-only once set, that's a different story.


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


[Tutor] question about metaclasses

2018-01-10 Thread Albert-Jan Roskam
Hi,


In another thread on this list I was reminded of types.SimpleNamespace. This is 
nice, but I wanted to create a bag class with constants that are read-only. My 
main question is about example #3 below (example #2 just illustrates my thought 
process). Is this a use case to a metaclass? Or can I do it some other way 
(maybe a class decorator?). I would like to create a metaclass that converts 
any non-special attributes (=not starting with '_') into properties, if needed. 
That way I can specify my bag class in a very clean way: I only specify the 
metaclass, and I list the attributes as normal attrbutes, because the metaclass 
will convert them into properties.


Why does following the line (in #3) not convert the normal attribute into a 
property?

setattr(cls, attr, property(lambda self: obj))  # incorrect!



# 1-
# nice, but I want the constants to be read-only
from types import SimpleNamespace
const = SimpleNamespace(YES=1, NO=0, DUNNO=9)
const.YES = 0
print(const)


# 2-
# works, but I wonder if there's a builtin way
class Const(object):
"""Adding attributes is ok, modifying them is not"""
YES = property(lambda self: 1)
NO = property(lambda self: 0)
DUNNO = property(lambda self: 42)
#THROWS_ERROR = 666

def __new__(cls):
for attr in dir(cls):
if attr.startswith('_'):
continue
elif not isinstance(getattr(cls, attr), property):
raise ValueError("Only properties allowed")
return super().__new__(cls)
def __repr__(self):
kv = ["%s=%s" % (attr, getattr(self, attr)) for \
  attr in sorted(dir(Const)) if not attr.startswith('_')]
return "ReadOnlyNamespace(" + ", ".join(kv) + ")"

c = Const()
print(repr(c))
#c.YES = 42  # raises AttributeError (desired behavior)

print(c.YES)


# 3-
class Meta(type):
def __new__(cls, name, bases, attrs):
for attr, obj in attrs.items():
if attr.startswith('_'):
continue
elif not isinstance(obj, property):
import pdb;pdb.set_trace()
#setattr(cls, attr, property(lambda self: obj))  # incorrect!
raise ValueError("Only properties allowed")
return super().__new__(cls, name, bases, attrs)

class MyReadOnlyConst(metaclass=Meta):
__metaclass__ = Meta
YES = property(lambda self: 1)
NO = property(lambda self: 0)
DUNNO = property(lambda self: 42)
THROWS_ERROR = 666


c2 = MyReadOnlyConst()
print(c2.THROWS_ERROR)
#c2.THROWS_ERROR = 777
#print(c2.THROWS_ERROR)


Thank you in advance and sorry about the large amount of code!


Albert-Jan

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


Re: [Tutor] Question

2017-12-10 Thread Steven D'Aprano
Hello Khabbab Zakaria,

On Sun, Dec 10, 2017 at 11:18:16AM +0530, Khabbab Zakaria wrote:
> I am working on a program where I found the line:
> x,y,z = np.loadtext('abcabc.txt', unpack= True, skiprows =1)
> What does the x, y, z thing mean?

"x, y, z = ..." is iterable unpacking. The right hand side has to be an 
iterable (any object that can be iterated over in a for-loop) such as a 
list, a tuple, a set, or similar. For example:


x, y, z = [1, 2, 3]


will set x = 1, y = 2, z = 3. It is an error if the object on the right 
hand side has too few or too many items:


a, b, c, d, e = (1, 2, 3) # Too few items

a, b, c, d, e = (1, 2, 3, 4, 5, 6, 7)  # Too many items


> What does the unpack= True mean?

I'm afraid you will need to read the numpy documentation for that. I 
tried looking at it myself, but the version of numpy I have seems to be 
too old:

py> import numpy as np
py> help(np.loadtext)
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'module' object has no attribute 'loadtext'



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


Re: [Tutor] Question

2017-12-10 Thread Alan Gauld via Tutor
On 10/12/17 05:48, Khabbab Zakaria wrote:
> I am working on a program where I found the line:

> x,y,z = np.loadtext('abcabc.txt', unpack= True, skiprows =1)

> What does the x, y, z thing mean?
> What does the unpack= True mean?

They are related. unpacking is a feature of Python whereby a collection
of values can be assigned to individual variables in one statement.

Consider a list of numbers:

nums = [1,2,3]

we can unpack those 3 values into separate variables like so

x,y,z = nums

This is equivalent to:

x = nums[0]
y = nums[1]
z = nums[2]

So in your example the numpy function returns some
kind of collection of 3 values which are unpacked
into x,y and z exactly as we did with nums above.

I assume the unpack=True argument simply controls
the output of the function such that unpacking is
possible, but I'm not familiar with it so cannot
be sure.


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


[Tutor] Question

2017-12-10 Thread Khabbab Zakaria
I am working on a program where I found the line:
x,y,z = np.loadtext('abcabc.txt', unpack= True, skiprows =1)
What does the x, y, z thing mean?
What does the unpack= True mean?
Thank you
-- 
Khabbab Zakaria
Dept of Power Engineering
Jadavpur University
Calcutta
India
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about calendar module in standard libriary

2017-09-11 Thread Peter Otten
Айнур Зулькарнаев wrote:

> Hello all!
> 
> 
> There is a class Calendar in calendar.py in standard libriary.
> 
> 
> class Calendar(object):
> """
> Base calendar class. This class doesn't do any formatting. It
> simply provides data to subclasses.
> """
> 
> def __init__(self, firstweekday=0):
> self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday
> 
> def getfirstweekday(self):
> return self._firstweekday % 7
> 
> def setfirstweekday(self, firstweekday):
> self._firstweekday = firstweekday
> 
> firstweekday = property(getfirstweekday, setfirstweekday)
> 
> 
> As far as I understand, even if user enters inappropriate firstweekday
> parameter (bigger than 6) during instansiation of the Calendar, the
> Calendar swallows it (and latter returns correct firstweekday value due to
> %7 in getfirstweekday method).
> 
> 
> So, the question is why not explicitly raise ValueError if user enters the
> firstweekday parameter bigger that 6 (with accordance with the Zen). Am I
> missing something?

It does no harm to those who use the class properly while it allows those 
unfamiliar with the idea of a 0th day to specify 7 instead 0. The behaviour 
thus may be interpreted as an example of

"""Be strict when sending and tolerant when receiving."""

See also

https://tools.ietf.org/html/rfc1958
https://en.wikipedia.org/wiki/Robustness_principle

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


Re: [Tutor] question about calendar module in standard libriary

2017-09-11 Thread Steven D'Aprano
On Mon, Sep 11, 2017 at 10:58:51AM +, Айнур Зулькарнаев wrote:

> class Calendar(object):
> def __init__(self, firstweekday=0):
> self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday
> 
> def getfirstweekday(self):
> return self._firstweekday % 7
> 
> def setfirstweekday(self, firstweekday):
> self._firstweekday = firstweekday
> 
> firstweekday = property(getfirstweekday, setfirstweekday)
>
> As far as I understand, even if user enters inappropriate firstweekday 
> parameter (bigger than 6) during instansiation of the Calendar, the 
> Calendar swallows it (and latter returns correct firstweekday value 
> due to %7 in getfirstweekday method).

That looks right to me.

> So, the question is why not explicitly raise ValueError if user enters 
> the firstweekday parameter bigger that 6 (with accordance with the 
> Zen). Am I missing something?

I don't think there is any specific reason. Probably just the personal 
choice of the person who wrote the code. The decision doesn't appear to 
be documented anywhere, so I don't think its official behaviour.


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


Re: [Tutor] question about calendar module in standard libriary

2017-09-11 Thread Alan Gauld via Tutor
On 11/09/17 11:58, Айнур Зулькарнаев wrote:

> So, the question is why not explicitly raise ValueError if 
> user enters the firstweekday parameter bigger that 6 

Its a valid question but you probably need to find the original PEP
document to find the answer and that module has been around for
a *very* long time!

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


[Tutor] question about calendar module in standard libriary

2017-09-11 Thread Айнур Зулькарнаев
Hello all!


There is a class Calendar in calendar.py in standard libriary.


class Calendar(object):
"""
Base calendar class. This class doesn't do any formatting. It simply
provides data to subclasses.
"""

def __init__(self, firstweekday=0):
self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday

def getfirstweekday(self):
return self._firstweekday % 7

def setfirstweekday(self, firstweekday):
self._firstweekday = firstweekday

firstweekday = property(getfirstweekday, setfirstweekday)


As far as I understand, even if user enters inappropriate firstweekday 
parameter (bigger than 6) during instansiation of the Calendar, the Calendar 
swallows it (and latter returns correct firstweekday value due to %7 in 
getfirstweekday method).


So, the question is why not explicitly raise ValueError if user enters the 
firstweekday parameter bigger that 6 (with accordance with the Zen). Am I 
missing something?


Thank you in advance


Best regards, Aynur



С уважением, А.И. Зулькарнаев

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


Re: [Tutor] Question to Phyton and XBee

2017-04-12 Thread Alan Gauld via Tutor
On 12/04/17 15:32, Daniel Berger wrote:

>For me it is not clear what is going wrong and I would be happy to get
>some help to solve the problem.

This list is for the core language and library, so while we
can help with installing third party packages that doesn't
mean anyone here will know how to use them. You might get
lucky and find somebody, but you are more likely to find
someone on a dedicated XBee support forum.

If both of those options fail then you can try the main
Python list.

-- 
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] Question to Phyton and XBee

2017-04-12 Thread Daniel Berger
   Hello,

   thank you very much for your help. I have done a mistake during
   installation.
   I have tested the code for reading data from Xbee:

 #! /usr/bin/python
 # Import and init an XBee device
 from xbee import XBee, ZigBee
 import serial
 ser = serial.Serial('COM4', 9600)
 xbee = XBee(ser)
 while True:
 try:
 response =  xbee.wait_read_frame()
 print response
 except KeyboardInterrupt:
 break
 ser.close()

   At the moment it is not possible to get any data received by the Xbee,
   although it is possible to read the data by XCTU. I have chosen the
   following setup:
   - A TMP36-sensor is connected to an Arduino Uno
   - A Sparkfun XBee-shield with an XBee S2C is mounted on the Arduino
   (Router). The Arduino is connected to COM3.
   - COM4 is connected with a Sparkfun XBee-Explorer (USB-connection).
   Another XBee S2C is connected on the explorer. This XBee is the
   coordinator.
   If I send sensor data (sensor reading and sending to Xbee is done by
   Arduino Software) from the router to the coordinator, I'm able to read the
   data frames by XCTU and the results make sense. If I use the Python-code
   above, I did not get any data frames, although the RSSI-diodes of router
   and coordinator are blinking independently from the software (XCTU or
   Python) I use.
   For me it is not clear what is going wrong and I would be happy to get
   some help to solve the problem.

   Regards and thank you very much
   Daniel Berger




   Gesendet: Dienstag, 11. April 2017 um 21:04 Uhr
   Von: "Marc Tompkins" <marc.tompk...@gmail.com>
   An: "Daniel Berger" <berg...@gmx.de>
   Cc: "tutor@python.org" <tutor@python.org>
   Betreff: Re: [Tutor] Question to Phyton and XBee
   On Tue, Apr 11, 2017 at 9:12 AM, Daniel Berger <[1]berg...@gmx.de> wrote:

Hello,

I have installed the modules to control xbee with Python
[2]https://pypi.python.org/pypi/XBee). Afterwards I have set the path
variable on C:\Python27\python-xbee-master and also the
 subdirectories. To
check, if the modules are available, I have written the code as
recommended ([3]https://pypi.python.org/pypi/XBee)

# Import and init xbee device
from xbee import XBee
import serial
import arduino

The interpreter gave the error message
File "C:/Users/daniel/PycharmProjects/hardware_test/test_xbee.py",
 line 2,
in 
from xbee import XBee
ImportError: No module named xbee

I have done the same with
 [4]https://github.com/nioinnovation/python-xbee and
it have the same effect.
As I'm not very familiar with Python, I would like to know, what is
 going
wrong and how I can find the module.


   How did you install it?  If you use the very simplest method -  "pip
   install xbee" - it should automatically take care of the path for you.



References

   Visible links
   1. mailto:berg...@gmx.de
   2. https://pypi.python.org/pypi/XBee
   3. https://pypi.python.org/pypi/XBee
   4. https://github.com/nioinnovation/python-xbee
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question to Phyton and XBee

2017-04-11 Thread Marc Tompkins
On Tue, Apr 11, 2017 at 9:12 AM, Daniel Berger  wrote:

>Hello,
>
>I have installed the modules to control xbee with Python
>https://pypi.python.org/pypi/XBee). Afterwards I have set the path
>variable on C:\Python27\python-xbee-master and also the subdirectories.
> To
>check, if the modules are available, I have written the code as
>recommended (https://pypi.python.org/pypi/XBee)
>
># Import and init xbee device
>from xbee import XBee
>import serial
>import arduino
>
>The interpreter gave the error message
>File "C:/Users/daniel/PycharmProjects/hardware_test/test_xbee.py",
> line 2,
>in 
>from xbee import XBee
>ImportError: No module named xbee
>
>I have done the same with https://github.com/nioinnovation/python-xbee
> and
>it have the same effect.
>As I'm not very familiar with Python, I would like to know, what is
> going
>wrong and how I can find the module.
>

How did you install it?  If you use the very simplest method -  "pip
install xbee" - it should automatically take care of the path for you.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Question to Phyton and XBee

2017-04-11 Thread Daniel Berger
   Hello,

   I have installed the modules to control xbee with Python
   https://pypi.python.org/pypi/XBee). Afterwards I have set the path
   variable on C:\Python27\python-xbee-master and also the subdirectories. To
   check, if the modules are available, I have written the code as
   recommended (https://pypi.python.org/pypi/XBee)

   # Import and init xbee device
   from xbee import XBee
   import serial
   import arduino

   The interpreter gave the error message
   File "C:/Users/daniel/PycharmProjects/hardware_test/test_xbee.py", line 2,
   in 
   from xbee import XBee
   ImportError: No module named xbee

   I have done the same with https://github.com/nioinnovation/python-xbee and
   it have the same effect.
   As I'm not very familiar with Python, I would like to know, what is going
   wrong and how I can find the module.

   Regards and thank you very much
   Daniel
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question about loop and assigning variables

2017-04-06 Thread Mats Wichmann
On 04/05/2017 01:07 PM, Fazal Khan wrote:
> Hello,
> 
> Heres another newbie python question: How can I loop through some data and
> assign different variables with each loop
> 
> So this is my original code:
> 
> def BeamInfo(x):
>   for Bnum in x:
> if plan1.IonBeamSequence[Bnum].ScanMode == 'MODULATED':
> TxTableAngle =
> plan1.IonBeamSequence[Bnum].IonControlPointSequence[0].PatientSupportAngle
> print(TxTableAngle)
> else:
> None
> 
> BeamInfo([0,1,2,3,4,5,6])
> 
> 
> Ideally what I want is this: when Bnum is 0, then "TxTableAngle" will be
> appended with "_0" (eg.TxTableAngle_0). When Bnum is 1 then TxTableAngle_1,
> etc. How do I do this in python?

well... what you're doing now is not very useful, as TxTableTangle goes
out of scope when the function has completed. Which means the work is
just lost.  And the else: clause - if you don't want to do anything here
(the terminology would be "pass", not "None", you don't even need to say
that).

the most likely solution, along the lines of what Alan has suggested, is
to create a list; and then you need to return it so it's actually usable
- just printing the output doesn't leave you with anything other than
characters on the console.  So consider this as a concept (not a working
implementation since there are other things missing):

def BeamInfo(x):
TxTableAngle = []
for Bnum in x:
if blah :
TxTableAngle.append(blah blah)
return TxTableAngle

var = BeamInfo([0,1,2,3,4,5,6])

(of course whenever you have a create-empty-list followed by a loop of
append-to-list you can replace that by a list comprehension)

that gets you back a variable var containing a a reference to a list
("array" if you prefer to think of it that way) you can iterate over.



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


Re: [Tutor] Question about loop and assigning variables

2017-04-05 Thread Steven D'Aprano
On Wed, Apr 05, 2017 at 12:07:05PM -0700, Fazal Khan wrote:
> Hello,
> 
> Heres another newbie python question: How can I loop through some data and
> assign different variables with each loop

You don't. That's a bad idea.

Instead, you use a sequence (a tuple, or a list), and use an index:

TxTableAngle[0]  # the first item
TxTableAngle[1]  # the second item
etc.


> So this is my original code:
> 
> def BeamInfo(x):
>   for Bnum in x:
> if plan1.IonBeamSequence[Bnum].ScanMode == 'MODULATED':
> TxTableAngle =
> plan1.IonBeamSequence[Bnum].IonControlPointSequence[0].PatientSupportAngle
> print(TxTableAngle)
> else:
> None


Let's say you succeed in doing what you want, and you have a bunch of 
variables called TxTableAngle_0, TxTableAngle_1, TxTableAngle_2, and so 
on. How do you use them?

The first problem is that you don't know if they even exist! You might 
not have *any* TxTableAngle variables at all, if x is empty, of if 
ScanMode is never MODULATED. So even

TxTableAngle_0

might fail with a NameError exception. But even if you can guarantee 
that there is *at least one* variable, you don't know how many there 
will be! That depends on how many times the ScanMode is MODULATED. 
Perhaps there is only one, perhaps there is a thousand. How do you know 
if it is safe to refer to:

TxTableAngle_3

or not? This rapidly becomes hard to code, difficult to write, harder to 
debug and maintain, a real nightmare.

Better is to collect the results into a list:

def BeamInfo(x):
results = []
for bnum in x:
beam = plan1.IonBeamSequence[bnum]
if beam.ScanMode == 'MODULATED':
TxTableAngle = beam.IonControlPointSequence[0].PatientSupportAngle
results.append(TxTableAngle)
print(TxtTableAngle)
return results

TxTableAngles = BeamInfo([0,1,2,3,4,5,6])

Now you know that TxTableAngles *must* exist. You can find out how many 
items there actually are:

len(TxTableAngles)

you can grab any one specific item (provided the index actually exists):

TxTableAngles[i]

and most importantly you can process all of the angles one after the 
other:

for angle in TxTableAngles:
print(angle)


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


Re: [Tutor] Question about loop and assigning variables

2017-04-05 Thread Alan Gauld via Tutor
On 05/04/17 20:07, Fazal Khan wrote:

> assign different variables with each loop

You can't, but you can fake it...

> def BeamInfo(x):
>   for Bnum in x:
> if plan1.IonBeamSequence[Bnum].ScanMode == 'MODULATED':
> TxTableAngle =
> plan1.IonBeamSequence[Bnum].IonControlPointSequence[0].PatientSupportAngle
> print(TxTableAngle)
> else:
> None

> Ideally what I want is this: when Bnum is 0, then "TxTableAngle" will be
> appended with "_0" (eg.TxTableAngle_0). When Bnum is 1 then TxTableAngle_1,
> etc. How do I do this in python?

Use a list (or a dictionary if the values are not sequential or numeric)

So
TxTableAngle_0 -> TxTableAngle[0]
TxTableAngle_1 -> TxTableAngle[1]

It's one extra character but hopefully that won't be too painful...

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


[Tutor] Question about loop and assigning variables

2017-04-05 Thread Fazal Khan
Hello,

Heres another newbie python question: How can I loop through some data and
assign different variables with each loop

So this is my original code:

def BeamInfo(x):
  for Bnum in x:
if plan1.IonBeamSequence[Bnum].ScanMode == 'MODULATED':
TxTableAngle =
plan1.IonBeamSequence[Bnum].IonControlPointSequence[0].PatientSupportAngle
print(TxTableAngle)
else:
None

BeamInfo([0,1,2,3,4,5,6])


Ideally what I want is this: when Bnum is 0, then "TxTableAngle" will be
appended with "_0" (eg.TxTableAngle_0). When Bnum is 1 then TxTableAngle_1,
etc. How do I do this in python?

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


Re: [Tutor] QUESTION

2017-03-04 Thread Alan Gauld via Tutor
On 04/03/17 01:37, Tasha Burman wrote:
> I am having difficulty with a power function; 
> what is another way I can do 4**9 without using **?

You can use the pow() function.

answer = pow(4,9)

However, I'm not sure that really answers your question?
Do you mean that you want to write your own power()
function and want help with that? If so ask again with
a more specific description of your problem.

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


[Tutor] QUESTION

2017-03-04 Thread Tasha Burman
Hello python tutors, 
I am having difficulty with a power function; what is another way I can do 4**9 
without using **?
Thanks, 
Tasha 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question About the .format Method.

2016-11-10 Thread Alan Gauld via Tutor
On 09/11/16 22:30, Bryon Adams wrote:
> Hello,
>  Working on a simple function to get an IP address and make it look 
> pretty for the PyNet course. I'm wondering if there's way to evenly 
> space text with the string.format() method similar to how I'm doing it 
> with the % operator. 

Yes, read section 6.1.3 of the documentation

https://docs.python.org/3/library/string.html#formatstrings

You can do everything that % formatting can do, and some more.

See the examples in section 6.1.3.2

-- 
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] Question About the .format Method.

2016-11-10 Thread Peter Otten
Bryon Adams wrote:

> Hello,
>  Working on a simple function to get an IP address and make it look
> pretty for the PyNet course. I'm wondering if there's way to evenly
> space text with the string.format() method similar to how I'm doing it
> with the % operator. The last two prints keep everything left aligned
> and 20 spaces wide. Is there a way to accomplish this with the .format()
> method that I use in the first print function?

You can left-align, center or right-align with format():

>>> print("| {:<12} | {:^12} | {:>12} |".format("left", "center", "right"))
| left |center|right |

The default is right-align for numbers and left-align for strings:

>>> "{:12}".format(42)
'  42'
>>> "{:12}".format("42")
'42  '

You can find the details here:




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


[Tutor] Question About the .format Method.

2016-11-09 Thread Bryon Adams

Hello,
Working on a simple function to get an IP address and make it look 
pretty for the PyNet course. I'm wondering if there's way to evenly 
space text with the string.format() method similar to how I'm doing it 
with the % operator. The last two prints keep everything left aligned 
and 20 spaces wide. Is there a way to accomplish this with the .format() 
method that I use in the first print function?



# Getting the IP address and putting it into list
ip4 = input('Please enter a /24 network address: ')
ip4 = ip4.split('.') # Split string into a list
ip4 = ip4[:3]# Force list to be a /24 network address
ip4.append('0')
print('{}.{}.{}.{}'.format(ip4[0], ip4[1], ip4[2], ip4[3]))

ip4_str = '.'.join(ip4)
ip4_bin = bin(int(ip4[0]))
ip4_hex = hex(int(ip4[0]))

# Printing the table
print('\n'+'-')
print('%-20s %-20s %-20s' %('NETWORK_NUMBER', 'FIRST_OCTET_BINARY', 
'FIRST_OCTET_HEX'))

print('%-20s %-20s %-20s' %(ip4_str, ip4_bin, ip4_hex))


PS. I realise the first print can be simplified with a .join but I 
forgot about .join and left it to help illustrate my question.


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


Re: [Tutor] question about __copy__ and __deepcopy__

2016-04-15 Thread Oscar Benjamin
On 15 April 2016 at 10:48, Albert-Jan Roskam  wrote:
> What I like about both namedtuple and AttrDict is attribute lookup: that
> makes code so, so, s much easier to read. This seems to be a nice
> generalization of your code:
>
> class Point(object):
>
> def __init__(self, **kwargs):
> Point.__slots__ = kwargs.keys()
> for k, v in kwargs.items():
> setattr(self, k, v)

This is not how __slots__ is supposed to work. __slots__ should be
defined in the class statement (outside of any method). The way that
__slots__ works is kind of magical so you can't just set the attribute
on the class any time you like.

I was just imagining that you would define a class with __slots__
listing the attributes instances should have when you want one. That's
how namedtuple works: you make a class with particular attributes. You
seem to want to generalise that so that each instance has different
attributes which is not really the idea.

If you just want an object to which you can attach some attributes
then I think you want types.SimpleNamespace:

https://docs.python.org/3/library/types.html#additional-utility-classes-and-functions

That's new in 3.4 but the docs show how to make something similar:

class SimpleNamespace:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
keys = sorted(self.__dict__)
items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
return "{}({})".format(type(self).__name__, ", ".join(items))
def __eq__(self, other):
return self.__dict__ == other.__dict__

Notice that it just passes the kwargs through to __dict__ rather than
subclassing __dict__ and using a self-reference.

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


Re: [Tutor] question about __copy__ and __deepcopy__

2016-04-15 Thread Albert-Jan Roskam

> From: oscar.j.benja...@gmail.com
> Date: Thu, 14 Apr 2016 21:34:39 +0100
> Subject: Re: [Tutor] question about __copy__ and __deepcopy__
> To: sjeik_ap...@hotmail.com
> CC: tutor@python.org
> 
> On 14 April 2016 at 20:38, Albert-Jan Roskam <sjeik_ap...@hotmail.com> wrote:
> > Hi,
> >
> > Lately I have been using the "mutable namedtuple"  shown below a lot. I 
> > found it somewhere on StackOverflow or ActiveState or something.
> > In its original form, it only had an __init__ method.
> 
> I don't know about your copy/deepcopy stuff. It looked fine to me but
> I'm not very experienced in that area. I wonder what this mutable
> namedtuple is for though.
> 
> Looking at it:
> 
> > class Record(dict):
> >
> > def __init__(self, *args, **kwargs):
> > super(Record, self).__init__(*args, **kwargs)
> > self.__dict__ = self
> 
> It's not so much a mutable namedtuple as an "attribute dict". It's a
> dict whose keys can be accessed as attributes - because it is its own
> instance dict. Of course it also has dict attributes like pop, items
> etc. (see dir(dict) for a list). The reason that dicts use d[k] rather
> than d.k for accessing keys is to be able to store arbitrary keys
> without conflicting with the dict's methods which are attributes.
> 
> A namedtuple is something very different. It subclasses tuple and the
> whole idea is that an instance is lightweight (not having an attribute
> dict) and hashable and imutable etc. A mutable version of that might
> just look like:
> 
> class Point(object):
> # No instance dict:
>  __slots__ = ['x', 'y']
> 
> def __init__(self, x, y):
> self.x = x
> self.y = y
> 
> It depends what you really want it for though.

HI Oscar, 

Ok, I agree that "mutable namedtuple" is a misnomer. I started using a regular 
namedtuple, and then I wanted something with similar functionality, but with 
the possibility to update/mutate the fields. The AttrDict was the option I 
liked. The order of the fields is rarely important in my case. I can easily use 
the AttrDict with SqlAlchemy, too. What I like about both namedtuple and 
AttrDict is attribute lookup: that makes code so, so, s much easier to 
read. This seems to be a nice generalization of your code:

class Point(object):

def __init__(self, **kwargs):
Point.__slots__ = kwargs.keys()
for k, v in kwargs.items():
setattr(self, k, v)

point = Point(x=1, y=2, z=3)
print point.x
point.x = 42
print point.x


I have no experience with __slots__ (but I think I roughly know what it's for). 
I expected this to fail:

point.remark = "booh"

point
Out[36]: <__main__.Point at 0x7f282de9ccd0>

point.remark
Out[37]: 'booh'

How can it be that __slots__ may be extended once the Point class has been 
instantiated?

(sorry if this post is a bit long --this is just so much fun!) If I add a 
convenience getter/setter, the setter does indeed only seem to work for 
attributes that were in __slots__ already (here "z")

class Point(object):

def __init__(self, **kwargs):
Point.__slots__ = kwargs.keys()
for k, v in kwargs.items():
setattr(self, k, v)

@property
def values(self):
return {attr: getattr(self, attr) for attr in Point.__slots__}
@values.setter
def values(self, d):
for attr, value in d.items():
print "setting", attr, value
setattr(self, attr, value)


point = Point(x=1, y=2, z=3)
print point.x
point.x = 42
print point.x
print point.values
point.values = dict(a=1, b=2, c=3)
print point.values  ## no a, b, c here!
point.values = dict(a=1, b=2, z=444)
print point.values   # z is updated, though!


Thank you!

Albert-Jan

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


Re: [Tutor] question about __copy__ and __deepcopy__

2016-04-15 Thread Oscar Benjamin
On 15 April 2016 at 09:55, Albert-Jan Roskam  wrote:
>
> Heh, it's my fancy __str__ method that confused me. This is what I get when I 
> run my code without __copy__ and __deepcopy__
> runfile('/home/albertjan/Downloads/attrdict_tutor.py', 
> wdir='/home/albertjan/Downloads')
> {'x': 1, 'y': 2, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]} {'x': 1, 'y': 2, 'z': 
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
> {'x': 1, 'y': 2, 'z': [42, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]} {}   # print 
> statements --> call __str__
>
> dc.__str__()
> Out[19]: '{}'
>
> dc.__repr__()
> Out[20]: "{'y': 2, 'x': 1, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}"
>
> Wicked. I do not understand the output of dc.__str__(). Somehow self.__dict__ 
> is empty. If I store a deepcopy of the instance __dict__ in a class attribute 
> "Record.dict_copy", __str__ does not return just the two curly braces. It's 
> wasteful to create a copy, though.

This kind of confusion comes from setting self.__dict__ = self. That's
not really a normal thing to do so I wouldn't expect it to necessarily
be supported by other things like copy.copy:

In [1]: class Record(dict):
   ...: def __init__(self, *args, **kwargs):
   ...: super(Record, self).__init__(*args, **kwargs)
   ...: self.__dict__ = self
   ...:

In [2]: r = Record(x=1, y=2)

In [3]: r
Out[3]: {'x': 1, 'y': 2}

In [4]: r.__dict__ is r# <--- Compare with r2 below
Out[4]: True

In [5]: import copy

In [6]: r2 = copy.copy(r)

In [7]: r2
Out[7]: {'x': 1, 'y': 2}

In [8]: r2.__dict__
Out[8]: {'x': 1, 'y': 2}

In [9]: r2 is r2.__dict__  # <-- self.__dict__ is not self
Out[9]: False

In [13]: type(r2.__dict__)
Out[13]: dict

In [14]: type(r.__dict__)
Out[14]: __main__.Record

In [15]: r2.__dict__ == r.__dict__  # <-- Equal but distinct
Out[15]: True

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


Re: [Tutor] question about __copy__ and __deepcopy__

2016-04-15 Thread Albert-Jan Roskam

> Date: Fri, 15 Apr 2016 16:30:16 +1000
> From: st...@pearwood.info
> To: tutor@python.org
> Subject: Re: [Tutor] question about __copy__ and __deepcopy__
> 
> On Thu, Apr 14, 2016 at 07:38:31PM +, Albert-Jan Roskam wrote:
> > Hi,
> > 
> > Lately I have been using the "mutable namedtuple"  shown below a lot. 
> > I found it somewhere on StackOverflow or ActiveState or something. In 
> > its original form, it only had an __init__ method. I noticed that 
> > copying Record objects sometimes failed.
> 
> Failed how?
> 
> Given how simple the class looks, I wonder whether that's a bug in copy. 
> Apart from a fancy __str__ method, there's practically nothing to it!
> 
> So I took your Record class, stripped out the __copy__ and __deepcopy__ 
> methods, created a slightly complex instance, and tried copying it:
> 
> d = Record(spam=23, ham=42, eggs=[], cheese={})
> d.cheese[1] = None
> d.cheese[2] = ['a', 'b', 'c']
> d.eggs.append(100)
> d.eggs.append(200)
> d.eggs.append(d)
> d.eggs.append(d.cheese)
> 
> from copy import copy, deepcopy
> 
> copy(d)
> deepcopy(d)
> 
> 
> and both appeat to work correctly. So perhaps you ought to look more 
> carefully at the copying failure?

Hi Steven,

Heh, it's my fancy __str__ method that confused me. This is what I get when I 
run my code without __copy__ and __deepcopy__
runfile('/home/albertjan/Downloads/attrdict_tutor.py', 
wdir='/home/albertjan/Downloads')
{'x': 1, 'y': 2, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]} {'x': 1, 'y': 2, 'z': [0, 
1, 2, 3, 4, 5, 6, 7, 8, 9]}
{'x': 1, 'y': 2, 'z': [42, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]} {}   # print 
statements --> call __str__

dc.__str__()
Out[19]: '{}'

dc.__repr__()
Out[20]: "{'y': 2, 'x': 1, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}"

Wicked. I do not understand the output of dc.__str__(). Somehow self.__dict__ 
is empty. If I store a deepcopy of the instance __dict__ in a class attribute 
"Record.dict_copy", __str__ does not return just the two curly braces. It's 
wasteful to create a copy, though.

from copy import copy, deepcopy

class Record(dict):

def __init__(self, *args, **kwargs):
super(Record, self).__init__(*args, **kwargs)
self.__dict__ = self

def __str__(self):
#items = ["%r: %r" % (k, v) for k, v in sorted(self.__dict__.items())]
Record.dict_copy = deepcopy(self)  # store it as a class attribute.
items = ["%r: %r" % (k, v) for k, v in sorted(Record.dict_copy.items())]
return "{" + ", ".join(items) + "}"

runfile('/home/albertjan/Downloads/attrdict_tutor.py', 
wdir='/home/albertjan/Downloads')
{'x': 1, 'y': 2, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]} {'x': 1, 'y': 2, 'z': [0, 
1, 2, 3, 4, 5, 6, 7, 8, 9]}
{'x': 1, 'y': 2, 'z': [42, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]} {'x': 1, 'y': 2, 'z': 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

dc.__str__()
Out[28]: "{'x': 1, 'y': 2, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}"

dc.__repr__()
Out[29]: "{'y': 2, 'x': 1, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}"



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


Re: [Tutor] question about __copy__ and __deepcopy__

2016-04-15 Thread Steven D'Aprano
On Thu, Apr 14, 2016 at 07:38:31PM +, Albert-Jan Roskam wrote:
> Hi,
> 
> Lately I have been using the "mutable namedtuple"  shown below a lot. 
> I found it somewhere on StackOverflow or ActiveState or something. In 
> its original form, it only had an __init__ method. I noticed that 
> copying Record objects sometimes failed.

Failed how?

Given how simple the class looks, I wonder whether that's a bug in copy. 
Apart from a fancy __str__ method, there's practically nothing to it!

So I took your Record class, stripped out the __copy__ and __deepcopy__ 
methods, created a slightly complex instance, and tried copying it:

d = Record(spam=23, ham=42, eggs=[], cheese={})
d.cheese[1] = None
d.cheese[2] = ['a', 'b', 'c']
d.eggs.append(100)
d.eggs.append(200)
d.eggs.append(d)
d.eggs.append(d.cheese)

from copy import copy, deepcopy

copy(d)
deepcopy(d)


and both appeat to work correctly. So perhaps you ought to look more 
carefully at the copying failure?



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


Re: [Tutor] question about __copy__ and __deepcopy__

2016-04-14 Thread Oscar Benjamin
On 14 April 2016 at 20:38, Albert-Jan Roskam  wrote:
> Hi,
>
> Lately I have been using the "mutable namedtuple"  shown below a lot. I found 
> it somewhere on StackOverflow or ActiveState or something.
> In its original form, it only had an __init__ method.

I don't know about your copy/deepcopy stuff. It looked fine to me but
I'm not very experienced in that area. I wonder what this mutable
namedtuple is for though.

Looking at it:

> class Record(dict):
>
> def __init__(self, *args, **kwargs):
> super(Record, self).__init__(*args, **kwargs)
> self.__dict__ = self

It's not so much a mutable namedtuple as an "attribute dict". It's a
dict whose keys can be accessed as attributes - because it is its own
instance dict. Of course it also has dict attributes like pop, items
etc. (see dir(dict) for a list). The reason that dicts use d[k] rather
than d.k for accessing keys is to be able to store arbitrary keys
without conflicting with the dict's methods which are attributes.

A namedtuple is something very different. It subclasses tuple and the
whole idea is that an instance is lightweight (not having an attribute
dict) and hashable and imutable etc. A mutable version of that might
just look like:

class Point(object):
# No instance dict:
 __slots__ = ['x', 'y']

def __init__(self, x, y):
self.x = x
self.y = y

It depends what you really want it for though.

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


[Tutor] question about __copy__ and __deepcopy__

2016-04-14 Thread Albert-Jan Roskam
Hi,

Lately I have been using the "mutable namedtuple"  shown below a lot. I found 
it somewhere on StackOverflow or ActiveState or something.
In its original form, it only had an __init__ method. I noticed that copying 
Record objects sometimes failed. So I implemented __copy__ and __deepcopy__,
Is this the correct way to do this? In my original use case, even shallow 
copies failed, but I can't reproduce that anymore (or maybe I am imagining 
things!). 
Is __copy__ really needed here? Does __deepcopy__ make any sense at all? My 
tests pass, but still I am not sure!

Thanks!

Albert-Jan

from copy import copy, deepcopy

class Record(dict):

    def __init__(self, *args, **kwargs):
    super(Record, self).__init__(*args, **kwargs)
    self.__dict__ = self

    def __str__(self):
    items = ["%r: %r" % (k, v) for k, v in sorted(self.__dict__.items())]
    return "{" + ", ".join(items) + "}"

    def __copy__(self):
    return Record(**self.__dict__.copy())

    def __deepcopy__(self, memo):
    address = id(self)
    try:
    return memo[address]
    except KeyError:
    memo[address] = {k: copy(v) for k, v in self.items()}
    return deepcopy(self, memo)

if __name__ == "__main__":
    
    # only shallow needed    
    record = Record(x=1, y=2, z=3)
    cp = copy(record)
    assert record == cp and not record is cp
    record = Record(x=1, y=2, z=3)
    dc = deepcopy(record)
    assert record == dc and not record is dc
    
    # mutable value: deepcopy needed
    L = range(10)
    record = Record(x=1, y=2, z=L)
    cp = copy(record)
    print record, cp
    assert record == cp and not record is cp
    dc = deepcopy(record)
    assert record == dc and not record is dc
    L.insert(0, 42)
    expect = {'y': 2, 'x': 1, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
    assert dc == expect and not record is dc
    print record, dc
    
  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] question

2016-02-12 Thread Brianna Hulbert
Hi,

I am new to python and just downloaded it onto my computer. The window
comes up however there is no menu bar across the top that says file, edit,
format, run, options, etc. I was wondering how to get that to appear.

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


Re: [Tutor] question

2016-02-12 Thread wolfrage8...@gmail.com
When you say "Window" are you referring to the Installer or Idle?
Which Operating System are you using and what version of Python did
you download? Did you run the installer that you downloaded?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Question about grid layout

2016-01-17 Thread Ricardo Martínez
Hi folks, first thanks to Peter and Alan for the comments about the
Interpreter, i really appreciate that.

The question that i have in mind is about grid layout, i have the below
code and i want to resize every widget when the user resize the main
windows.

"""
START
"""


import tkinter  as tk
import tkinter.ttk as ttk


class sqlConsole(ttk.Frame):
def __init__(self):
self.root = tk.Tk()
self.width = "640"
self.height = "480"

ttk.Frame.__init__(self, self.root)
self.createWidgets()
self.layoutWidgets()

self.root.mainloop()


def createWidgets(self):
self.frmFrame = ttk.Frame(self.root, width=self.width,
height=self.height)
self.grdResult = ttk.Treeview(self.frmFrame)

self.grdResult.column("#0", width=self.width)
self.frmFrame.grid_propagate(0)


def layoutWidgets(self):
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.frmFrame.rowconfigure(0, weight=1)
self.frmFrame.columnconfigure(0, weight=1, minsize=self.width)

self.grdResult.grid(row=0, column=0, columnspan=5, padx=5, pady=5, \
sticky="nsew")
self.frmFrame.grid(sticky="nsew")


if __name__ == "__main__":
app = sqlConsole()


"""
END
"""

The issue that i have is when i resize the window the Treeview won't, i
tried combinations of sticky as NWSE, or WS, but is not working for me,
and i think that i'm missing some instruction in the grid layout that is
avoiding the widget resize.

I've googled the issue but not finish to understand the "misterious ways of
the grid layout", sometimes i think that is like "the ways of the force".

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


Re: [Tutor] Question about grid layout

2016-01-17 Thread Alan Gauld
On 17/01/16 18:27, Ricardo Martínez wrote:
> Hi folks, first thanks to Peter and Alan for the comments about the
> Interpreter, i really appreciate that.

I don't remember giving any comments about the interpreter,
but if I did you're welcome! :-)

> The question that i have in mind is about grid layout, i have the below
> code and i want to resize every widget when the user resize the main
> windows.

Personally I rarely use grid() unless it really is
a form that I'm creating. Usually I use pack() because
I find it more flexible. So I'd suggest that you pack()
the treeview into the frame then grid() the frame.

In the packer use the expand=True and fill=BOTH options.


-- 
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] Question about the memory manager

2016-01-17 Thread Albert-Jan Roskam
> From: eryk...@gmail.com
> Date: Thu, 14 Jan 2016 04:42:57 -0600
> Subject: Re: [Tutor] Question about the memory manager
> To: tutor@python.org
> CC: sjeik_ap...@hotmail.com
> 
> On Thu, Jan 14, 2016 at 3:03 AM, Albert-Jan Roskam
> <sjeik_ap...@hotmail.com> wrote:
> >
> > These two pages are quite nice. The author says the memory used by small 
> > objects is
> > never returned to the OS, which may be problematic for long running 
> > processes.
> 
> The article by Evan Jones discusses a patch to enable releasing unused
> arenas (i.e. "how the problem was fixed"). Starting with 2.5, unused
> arenas do get released back to the heap. Here's the diff in which Tim
> Peters merged in a "heavily altered derivative" of Evan's patch [1].
> 
> Also, 2.7 and 3.3 bypass C malloc/free and the process heap to instead
> use mmap/munmap on POSIX when available. This avoids the heap
> high-water mark problem. Similarly, 3.4 switched to using
> VirtualAlloc/VirtualFree on Windows. 3.4 also introduced the
> PyObjectArenaAllocator and associated C API functions [2] to allow
> modifying the default allocators.
> 
> [1]: https://hg.python.org/cpython/diff/685849bd905c/Objects/obmalloc.c
> [2]: 
> https://docs.python.org/3/c-api/memory.html#customize-pyobject-arena-allocator

Hi Eryk,

Thanks a lot for the info and the links. This is truly interesting to read 
about! Glad to know that the high-water mark problem is no longer relevant 
anymore in recent Python versions. Also, thank you for your suggestion about 
psutils (and ctypes).

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


Re: [Tutor] Question about the memory manager

2016-01-14 Thread eryk sun
On Thu, Jan 14, 2016 at 3:03 AM, Albert-Jan Roskam
 wrote:
>
> These two pages are quite nice. The author says the memory used by small 
> objects is
> never returned to the OS, which may be problematic for long running processes.

The article by Evan Jones discusses a patch to enable releasing unused
arenas (i.e. "how the problem was fixed"). Starting with 2.5, unused
arenas do get released back to the heap. Here's the diff in which Tim
Peters merged in a "heavily altered derivative" of Evan's patch [1].

Also, 2.7 and 3.3 bypass C malloc/free and the process heap to instead
use mmap/munmap on POSIX when available. This avoids the heap
high-water mark problem. Similarly, 3.4 switched to using
VirtualAlloc/VirtualFree on Windows. 3.4 also introduced the
PyObjectArenaAllocator and associated C API functions [2] to allow
modifying the default allocators.

[1]: https://hg.python.org/cpython/diff/685849bd905c/Objects/obmalloc.c
[2]: 
https://docs.python.org/3/c-api/memory.html#customize-pyobject-arena-allocator
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question about the memory manager

2016-01-14 Thread Albert-Jan Roskam
D

> From: sjeik_ap...@hotmail.com
> To: tim.pet...@gmail.com
> Date: Wed, 13 Jan 2016 08:11:11 +
> Subject: Re: [Tutor] Question about the memory manager
> CC: tutor@python.org
> 
> > From: tim.pet...@gmail.com
> > Date: Sun, 10 Jan 2016 10:54:10 -0600
> > Subject: Re: [Tutor] Question about the memory manager
> > To: sjeik_ap...@hotmail.com
> > CC: tutor@python.org
> > 
> > [Albert-Jan Roskam <sjeik_ap...@hotmail.com>]
> > > I just found a neat trick to free up an emergency stash of memory in
> > > a funtion that overrides sys.excepthook. The rationale is that all
> > > exceptions, including MemoryErrors will be logged.
> > > The code is below. My question: is that memory *guaranteed* to be
> > > freed right after the 'del' statement? Or should one call gc.collect to
> > > be really sure?
> > >
> > > rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
> > > def handle_exception(e):
> > > global rainydayfund
> > > del rainydayfund
> > > ... etc, etc ...
> > > http://stackoverflow.com/questions/1235349/python-how-can-i-handle-any-unhandled-exception-in-an-alternative-way
> > 
> > This works fine in all versions of CPython (the C implementation of
> > Python distributed by python.org) to date.  That's because:
> > 
> > 1. All versions of CPython rely primarily on reference counting (`gc`
> > is only needed to reclaim garbage containing reference cycles).  An
> > object is released immediately when its reference count falls to 0.
> > 
> > 2. There is only one reference to the big list there (via the global
> > `raindydayfund`), so the memory becomes garbage immediately upon
> > executing the `del`.
> > 
> > 3. Similarly, that giant list holds the only references to the masses
> > of distinct empty lists it contains, so they also become garbage
> > immediately upon the giant list becoming garbage.
> > 
> > 4. CPython doesn't happen to stick garbage lists in, e.g., some
> > internal free list reusable only for new list objects - it actually
> > releases the memory for garbage lists.  Kinda ;-)
> > 
> > #2 and #3 are necessarily true.  #1 is true in CPython, but not in all
> > implementations of Python.
> > 
> > #4 is where things _might_ change even in CPython, but it's very
> > unlikely to change.  As is, it would take a small book to flesh out
> > what "Kinda ;-)" means, exactly.  Memory management is complex, with
> > many layers, involving many details.
> > 
> > If you can live with all that, I'd suggest a more straightforward way
> > of setting it up, like:
> > 
> > rainydayfund  = b"x" * N
> > 
> > where `N` is the number of bytes you want to reserve.  That is, create
> > a giant bytestring containing the number of "emergency bytes" you
> > need.  If N is large enough, that will avoid CPython's "small object
> > allocator" and CPython's "arena allocator", getting the memory
> > directly from (and returning the memory directly to) the OS.  The
> > fewer layers that get involved, the fewer layers that _may_ surprise
> > you by changing behavior in the future.
> 
> Hi Tim,
> 
> Thank you! Can you recommend a document or website that CPython's memory 
> manager?
> Might be interesting and perhaps useful to know a bit more about the details. 
> Perhaps this knowledge might sometimes help writing faster code?
> 

These two pages are quite nice. The author says the memory used by small 
objects is never returned to the OS, which may be problematic for long running 
processes. It appears that it is better to have a few big objects rather than 
many small ones, because memory is more likely to become fragmented with many 
deleted small objects (and there's no such thing as gc.defrag)
http://www.evanjones.ca/memoryallocator/
http://deeplearning.net/software/theano/tutorial/python-memory-management.html


> Best wishes,
> Albert-Jan
> 
> PS:
> 
> albertjan@debian:~$ python -c "import this" 
> The Zen of Python, by Tim Peters
> 
> ...
> ...
> There should be one-- and preferably only one --obvious way to do it.
> Although that way may not be obvious at first unless you're Dutch.
> 
> --> Nope not even then. Perhaps if my name were Guido? :-)
> 
> 
> 
> 
> ___
> 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 the memory manager

2016-01-13 Thread Albert-Jan Roskam
> To: tutor@python.org
> From: __pete...@web.de
> Date: Sun, 10 Jan 2016 18:29:06 +0100
> Subject: Re: [Tutor] Question about the memory manager
> 
> Albert-Jan Roskam wrote:
> 
> > Hi,
> > 
> > I just found a neat trick to free up an emergency stash of memory in a
> > funtion that overrides sys.excepthook. The rationale is that all
> > exceptions, including MemoryErrors will be logged. The code is below. My
> > question: is that memory *guaranteed* to be freed right after the 'del'
> > statement? Or should one call gc.collect to be really sure?
> > 
> > rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
> > def handle_exception(e):
> > global rainydayfund
> > del rainydayfund
> > ... etc, etc ...
> > http://stackoverflow.com/questions/1235349/python-how-can-i-handle-any-unhandled-exception-in-an-alternative-way
> 
> I must admit that this looks rather strange to me, but I don't see any 
> problem why it wouldn't work. gc.collect() only helps with circular 
> dependencies, and there aren't any in your "rainy day fund".
> 
> Regarding the use of sys.excepthook I'd rather (SO voting be damned!) take 
> the obvious approach as suggested by Vinay Sajip, i. e.
> 
> try:
> main()
> except:
> # do what you have to do
> 
> instead of rewriting the hook. If potential memory resource hogs are 
> confined within main() with no references from any module namespace you 
> should have enough memory availaible to run the except suite without the 
> need for a rainy day fund. If you know about a specific global name that 
> references a consumer of a lot of memory, an in-memory db, say, then why not 
> handle the memory error there or at least use it in lieu of a dedicated 
> dummy? I. e.
> 
> in_memory_db = None
> try:
> try:
> main()
> finally:
> del in_memory_db
> except:
> # do what you have to do

Hi all,

Thanks for your replies. Initially my main concern was to also log 
fatal/unhandled exceptions. The database MemoryError was also I was also an 
issue I was just facing, so Martelli's approach seemed nice. Meanwhile I found 
out I did not only delete "TOP 100" (which I used to debug my code) in my 
SELECT query, but also DISTINCT. After I corrected this MemoryErrors are no 
longer an issue with this function. :-) Still, I always wonder how close I am 
to a MemoryError (I am on a tiny Win 7 32 VM, with Python 2.7). I sometimes 
check the Task Manager to see how much RAM is in use. Is there a Python way to 
do something similar?

Best wishes,
Albert-Jan


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


Re: [Tutor] Question about the memory manager

2016-01-11 Thread Alan Gauld
On 10/01/16 16:16, Steven D'Aprano wrote:

>> rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
>> def handle_exception(e):
>> global rainydayfund
>> del rainydayfund
>> ... etc, etc ...
> 
> I was going to write a scornful email about how useless this would be.

Me too.

> still think it's useless, but I see that the idea comes from Alex 
> Martelli, who normally knows what he is talking about, so that makes me 
> pause and think and perhaps do some experiments before commenting.

Me too. :-)

But I think that it definitely is heavily OS dependent.
It should work in most *nix environments the first time
you call the function. But on second call I'd expect
all bets to be off. And in most real-time OS's memory
goes right back to the OS pool - but even there it
would probably be available I guess, at least the first
time.

Maybe the theory is that if you get a memory error the
only sensible thing is just to log it and exit. In which
case you only ever call this once.

Steven, Did you try any experiments? I'm struggling
to come up with a reliable test scenario.

-- 
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] Question about the memory manager

2016-01-11 Thread James Chapman
If you read the comment that goes with the code snippet pasted in the
original email it makes far more sense as the author is talking
specifically about out of memory errors...


"You already got excellent answers, I just wanted to add one more tip
that's served me well over the years in a variety of language for the
specific problem "how to cleanly diagnose, log, etc, out of memory
errors?". Problem is, if your code gets control before enough objects
have been destroyed and their memory recycled, memory might be too
tight to do propert logging, gui work, etc, etc -- how do we ensure
this doesn't happen?

Answer: build an emergency stash so you know you can spend it in such
emergencies:

rainydayfund = [[] for x in xrange(16*1024)]  # or however much you need

def handle_exception(e):
  global rainydayfund
  del rainydayfund
  ... etc, etc ...

" - Alex Martelli


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


Re: [Tutor] Question about the memory manager

2016-01-11 Thread Oscar Benjamin
On 11 January 2016 at 12:15, Alan Gauld  wrote:
>
> But I think that it definitely is heavily OS dependent.
> It should work in most *nix environments the first time
> you call the function. But on second call I'd expect
> all bets to be off. And in most real-time OS's memory
> goes right back to the OS pool - but even there it
> would probably be available I guess, at least the first
> time.
>
> Maybe the theory is that if you get a memory error the
> only sensible thing is just to log it and exit. In which
> case you only ever call this once.
>
> Steven, Did you try any experiments? I'm struggling
> to come up with a reliable test scenario.

I can't even work out how you trigger a MemoryError on Linux (apart
from just raising one). I've tried a few ways to make the system run
out of memory and it just borks the system rather than raise any error
- I can only interrupt it with REISUB.

Here's a simple one:

$ python -c 'x = []; x.append(iter(x))'

(Make sure you save all your work before trying that!)

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


Re: [Tutor] Question about the memory manager

2016-01-11 Thread Oscar Benjamin
On 11 January 2016 at 15:40, Peter Otten <__pete...@web.de> wrote:
>> I can't even work out how you trigger a MemoryError on Linux (apart
>> from just raising one). I've tried a few ways to make the system run
>> out of memory and it just borks the system rather than raise any error
>> - I can only interrupt it with REISUB.
>>
>> Here's a simple one:
>>
>> $ python -c 'x = []; x.append(iter(x))'
>>
>> (Make sure you save all your work before trying that!)
>
> You can set the interpreter on a diet:
>
> $ ulimit -v 22000
> $ python -c 'print "x"'
> x
> $ python -c 'print "x"*10**6'
> Traceback (most recent call last):
>   File "", line 1, in 
> MemoryError

This didn't initially work for me:

$ ulimit -v 22000
$ python -c 'print "x"*10**6'
python: error while loading shared libraries: libc.so.6: failed to map
segment from shared object: Cannot allocate memory

I guess that limit's too low so (in a new terminal):

$ ulimit -v 5
$ python -c '"x"*10**8'
Traceback (most recent call last):
  File "", line 1, in 
MemoryError
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line
66, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
  File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 1,
in 
from apport.report import Report
  File "/usr/lib/python2.7/dist-packages/apport/report.py", line 20, in 
import apport.fileutils
  File "/usr/lib/python2.7/dist-packages/apport/fileutils.py", line
22, in 
from apport.packaging_impl import impl as packaging
  File "/usr/lib/python2.7/dist-packages/apport/packaging_impl.py",
line 20, in 
import apt
  File "/usr/lib/python2.7/dist-packages/apt/__init__.py", line 21, in 
import apt_pkg
ImportError: /usr/lib/python2.7/dist-packages/apt_pkg.so: failed to
map segment from shared object: Cannot allocate memory

Original exception was:
Traceback (most recent call last):
  File "", line 1, in 
MemoryError

So it seems that it ran out of memory and sys.excepthook failed
because of insufficient memory which is the situation Alex Martelli
described. However:

$ python -c 'raise ValueError'
Traceback (most recent call last):
  ...
ImportError: /usr/lib/python2.7/dist-packages/apt_pkg.so: failed to
map segment from shared object: Cannot allocate memory

Original exception was:
Traceback (most recent call last):
  File "", line 1, in 
ValueError

It seems I need a ulimit of 6 to get this to work properly:

$ ulimit -v 6
$ python -c 'raise ValueError'
Traceback (most recent call last):
  File "", line 1, in 
ValueError
$ python -c '"x"*10**8'
Traceback (most recent call last):
  File "", line 1, in 
MemoryError

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


Re: [Tutor] Question about the memory manager

2016-01-11 Thread Peter Otten
Oscar Benjamin wrote:

> On 11 January 2016 at 12:15, Alan Gauld  wrote:
>>
>> But I think that it definitely is heavily OS dependent.
>> It should work in most *nix environments the first time
>> you call the function. But on second call I'd expect
>> all bets to be off. And in most real-time OS's memory
>> goes right back to the OS pool - but even there it
>> would probably be available I guess, at least the first
>> time.
>>
>> Maybe the theory is that if you get a memory error the
>> only sensible thing is just to log it and exit. In which
>> case you only ever call this once.
>>
>> Steven, Did you try any experiments? I'm struggling
>> to come up with a reliable test scenario.
> 
> I can't even work out how you trigger a MemoryError on Linux (apart
> from just raising one). I've tried a few ways to make the system run
> out of memory and it just borks the system rather than raise any error
> - I can only interrupt it with REISUB.
> 
> Here's a simple one:
> 
> $ python -c 'x = []; x.append(iter(x))'
> 
> (Make sure you save all your work before trying that!)

You can set the interpreter on a diet:

$ ulimit -v 22000
$ python -c 'print "x"'
x
$ python -c 'print "x"*10**6'
Traceback (most recent call last):
  File "", line 1, in 
MemoryError


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


[Tutor] Question about the memory manager

2016-01-10 Thread Albert-Jan Roskam
Hi,

I just found a neat trick to free up an emergency stash of memory in a funtion 
that overrides sys.excepthook. The rationale is that all exceptions, including 
MemoryErrors will be logged.
The code is below. My question: is that memory *guaranteed* to be freed right 
after the 'del' statement? Or should one call gc.collect to be really sure?

rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
def handle_exception(e):
global rainydayfund
del rainydayfund
... etc, etc ...
http://stackoverflow.com/questions/1235349/python-how-can-i-handle-any-unhandled-exception-in-an-alternative-way

Thanks!

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


Re: [Tutor] Question about the memory manager

2016-01-10 Thread Steven D'Aprano
On Sun, Jan 10, 2016 at 11:53:22AM +, Albert-Jan Roskam wrote:
> Hi,
> 
> I just found a neat trick to free up an emergency stash of memory in a 
> funtion that overrides sys.excepthook.

> rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
> def handle_exception(e):
> global rainydayfund
> del rainydayfund
> ... etc, etc ...

I was going to write a scornful email about how useless this would be. I 
still think it's useless, but I see that the idea comes from Alex 
Martelli, who normally knows what he is talking about, so that makes me 
pause and think and perhaps do some experiments before commenting.

Even the best programmer can have some weird idiosyncratic 
superstitions, but only a fool would assume that Alex Martelli has got 
it wrong without doing some careful investigation. So let me get back to 
you :-)


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


Re: [Tutor] Question about the memory manager

2016-01-10 Thread Tim Peters
[Albert-Jan Roskam ]
> I just found a neat trick to free up an emergency stash of memory in
> a funtion that overrides sys.excepthook. The rationale is that all
> exceptions, including MemoryErrors will be logged.
> The code is below. My question: is that memory *guaranteed* to be
> freed right after the 'del' statement? Or should one call gc.collect to
> be really sure?
>
> rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
> def handle_exception(e):
> global rainydayfund
> del rainydayfund
> ... etc, etc ...
> http://stackoverflow.com/questions/1235349/python-how-can-i-handle-any-unhandled-exception-in-an-alternative-way

This works fine in all versions of CPython (the C implementation of
Python distributed by python.org) to date.  That's because:

1. All versions of CPython rely primarily on reference counting (`gc`
is only needed to reclaim garbage containing reference cycles).  An
object is released immediately when its reference count falls to 0.

2. There is only one reference to the big list there (via the global
`raindydayfund`), so the memory becomes garbage immediately upon
executing the `del`.

3. Similarly, that giant list holds the only references to the masses
of distinct empty lists it contains, so they also become garbage
immediately upon the giant list becoming garbage.

4. CPython doesn't happen to stick garbage lists in, e.g., some
internal free list reusable only for new list objects - it actually
releases the memory for garbage lists.  Kinda ;-)

#2 and #3 are necessarily true.  #1 is true in CPython, but not in all
implementations of Python.

#4 is where things _might_ change even in CPython, but it's very
unlikely to change.  As is, it would take a small book to flesh out
what "Kinda ;-)" means, exactly.  Memory management is complex, with
many layers, involving many details.

If you can live with all that, I'd suggest a more straightforward way
of setting it up, like:

rainydayfund  = b"x" * N

where `N` is the number of bytes you want to reserve.  That is, create
a giant bytestring containing the number of "emergency bytes" you
need.  If N is large enough, that will avoid CPython's "small object
allocator" and CPython's "arena allocator", getting the memory
directly from (and returning the memory directly to) the OS.  The
fewer layers that get involved, the fewer layers that _may_ surprise
you by changing behavior in the future.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Question about the memory manager

2016-01-10 Thread Peter Otten
Albert-Jan Roskam wrote:

> Hi,
> 
> I just found a neat trick to free up an emergency stash of memory in a
> funtion that overrides sys.excepthook. The rationale is that all
> exceptions, including MemoryErrors will be logged. The code is below. My
> question: is that memory *guaranteed* to be freed right after the 'del'
> statement? Or should one call gc.collect to be really sure?
> 
> rainydayfund = [[] for x in xrange(16*1024)] # or however much you need
> def handle_exception(e):
> global rainydayfund
> del rainydayfund
> ... etc, etc ...
> http://stackoverflow.com/questions/1235349/python-how-can-i-handle-any-unhandled-exception-in-an-alternative-way

I must admit that this looks rather strange to me, but I don't see any 
problem why it wouldn't work. gc.collect() only helps with circular 
dependencies, and there aren't any in your "rainy day fund".

Regarding the use of sys.excepthook I'd rather (SO voting be damned!) take 
the obvious approach as suggested by Vinay Sajip, i. e.

try:
main()
except:
# do what you have to do

instead of rewriting the hook. If potential memory resource hogs are 
confined within main() with no references from any module namespace you 
should have enough memory availaible to run the except suite without the 
need for a rainy day fund. If you know about a specific global name that 
references a consumer of a lot of memory, an in-memory db, say, then why not 
handle the memory error there or at least use it in lieu of a dedicated 
dummy? I. e.

in_memory_db = None
try:
try:
main()
finally:
del in_memory_db
except:
# do what you have to do



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


Re: [Tutor] question about "__main__"

2015-11-16 Thread Alan Gauld

On 16/11/15 15:30, CUONG LY wrote:

Hello,

I’m learning Python.


Hello, welcome.


I want to know what does the following line represent
if __name__ == ‘__main__’:


The short answer is that it tests whether the file is being
imported as a module or executed as a program.
If its being imported as a module its __name__ attribute will
be set to the name of the module.

If its being executed as the main (top level) program file
its __name__ will be set to "__main__".

So when you see:

if __name__ == ‘__main__’:
# some code here

the 'some code here' block will only be executed if the file
is being executed as a program. It will not be executed
if the file is being imported by another file.

That will only make sense if you have come across modules yet.
If not don't worry about it, you will get there eventually.
Then it will all become clear.

> and why I see some python codes have two of them ?

I don't know, I've never seen two.
But it is perfectly acceptable to do it, just a
little pointless - unless perhaps they are inside
a function or something.

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


[Tutor] question about "__main__"

2015-11-16 Thread CUONG LY
Hello,

I’m learning Python. 

I want to know what does the following line represent and why I see some python 
codes have two of them ?

if __name__ == ‘__main__’:




Thanks in advance

Cuong
___
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-13 Thread Albert-Jan Roskam
> To: tutor@python.org
> From: __pete...@web.de
> Date: Fri, 13 Nov 2015 09:26:55 +0100
> Subject: Re: [Tutor] question about descriptors
> 
> Albert-Jan Roskam wrote:
> 
> >> __getattr__() is only invoked as a fallback when the normal attribute
> >> lookup fails:
> > 
> > 
> > Aha.. and "normal attributes" live in self.__dict__?
> 
> I meant "normal (attribute lookup)" rather than "(normal attribute) lookup".
> __getattr__() works the same (I think) when there is no __dict__: 
> 
> >>> class A(object):
> ... __slots__ = ["foo"]
> ... def __getattr__(self, name):
> ... print "looking for", name
> ... return 42
> ... 
> >>> a = A()
> >>> a.foo
> looking for foo
> 42
> >>> a.__dict__
> looking for __dict__
> 42
> >>> a.foo = "bar"
> >>> a.foo
> 'bar'

Thank you again for the explanation. Much appreciated. I had not even thought 
about __slots__ yet.

  
___
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-13 Thread Steven D'Aprano
On Thu, Nov 12, 2015 at 12:11:19PM +, Albert-Jan Roskam wrote:

> > __getattr__() is only invoked as a fallback when the normal attribute 
> > lookup 
> > fails:
> 
> 
> Aha.. and "normal attributes" live in self.__dict__?

Not necessarily.

Attributes can live either in "slots" or the instance dict, or the class 
dict, or one of the superclass dicts. Some examples may help. Let's 
start with defining a hierarchy of classes, and make an instance:


class Grandparent(object):
spam = "from the grandparent class"
def __getattr__(self, name):
return "%s calculated by __getattr__" % name

class Parent(Grandparent):
eggs = "from the parent class"

class MyClass(Parent):
cheese = "from the instance's own class"

instance = MyClass()
instance.tomato = "from the instance itself"


The attributes defined above return their value without calling 
__getattr__:

py> instance.tomato, instance.cheese, instance.eggs, instance.spam
('from the instance itself', "from the instance's own class", 
 'from the parent class', 'from the grandparent class')

but only "tomato" lives in the instance __dict__:

py> instance.__dict__
{'tomato': 'from the instance itself'}


You can check MyClass.__dict__, etc. to see the other class attributes. 
And, of course, __getattr__ is called for anything not found in those 
dicts:

py> instance.foo
'foo calculated by __getattr__'


Slots are an alternative to dict-based attributes. If you have millions 
of instances, all with a fixed number of attributes, using a dict for 
each one can waste a lot of memory. Using slots is a way of optimizing 
for memory:

class Slotted(object):
__slots__ = ["spam", "eggs"]
def __init__(self):
self.spam = 1
self.eggs = 2
def __getattr__(self, name):
return "%s calculated by __getattr__" % name

x = Slotted()


This works similarly to the above, except there is no instance dict at 
all:

py> x.spam
1
py> x.eggs
2
py> x.foo
'foo calculated by __getattr__'
py> x.__dict__
'__dict__ calculated by __getattr__'


To be honest, I didn't expect that last result. I expected it to return 
Slotted.__dict__. I'm not entirely sure why it didn't.


[...]
> > If you need to intercept every attribute lookup use __getattribute__():
> 
> Fantastic, thank you for the clear explanation. Do you happen to know 
> whether the __getattr__ vs. __getattribute__ distinction was (a) a 
> deliberate design decision or (b) a historic anomaly? 

A bit of both.

Originally, classes didn't support __getattribute__. Only __getattr__ 
existed (together with __setattr__ and __delattr__), and as you have 
seen, that is only called where the normal attribute lookup mechanism 
fails. That was deliberate.

But in Python 2.2, "new style" classes were added. For technical 
reasons, new-style classes need to support intercepting every attribute 
lookup (that provides the hook for descriptors to work). So 
__getattribute__ was added, but only for new-style classes.

But be warned: writing your own __getattribute__ method is tricky to get 
right, and tends to slow down your class. So it's best avoided, unless 
you really need it.




-- 
Steve
___
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-13 Thread Peter Otten
Albert-Jan Roskam wrote:

>> __getattr__() is only invoked as a fallback when the normal attribute
>> lookup fails:
> 
> 
> Aha.. and "normal attributes" live in self.__dict__?

I meant "normal (attribute lookup)" rather than "(normal attribute) lookup".
__getattr__() works the same (I think) when there is no __dict__: 

>>> class A(object):
... __slots__ = ["foo"]
... def __getattr__(self, name):
... print "looking for", name
... return 42
... 
>>> a = A()
>>> a.foo
looking for foo
42
>>> a.__dict__
looking for __dict__
42
>>> a.foo = "bar"
>>> a.foo
'bar'


___
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-12 Thread Albert-Jan Roskam
> To: tutor@python.org
> From: __pete...@web.de
> Date: Wed, 11 Nov 2015 20:06:20 +0100
> Subject: Re: [Tutor] question about descriptors
> 
> 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:


Aha.. and "normal attributes" live in self.__dict__?


 
> >>> 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__():

Fantastic, thank you for the clear explanation. Do you happen to know whether 
the __getattr__ vs. __getattribute__ distinction was (a) a deliberate design 
decision or (b) a historic anomaly? If one considers the distinction between 
"normal attributes"  vs. "attributes of which the read/write/delete 
properties*) may be changed" , I'd say (a).
 
*) with files these are called "attributes", so one could call them attributes 
with attributes. :-)

> >>> 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
  
___
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
> 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( ... ))
> 

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


Re: [Tutor] question about descriptors

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

> 
> 
> p, li { white-space: pre-wrap; }
> 
> Hi,
> First, before I forget, emails from hotmail/yahoo etc appear to end up in
> the spam folder these days, so apologies in advance if I do not appear to
> follow up to your replies. 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. I now tried to use descriptors
> (__get__ and __set__), which are also used by ' property' (See also:
> https://docs.python.org/2/howto/descriptor.html).
> 
> In the " if __name__ == '__main__'" section, [a] is supposed to be a
> shorthand for == equivalent to [b]. But it's not.I suspect it has to do
> with the way attributes are looked up. So once an attribute has been found
> in self.__dict__ aka "the usual place", the search stops, and __get__ is
> never called. But I may be wrong. I find the __getatttribute__,
> __getattr__ and __get__ distinction quite confusing. What is the best
> approach to do this? Ideally, the column values should only be retrieved
> when they are actually requested (the .csv could be big). Thanks in
> advance!
> 
> 
> 
> import csv
> from cStringIO import StringIO
> 
> 
> class AttrAccess(object):
> 
> 
> def __init__(self, fileObj):
> self.__reader = csv.reader(fileObj, delimiter=";")
> self.__header = self.__reader.next()
> #[setattr(self, name, self.__get_column(name)) for name in
> #[self.header]
> self.a = range(10)
> 
> 
> @property
> def header(self):
> return self.__header
> 
> def __get_column(self, name):
> return [record[self.header.index(name)] for record in
> self.__reader]  # generator expression might be better here.
> 
> def __get__(self, obj, objtype=type):
> print "__get__ called"
> return self.__get_column(obj)
> #return getattr(self, obj)
> 
> def __set__(self, obj, val):
> raise AttributeError("Can't set attribute")
> 
> if __name__ == " __main__":
> f = StringIO("a;b;c\n1;2;3\n4;5;6\n7;8;9\n")
> instance = AttrAccess(f)
> print instance.a  # [a] does not call __get__. Looks, and finds, in
> self.__dict__?
> print instance.__get__("a")  # [b] this is supposed to be equivalent
> to [a]
> instance.a = 42  # should throw AttributeError!

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.

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

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


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

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


___
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-07 Thread Alan Gauld

On 07/11/15 12:53, 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.


Can you clarify what you mean by that?
The csvreader is by definition read only.
So is it the in-memory  model that you want read-only?
Except you don't really have an in-memory model that I can see?


E.g. when a file has a column named 'a', that column should

> be returned as list by using instance.a.

That appears to be a separate issue to whether the returned
list is read-only or not? As ever the issue of dynamically
naming variables at run time and then figuring out how to
access them later raises its head. Its hardly ever a good plan.


At first I thought I could do this with the builtin 'property'

> class, but I am not sure how.

To use property I think you'd need to know the names of your
columns in advance. (Or dynamically build your classes)


I now tried to use descriptors (__get__ and __set__),
which are also used by ' property'



In the " if __name__ == '__main__'" section, [a] is supposed

> to be a shorthand for == equivalent to [b].

I have no idea what you mean by that sentence?


class AttrAccess(object):

 def __init__(self, fileObj):
 self.__reader = csv.reader(fileObj, delimiter=";")
 self.__header = self.__reader.next()
 @property
 def header(self):
 return self.__header

 def __get_column(self, name):
 return [record[self.header.index(name)] for record in self.__reader]  
# generator expression might be better here.


You should only get the index once otherwise it could add a lot of time 
for a long file(especially if there were a lot of columns)


 def __get_column(self, name):
idx = self.header.index(name)
return [record[idx] for record in self.__reader]


 def __get__(self, obj, objtype=type):
 print "__get__ called"
 return self.__get_column(obj)
 #return getattr(self, obj)

 def __set__(self, obj, val):
 raise AttributeError("Can't set attribute")


If you want everything read-only should this not be __setattr__()?


--
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] question about descriptors

2015-11-07 Thread Steven D'Aprano
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.


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'][:]



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.


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


(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!)


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

You might be tempted to write this instead:

setattr(self.__class__, key, property( ... ))

but that's even worse. Now, every time you create a new ColumnView 
instance, *all the other instances will change*. They will grown new 
properties, or overwrite existing properties. You don't want that.

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)



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


Re: [Tutor] Question how to ready data from excle file and convert the german to english language

2015-09-10 Thread Alan Gauld

On 10/09/15 18:00, Sarika Shrivastava wrote:


I wanted to ready data from excel file  which in german Language and
onovert to English language ??


Those are two completely separate questions.

To read Excel there are several options. The simplest
is if you can convert the file to csv and use the
csv module from the standard library.

Failing that Google python excel reader, you should come
up with something like xlrd or openpyxl

To translate from German to English you probably should
look into the API from Google for their translator.

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


[Tutor] Question how to ready data from excle file and convert the german to english language

2015-09-10 Thread Sarika Shrivastava
Hello pythonistats,

I wanted to ready data from excel file  which in german Language and
onovert to English language ??

-- 
Thanks

Sarika Shrivastava | Software Developer Trainee

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


Re: [Tutor] question / decision tree

2015-08-05 Thread Laura Creighton
In a message of Mon, 03 Aug 2015 10:38:40 +0100, matej taferner writes:
Or maybe should I go with the tkinter?

You have to decide whether what you want is a Stand Alone GUI Application
(in which case tkinter could be a fine idea) or a web app.  It sounds
to me as if you want your customers to navigate to your site and then
fill out a questionaire.  If this is the case, then it's a web app
you want to write.

You generally write buttons and the like in web apps in javascript,
not python.  Then you connect them to whatever web framework you use.
Django, which you mentioned before, would work.  So would web2py and
there are others, many, many others see:
https://wiki.python.org/moin/WebFrameworks (which isn't completely up
to date -- I know there have been 2015 releases for most of these
Frameworks).

Which one you should use is a very personal decision.  There really
isn't anything to do but to try building a small app with every one
you are curious about and then see which you find most pleasant to
use.  People differ enormously on this issue, and indeed the very
things that make the people who love framework A think it is
wonderful are the things that other people cannot stand about it, and
are the reasons why they never use the thing.

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


[Tutor] Question

2015-08-04 Thread Lulwa Bin Shuker
Dear Python tutor list ...

I'm currently learning Python through an online course but after learning
the basics of the language I need to apply what I learned on a real project
and start practicing it. How can I do that ?

Thanks,

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


Re: [Tutor] Question

2015-08-04 Thread Alan Gauld

On 04/08/15 05:21, Lulwa Bin Shuker wrote:


I'm currently learning Python through an online course but after learning
the basics of the language I need to apply what I learned on a real project
and start practicing it. How can I do that ?


Do you have a project in mind but are not sure how to start?
Or do you not know what kind of project to attempt?

There are several options but the best one is to find some
kind of repetitive task that you perform and automate it
using Python. Something you get a personal benefit from.

If you just want to practice Python then you can attempt
the Python Challenge which is a kind of adventure game
for programmers. The tasks get progressively harder as
you climb up through the levels.

PLUG
If you are struggling to know *how* to tackle a project
that you have in mind you could try my latest book
Python Projects which is designed to get beginners
over that initial hurdle by showing how to structure
applications and use the library.
/PLUG

HTH
--
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] question / decision tree

2015-08-03 Thread matej taferner
Or maybe should I go with the tkinter?

2015-08-03 10:36 GMT+01:00 matej taferner matej.tafer...@gmail.com:

 thanks for the reply. I'll definitely check the book.

 The back end solution of the problem is more or less clear to me. What I
 find difficult is the grasp the idea of o called front end dev. or better
 to say what should I use to make buttons should I dig into django framework
 or something else?


 2015-08-03 10:09 GMT+01:00 Laura Creighton l...@openend.se:

 In a message of Mon, 03 Aug 2015 08:58:43 +0100, matej taferner writes:
 hi guys,
 
 I am wondering if there is a python solution for the problem I am
 currently
 dealing with.
 I need to build a decision tree based questionnaire which helps users to
 find the right answer.
 
 As a final product of this decision tree app I need a clickable buttons
 ready to be embedded into the website which will guide customer(s) to
 desired answer(s).
 
 Thanks,
 
 Matej

 I am assuming that your app will need to learn based on user input.
 If you already know what all the answers are going to be, then the
 problem is a lot simpler.

 I have this book.
  Russell  Norvig's Artificial Intelligence: A Modern Approach

 http://www.amazon.com/Artificial-Intelligence-Modern-Approach-Edition/dp/01360\
   42597

 It's comprehensive, but expensive.  Maybe you can borrow it from a
 library.
 Chapters 18-20 are relevant.

 It comes with this code:
 http://aima-python.googlecode.com/svn/trunk/learning.py

 If you google for 'python decision trees' you get many other hits, for
 other code people have written to do this.  This hit has some
 explanation as well.
 http://www.onlamp.com/pub/a/python/2006/02/09/ai_decision_trees.html?page=1

 I haven't tried any of them, so don't know how good any of them are.

 If you know a good bit about machine learning, but don't know a lot
 about Python, then you can probably test them yourself, and we can help
 with getting the code to work, if you need help with that.  If, on the
 other hand, machine learning is new to you, you will need to understand
 more about that first, and will probably need a textbook.  The Russell and
 Norvig book is very good, but there are other good ones out there.

 Laura Creighton



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


Re: [Tutor] question / decision tree

2015-08-03 Thread matej taferner
thanks for the reply. I'll definitely check the book.

The back end solution of the problem is more or less clear to me. What I
find difficult is the grasp the idea of o called front end dev. or better
to say what should I use to make buttons should I dig into django framework
or something else?


2015-08-03 10:09 GMT+01:00 Laura Creighton l...@openend.se:

 In a message of Mon, 03 Aug 2015 08:58:43 +0100, matej taferner writes:
 hi guys,
 
 I am wondering if there is a python solution for the problem I am
 currently
 dealing with.
 I need to build a decision tree based questionnaire which helps users to
 find the right answer.
 
 As a final product of this decision tree app I need a clickable buttons
 ready to be embedded into the website which will guide customer(s) to
 desired answer(s).
 
 Thanks,
 
 Matej

 I am assuming that your app will need to learn based on user input.
 If you already know what all the answers are going to be, then the
 problem is a lot simpler.

 I have this book.
  Russell  Norvig's Artificial Intelligence: A Modern Approach

 http://www.amazon.com/Artificial-Intelligence-Modern-Approach-Edition/dp/01360\
   42597

 It's comprehensive, but expensive.  Maybe you can borrow it from a library.
 Chapters 18-20 are relevant.

 It comes with this code:
 http://aima-python.googlecode.com/svn/trunk/learning.py

 If you google for 'python decision trees' you get many other hits, for
 other code people have written to do this.  This hit has some
 explanation as well.
 http://www.onlamp.com/pub/a/python/2006/02/09/ai_decision_trees.html?page=1

 I haven't tried any of them, so don't know how good any of them are.

 If you know a good bit about machine learning, but don't know a lot
 about Python, then you can probably test them yourself, and we can help
 with getting the code to work, if you need help with that.  If, on the
 other hand, machine learning is new to you, you will need to understand
 more about that first, and will probably need a textbook.  The Russell and
 Norvig book is very good, but there are other good ones out there.

 Laura Creighton


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


  1   2   3   4   5   6   7   8   9   10   >