What happens when a __call__ function is defined in both class and object ?

2017-10-19 Thread ast

Hello, please have a look at following code snippet
(python 3.4.4)

class Test:

   a = 1

   def __init__(self):
   self.a = 2
   self.f = lambda : print("f from object")
   self.__call__ = lambda : print("__call__ from object")
 
   def __call__(self):

   print("__call__ from class Test")
 
   def f(self):

   print("f from class Test")

test=Test()


test.a

2
ok, a is defined in both the class and the object, it is read from
the object. This is the expected behavior


test.f()

f from object

ok for the same reason


test()

__call__ from class Test


Surprisingly, __call__ from the class is called, not the
one defined in the object. Why ?

Regards
--
https://mail.python.org/mailman/listinfo/python-list


integer copy

2017-10-20 Thread ast

Hello, I tried the following:

import copy

a = 5
b = copy.copy(a)

a is b
True

I was expecting False

I am aware that it is useless to copy an integer
(or any immutable type). 


I know that for small integers, there is always a
single integer object in memory, and that for larger
one's there may have many.

a = 7
b = 7
a is b
True

a = 56543
b = 56543
a is b
False

But it seems that Python forbids to have two different
small integer objects with same value even if you
request it with:

a = 5
b = copy.copy(a)

any comments ?


--
https://mail.python.org/mailman/listinfo/python-list


Re: integer copy

2017-10-20 Thread ast


"ast"  a écrit dans le message de 
news:[email protected]...

Neither works for large integers which is
even more disturbing

a = 6555443
b = copy.copy(a)
a is b

True 


--
https://mail.python.org/mailman/listinfo/python-list


Re: integer copy

2017-10-20 Thread ast


"Thomas Nyberg"  a écrit dans le message de 
news:[email protected]...

On 10/20/2017 10:30 AM, ast wrote:

I am aware that it is useless to copy an integer
(or any immutable type).

...

any comments ?



Why is this a problem for you?

Cheers,
Thomas


It is not. It was a test. 


--
https://mail.python.org/mailman/listinfo/python-list


Objects with __name__ attribute

2017-10-24 Thread ast

Hi,

I know two Python's objects which have an intrinsic 
name, classes and functions.


def f():
   pass


f.__name__

'f'

g = f
g.__name__

'f'

class Test:
   pass


Test.__name__

'Test'

Test2 = Test
Test2.__name__

'Test'

Are there others objects with a __name__ attribute
and what is it used for ?

Regards



--
https://mail.python.org/mailman/listinfo/python-list


enum

2017-10-31 Thread ast

Hi

Below an example of enum which defines an __init__
method. 


https://docs.python.org/3.5/library/enum.html#planet

Documentation says that the value of the enum 
members will be passed to this method.


But in that case __init__ waits for two arguments, mass
and radius, while enum member's value is a tuple. 


It seems that there is a tuple unpacking, but it is
not documented, that's not clear 


class Planet(Enum):
... MERCURY = (3.303e+23, 2.4397e6)
... VENUS   = (4.869e+24, 6.0518e6)
... EARTH   = (5.976e+24, 6.37814e6)
... MARS= (6.421e+23, 3.3972e6)
... JUPITER = (1.9e+27,   7.1492e7)
... SATURN  = (5.688e+26, 6.0268e7)
... URANUS  = (8.686e+25, 2.5559e7)
... NEPTUNE = (1.024e+26, 2.4746e7)
...
... def __init__(self, mass, radius):
... self.mass = mass   # in kilograms
... self.radius = radius# in meters
...
... @property
... def surface_gravity(self):
... # universal gravitational constant  (m3 kg-1 s-2)
... G = 6.67300E-11
... return G * self.mass / (self.radius * self.radius)
--
https://mail.python.org/mailman/listinfo/python-list


What happens to module's variables after a "from module import" ?

2017-11-07 Thread ast

Hello

Here is my module tmp.py:

a=0

def test():
   global a
   print(a)
   a+=1

If I import function "test" from module "tmp" with:


from tmp import test


it works


test()

0

test()

1

But where variable "a" is located ? I can't find it anywhere


Regards






--
https://mail.python.org/mailman/listinfo/python-list


Re: What happens to module's variables after a "from module import" ?

2017-11-07 Thread ast


"Paul Moore"  a écrit dans le message de 
news:[email protected]...

On 7 November 2017 at 15:39, ast  wrote:




It's in the "tmp" module, where you defined it. But because you didn't
ask for a reference to it in your import statement, it's not
accessible to you[1].
Do

   import tmp
   print(tmp.a)

and you can see it.

Paul

[1] Technically you can find it via the globals of the function test,
as test.__globals__['a'], but if you understand how that works, you
wouldn't have been asking the question in the first place :-)


Clear, ty 


--
https://mail.python.org/mailman/listinfo/python-list


asyncio loop.call_soon()

2017-11-28 Thread ast

Hello

Python's doc says about loop.call_soon(callback, *arg):

Arrange for a callback to be called as soon as possible. The callback is called 
after call_soon() returns, when control returns to the event loop.


But it doesn't seem to be true; see this program:

import asyncio

async def task_func():
   print("Entering task_func")

def callback():
   print("Entering callback")

async def main():
   print("Entering main")
   task = loop.create_task(task_func())
   loop.call_soon(callback)
   await task

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Execution provides following output:

Entering main
Entering task_func
Entering callback

callback is executed AFTER task_func, I expected it
to be executed BEFORE.

When "main()" coroutine reach line "await task", it let the control 
to the event loop, and it seems that the loop starts to execute 
task instead of callback. Then, when task is over the loop runs 
callback


This is not what the doc says: callback should be called as soon
as possible when the loop has control, with a priority over other
tasks pending in the loop








--
https://mail.python.org/mailman/listinfo/python-list


asyncio awaitable object

2017-12-08 Thread ast

Hello,

According to: 
https://www.python.org/dev/peps/pep-0492/#await-expression

an awaitable object is:

- A native coroutine object returned from a native coroutine function
- A generator-based coroutine object returned from a function decorated 
with types.coroutine()

- An object with an __await__ method returning an iterator

I dont understand the last one.

For example in instruction "res = await obj"

where obj has a __await__ method returning an iterator

What kind of data this generator is supposed to provide when next() 
is applied to it and what are these data becoming ?


what res contains when the iterator has finished to iterate ?

It seems that PEP492 documentation says nothing about it (or I dont 
understand, english is not my native language)










--
https://mail.python.org/mailman/listinfo/python-list


Re: asyncio awaitable object

2017-12-08 Thread ast


"ast"  a écrit dans le message de 
news:[email protected]...

I made some experiment.

It seems that the iterator shall provide None values, an other value
raises an exception: "RuntimeError: Task got bad yield: 1"

and in instruction "res = await obj", res got the StopIteration exception
value

See my test program and output.

import asyncio

class Test:

   def __init__(self):
   self.i = 0
   def __await__(self):
   return self
   def __iter__(self):
   return self
   def __next__(self):
   if self.i < 5:
   self.i += 1
   return None
   else:
   raise StopIteration(11)

test = Test()

async def coro1():
   print("Enter coro1")
   res = await test
   print("end of coro1, res= ", res)

async def coro2():
   print("Enter coro2")
   for i in range(8):
   print("in coro2")
   await asyncio.sleep(0)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([coro1(), coro2()]))

== RESTART ==
Enter coro1
Enter coro2
in coro2
in coro2
in coro2
in coro2
in coro2
end of coro1, res=  11
in coro2
in coro2
in coro2 


--
https://mail.python.org/mailman/listinfo/python-list


Problem with timeit

2017-12-15 Thread ast

Hi

Time measurment with module timeit seems to work with some 
statements but not with some other statements on my computer.


Python version 3.6.3

from timeit import Timer


Timer("'-'.join([str(i) for i in range(10)])").timeit(1)

0.179271876732912

Timer("'-'.join([str(i) for i in range(10)])").timeit(10)

1.7445643231192776

It's OK, with 10 more loops I get 10 more execution time.

But with exponentiation, it's a mess


Timer("x=123456**123456").timeit(1)

6.076191311876755e-06

Timer("x=123456**123456").timeit(10)

3.841270313387213e-06

All wrong, the calculation of 123456**123456 is much longer
than 6 microseconds, it takes few seconds, and with 10 loops 
timeit provided a shorter time ...


What happens plz ?

--
https://mail.python.org/mailman/listinfo/python-list


Re: Problem with timeit

2017-12-15 Thread ast


"Thomas Jollans"  a écrit dans le message de 
news:[email protected]...

On 2017-12-15 11:36, ast wrote:




No, this is right. The calculation takes practically no time; on my
system, it takes some 10 ns. The uncertainty of the timeit result is at
least a few hundred nanoseconds.


There are more than 10 multiplications to perform on a
soaring size integer. I have some doubts "x=123456**123456 "
only takes 10 ns on your system.

On my computer it takes roughtly 4 s, mesured with a watch.
I can't do "len(str(x))" to know the size, I have to kill the process
But x.bit_length() answers 2088091, so x should have about
60 digits

If I measure execution time:


t=time(); x=123456**123456; print(time()-t)

0.0

There is still something wrong

I suppose that my computer CPU goes to 100% busy and
that the timer used by timeit or time no longer works.






--
https://mail.python.org/mailman/listinfo/python-list


Re: Problem with timeit

2017-12-15 Thread ast


"ast"  a écrit dans le message de 
news:[email protected]...

Ty Peter and Steve, I would never have found that
explanation myself 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Problem with timeit

2017-12-18 Thread ast


"Steve D'Aprano"  a écrit dans le message de 
news:[email protected]...

On Sat, 16 Dec 2017 12:25 am, ast wrote:



"Thomas Jollans"  a écrit dans le message de
news:[email protected]...

On 2017-12-15 11:36, ast wrote:








py> x = 123456**123456
py> s = str(x)
py> len(s)
628578




I discovered that log functions from math module
works with integers, whatever their size, there is
no conversion to float.


import math
x = 123456**123456
math.log10(x)

628577.7303641582   (instantaneous)

so 628578 digits


--
https://mail.python.org/mailman/listinfo/python-list


Old format with %

2018-02-14 Thread ast

Hello

It seems that caracter % can't be escaped

>>>"test %d %" % 7
ValueError: incomplete format

>>>"test %d \%" % 7
ValueError: incomplete format

>>>"test %d" % 7 + "%"
'test 7%'  # OK

But is there a way to escape a % ?

thx
--
https://mail.python.org/mailman/listinfo/python-list


Re: Old format with %

2018-02-14 Thread ast

Le 14/02/2018 à 13:46, ast a écrit :

Hello

It seems that caracter % can't be escaped

 >>>"test %d %" % 7
ValueError: incomplete format

 >>>"test %d \%" % 7
ValueError: incomplete format

 >>>"test %d" % 7 + "%"
'test 7%'  # OK

But is there a way to escape a % ?

thx


Found, double % to escape it

>>>"test %d%%" % 7
'test 7%'
--
https://mail.python.org/mailman/listinfo/python-list


Writing some floats in a file in an efficient way

2018-02-21 Thread ast

Hello

I would like to write a huge file of double precision
floats, 8 bytes each, using IEEE754 standard. Since
the file is big, it has to be done in an efficient
way.

I tried pickle module but unfortunately it writes
12 bytes per float instead of just 8.

Example:

import pickle

f = open("data.bin", "wb")
mypickler = pickle.Pickler(f)

mypickler.dump(0.0)
mypickler.dump(-0.0)

f.close()

Let's see what file data.bin contains now:

80 03 47
00 00 00 00 00 00 00 00
2E
80 03 47
80 00 00 00 00 00 00 00
2E

We see our 2 floats
00 00 00 00 00 00 00 00
which is the IEEE754 representation for 0.0 and
80 00 00 00 00 00 00 00
which is the IEEE754 representation for -0.0
yes, there are two 0 for floats, a positive and
a negative one ;-)

but there is a 3 bytes overhead 80 03 47 and an
ending byte 2E for each float. This is a 50% overhead.

Is there a way to write a float with only 8 bytes ?

Thx
--
https://mail.python.org/mailman/listinfo/python-list


Re: Writing some floats in a file in an efficient way

2018-02-21 Thread ast

Le 21/02/2018 à 15:02, bartc a écrit :

On 21/02/2018 13:27, ast wrote:




Time efficient or space efficient?


space efficient


If the latter, how many floats are we talking about?


10^9




--
https://mail.python.org/mailman/listinfo/python-list


Re: Writing some floats in a file in an efficient way

2018-02-21 Thread ast

Le 21/02/2018 à 14:27, ast a écrit :

struct.pack() as advised works fine.
Exemple:

>>> import struct
>>> struct.pack(">d", -0.0)
b'\x80\x00\x00\x00\x00\x00\x00\x00'

before I read your answers I found a way
with pickle

>>> import pickle
>>> pickle.dumps(-0.0)[3:-1]
b'\x80\x00\x00\x00\x00\x00\x00\x00'

but struct.pack() is better
Thx


--
https://mail.python.org/mailman/listinfo/python-list


Re: Writing some floats in a file in an efficient way

2018-02-22 Thread ast

Le 21/02/2018 à 18:23, bartc a écrit :

On 21/02/2018 15:54, ast wrote:

Le 21/02/2018 à 15:02, bartc a écrit :

On 21/02/2018 13:27, ast wrote:




Time efficient or space efficient?


space efficient


If the latter, how many floats are we talking about?


10^9






Although it might be better to convert to proper 32-bit float format in 
this case. This will halve space and probably time requirements.)




Yes, storing 32 bits only floats is a good idea.
and the good news is that struct.pack() does the job.

from struct import *

>>> pack('>ff', 3.1234, 5.3e-7)
b'@G\xe5\xc95\x0eES'  # 2*4 bytes

>>> unpack('>ff', b'@G\xe5\xc95\x0eES')
(3.1233999729156494, 5.30225361146e-07)

What happens if we input some out of range floats ?

>>> pack('>dd', 3.1e-500, 5.3e400)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xf0\x00\x00\x00\x00\x00\x00'
>>> unpack('>dd', 
b'\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xf0\x00\x00\x00\x00\x00\x00')

(0.0, inf)

So underflow/overflow are well handled

I saw there is a half precision float too, on 16 bits, but it is
really unaccurate

--
https://mail.python.org/mailman/listinfo/python-list


File opening modes (r, w, a ...)

2018-02-22 Thread ast

Hello

I share a very valuable table I found on
StackOverflow about file opening modes

If like me you always forget the details of
file opening mode, the following table provides
a good summary

  | r   r+   w   w+   a   a+
--|--
read  | +   +++
write | ++   ++   +
write after seek  | ++   +
create|  +   ++   +
truncate  |  +   +
position at start | +   ++   +
position at end   |   +   +

--
https://mail.python.org/mailman/listinfo/python-list


Re: How to make Python run as fast (or faster) than Julia

2018-02-22 Thread ast

Le 22/02/2018 à 13:03, bartc a écrit :

On 22/02/2018 10:59, Steven D'Aprano wrote:
https://www.ibm.com/developerworks/community/blogs/jfp/entry/Python_Meets_Julia_Micro_Performance?lang=en 



While an interesting article on speed-up techniques, that seems to miss 
the point of benchmarks.


On the fib(20) test, it suggests using this to get a 30,000 times speed-up:

     from functools import lru_cache as cache

     @cache(maxsize=None)
     def fib_cache(n):
     if n<2:
     return n
     return fib_cache(n-1)+fib_cache(n-2)



It's a meaningless to test the execution time of a function
with a cache decorator on 1.000.000 loops

The first execution, ok, you get something meaningfull
but for the other 999.999 executions, the result is already on
the cache so you just measure the time to read the result
in a dictionnary and output it.

On my computer:

>>> setup = """\
from functools import lru_cache as cache
@cache(maxsize=None)
def fib(n):
if n < 2: return n
return fib(n-1) + fib(n-2)
"""
>>> from timeit import timeit

>>> timeit("fib(20)", setup=setup, number=1)
0.00010329007704967808

>>> timeit("fib(20)", setup=setup, number=100)
0.0001489834564836201

so 100 loops or 1 loop provides similar results
as expected !





--
https://mail.python.org/mailman/listinfo/python-list


Re: How to make Python run as fast (or faster) than Julia

2018-02-22 Thread ast

Le 22/02/2018 à 19:53, Chris Angelico a écrit :

On Fri, Feb 23, 2018 at 2:15 AM, ast  wrote:

Le 22/02/2018 à 13:03, bartc a écrit :


On 22/02/2018 10:59, Steven D'Aprano wrote:







for count in 1, 10, 100, 1000:
 print(count, timeit("cache(maxsize=None)(fib)(20)", setup=setup,
number=count))



 hum ... very astute


--
https://mail.python.org/mailman/listinfo/python-list


Re: list() strange behaviour

2021-01-22 Thread ast

Le 20/12/2020 à 21:00, danilob a écrit :




b = ((x[0] for x in a))



There is a useless pair of parenthesis

b = (x[0] for x in a)

b is a GENERATOR expression

first list(b) calls next method on b repetedly until b is empty.
So it provides the "content" of b

second list(b) provides nothing since b is empty
(there is no reset on generators)




--
https://mail.python.org/mailman/listinfo/python-list


Subtle difference between any(a list) and any(a generator) with Python 3.9

2021-07-29 Thread ast

Hello

Reading PEP572 about Python 3.9 assignment expressions,
I discovered a subtle difference between any(a list)
and any(a generator)

see:

>>> lines = ["azerty", "#qsdfgh", "wxcvbn"]
>>> any((comment := line).startswith('#') for line in lines)
True
>>> comment
"#qsdfgh"

>>> any([(comment := line).startswith('#') for line in lines])
True
>>> comment
'wxcvbn'

The two code snippets which seems very similar provide a
different value for "comment".

When "any" deals with a generator, it stops as soon it finds
a True value and returns True.

When "any" deals with a list, the whole list is calculated
first, and then "any" looks for a True.

Before 3.9 and the walrus operator, the two ways always provide
the same result, in a faster way with a generator.

With 3.9 and the walrus operator, result can be different








--
https://mail.python.org/mailman/listinfo/python-list


Re: Ask for help on using re

2021-08-05 Thread ast

Le 05/08/2021 à 11:40, Jach Feng a écrit :

I want to distinguish between numbers with/without a dot attached:


text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'
re.compile(r'ch \d{1,}[.]').findall(text)

['ch 1.', 'ch 23.']

re.compile(r'ch \d{1,}[^.]').findall(text)

['ch 23', 'ch 4 ', 'ch 56 ']

I can guess why the 'ch 23' appears in the second list. But how to get rid of 
it?

--Jach



>>> import re

>>> text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'

>>> re.findall(r'ch \d+\.', text)
['ch 1.', 'ch 23.']

>>> re.findall(r'ch \d+(?!\.)', text)   # (?!\.) for negated look ahead
['ch 2', 'ch 4', 'ch 56']
--
https://mail.python.org/mailman/listinfo/python-list


Re: Ask for help on using re

2021-08-05 Thread ast

Le 05/08/2021 à 17:11, ast a écrit :

Le 05/08/2021 à 11:40, Jach Feng a écrit :

I want to distinguish between numbers with/without a dot attached:


text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'
re.compile(r'ch \d{1,}[.]').findall(text)

['ch 1.', 'ch 23.']

re.compile(r'ch \d{1,}[^.]').findall(text)

['ch 23', 'ch 4 ', 'ch 56 ']

I can guess why the 'ch 23' appears in the second list. But how to get 
rid of it?


--Jach



 >>> import re

 >>> text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'

 >>> re.findall(r'ch \d+\.', text)
['ch 1.', 'ch 23.']

 >>> re.findall(r'ch \d+(?!\.)', text)   # (?!\.) for negated look ahead
['ch 2', 'ch 4', 'ch 56']


import regex

# regex is more powerful that re

>>> text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'

>>> regex.findall(r'ch \d++(?!\.)', text)

['ch 4', 'ch 56']

## ++ means "possessive", no backtrack is allowed




--
https://mail.python.org/mailman/listinfo/python-list


Re: Ask for help on using re

2021-08-05 Thread ast

Le 05/08/2021 à 17:11, ast a écrit :

Le 05/08/2021 à 11:40, Jach Feng a écrit :

I want to distinguish between numbers with/without a dot attached:


text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'
re.compile(r'ch \d{1,}[.]').findall(text)

['ch 1.', 'ch 23.']

re.compile(r'ch \d{1,}[^.]').findall(text)

['ch 23', 'ch 4 ', 'ch 56 ']

I can guess why the 'ch 23' appears in the second list. But how to get 
rid of it?


--Jach



 >>> import re

 >>> text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'

 >>> re.findall(r'ch \d+\.', text)
['ch 1.', 'ch 23.']

 >>> re.findall(r'ch \d+(?!\.)', text)   # (?!\.) for negated look ahead
['ch 2', 'ch 4', 'ch 56']


ops ch2 is found. Wrong
--
https://mail.python.org/mailman/listinfo/python-list


Re: Ask for help on using re

2021-08-06 Thread ast

Le 06/08/2021 à 02:57, Jach Feng a écrit :

ast 在 2021年8月5日 星期四下午11:29:15 [UTC+8] 的信中寫道:

Le 05/08/2021 à 17:11, ast a écrit :

Le 05/08/2021 à 11:40, Jach Feng a écrit :



import regex

# regex is more powerful that re

text = 'ch 1. is\nch 23. is\nch 4 is\nch 56 is\n'
regex.findall(r'ch \d++(?!\.)', text)


['ch 4', 'ch 56']

## ++ means "possessive", no backtrack is allowed



Can someone explain how the difference appear? I just can't figure it out:-(



+, *, ? are greedy, means they try to catch as many characters
as possible. But if the whole match doesn't work, they release
some characters once at a time and try the whole match again.
That's backtrack.
With ++, backtrack is not allowed. This works with module regex
and it is not implemented in module re

with string = "ch 23." and pattern = r"ch \d+\."

At first trial \d+  catch 23
but whole match will fail because next character is . and . is not 
allowed (\.)


A backtrack happens:

\d+  catch only 2
and the whole match is successful because the next char 3 is not .
But this is not what we want.

with ++, no backtrack, so no match
"ch 23." is rejected
this is what we wanted


Using re only, the best way is probably

re.findall(r"ch \d+(?![.0-9])", text)
['ch 4', 'ch 56']
--
https://mail.python.org/mailman/listinfo/python-list


Inheriting from str

2021-09-20 Thread ast

Hello

class NewStr(str):
def __init__(self, s):
self.l = len(s)

Normaly str is an immutable type so it can't be modified
after creation with __new__

But the previous code is working well

obj = NewStr("qwerty")
obj.l
6

I don't understand why it's working ?


(python 3.9)
--
https://mail.python.org/mailman/listinfo/python-list


Recursion on list

2021-11-04 Thread ast

> li = []
> li.append(li)
> li
[[...]]

>li[0][0][0][0]
[[...]]

That's funny
--
https://mail.python.org/mailman/listinfo/python-list


Syntax not understood

2021-11-04 Thread ast

Hello

In this function

def get4(srcpages):
scale = 0.5
srcpages = PageMerge() + srcpages
x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:])
for i, page in enumerate(srcpages):
page.scale(scale)
page.x = x_increment if i & 1 else 0
page.y = 0 if i & 2 else y_increment
return srcpages.render()

found here

https://www.blog.pythonlibrary.org/2018/06/06/creating-and-manipulating-pdfs-with-pdfrw/

I do not understand this line:

x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:])

(scale * i for i in srcpages.xobj_box[2:]) is a generator, a single
object, it should not be possible to unpack it into 2 variables.

x, y = 1 generates an error
x, y = (i for i in range(10)) too

but not

x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:])

why ?
--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax not understood

2021-11-04 Thread ast

Le 04/11/2021 à 16:41, Stefan Ram a écrit :

ast  writes:

(scale * i for i in srcpages.xobj_box[2:]) is a generator, a single
object, it should not be possible to unpack it into 2 variables.


   But the value of the right-hand side /always/ is a single object!

   A syntax of an assignment statement that has been simplified
   by me but is sufficient for this post is:

target list = source expression

   . The evaluation of the source expression yields an object.

   If the target list is not a single target, that object must
   be an iterable with the same number of items as there are targets
   in the target list, and the items are assigned, from left to
   right, to the corresponding targets.

   A generator object /is/ an iterable, and, here, it apparently
   yields exactly two items.




understood

It is like:

x, y = (i for i in range(2))

thx
--
https://mail.python.org/mailman/listinfo/python-list


One line sort

2021-11-15 Thread ast

A curiosity:

q = lambda x: x and q([i for i in x[1:] if i < x[0]]) + [x[0]] + q([i 
for i in x[1:] if i >= x[0]])


>>> q([7, 5, 9, 0])
[0, 5, 7, 9]
--
https://mail.python.org/mailman/listinfo/python-list


Symbolic links on Windows

2021-11-17 Thread ast

Hello,

It seems that symbolic links on Windows are not
well reconized by modules os or pathlib.

I have a file named json.txt on my destop. With a
drag and drop right click on it I create a link
automatically named: json.txt - Raccourci.lnk

Then:

>>> from pathlib import Path

>>> p2 = Path('C:/Users/jm/desktop/json.txt - Raccourci.lnk')

>>> p2
WindowsPath('C:/Users/jm/desktop/json.txt - Raccourci.lnk')

>>> p2.exists()
True

>>> p2.is_file()
True

>>> p2.is_symlink()
False

With this last command I was expecting True and for
p2_is_file() I was expecting False



With os, it's the same

import os

>>> os.path.exists(p2)
True

>>> os.path.isfile(p2)
True

os.path.islink(p2)
False


What's wrong plz ?
--
https://mail.python.org/mailman/listinfo/python-list


Re: Symbolic links on Windows

2021-11-17 Thread ast

Le 17/11/2021 à 13:10, Python a écrit :

ast wrote:

Hello,

It seems that symbolic links on Windows are not
well reconized by modules os or pathlib.

I have a file named json.txt on my destop. With a
drag and drop right click on it I create a link
automatically named: json.txt - Raccourci.lnk


This is not a symbolic link.

Symbolic links were introduced in Windows Vista/Windows
Server 2008. A .lnk file is just a regular file containing
the path of the target (you can open it and read it if you
wish) that is interpreted in a specific way by the graphical
Shell and some other applications.




Yes you are right

On Windows symbolic links are created in a cmd tool:
e.g

mklink json2.txt json.txt

And it is something different than shortcut files (suffix .lnk)
--
https://mail.python.org/mailman/listinfo/python-list


Re: Unexpected behaviour of math.floor, round and int functions (rounding)

2021-11-19 Thread ast

Le 19/11/2021 à 03:51, MRAB a écrit :

On 2021-11-19 02:40, [email protected] wrote:

On 2021-11-18 at 23:16:32 -0300,
René Silva Valdés  wrote:


Hello, I would like to report the following issue:

Working with floats i noticed that:

int(23.99/12) returns 1, and
int(23.999/12) returns 2

This implies that int() function is rounding ...


It's not int() that's doing the rounding; that second numerator is being
rounded before being divided by 12:

 Python 3.9.7 (default, Oct 10 2021, 15:13:22)
 [GCC 11.1.0] on linux
 Type "help", "copyright", "credits" or "license" for more 
information.

 >>> 23.999
 24.0
 >>> (23.999).hex()
 '0x1.8p+4'

I think this is a bit clearer because it shows that it's not just being 
rounded for display:


Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 
64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.
 >>> 23.99 == 24
False
 >>> 23.999 == 24
True


>>> 0.3 + 0.3 + 0.3 == 0.9
False
--
https://mail.python.org/mailman/listinfo/python-list


Re: Unexpected behaviour of math.floor, round and int functions (rounding)

2021-11-19 Thread ast

Le 19/11/2021 à 12:43, ast a écrit :

Le 19/11/2021 à 03:51, MRAB a écrit :

On 2021-11-19 02:40, [email protected] wrote:

On 2021-11-18 at 23:16:32 -0300,
René Silva Valdés  wrote:


Hello, I would like to report the following issue:

Working with floats i noticed that:

int(23.99/12) returns 1, and
int(23.999/12) returns 2

This implies that int() function is rounding ...


It's not int() that's doing the rounding; that second numerator is being
rounded before being divided by 12:

 Python 3.9.7 (default, Oct 10 2021, 15:13:22)
 [GCC 11.1.0] on linux
 Type "help", "copyright", "credits" or "license" for more 
information.

 >>> 23.999
 24.0
 >>> (23.999).hex()
 '0x1.8p+4'

I think this is a bit clearer because it shows that it's not just 
being rounded for display:


Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC 
v.1929 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.
 >>> 23.99 == 24
False
 >>> 23.999 == 24
True


 >>> 0.3 + 0.3 + 0.3 == 0.9
False


Better use math.isclose to test equality between 2 floats

>>> import math
>>> math.isclose(0.3 + 0.3 + 0.3, 0.9)
True
--
https://mail.python.org/mailman/listinfo/python-list


copy.copy

2021-11-22 Thread ast

Hi,

>>> a = 6
>>> b = 6
>>> a is b
True

ok, we all know that Python creates a sole instance
with small integers, but:

>>> import copy
>>> b = copy.copy(a)
>>> a is b
True

I was expecting False
--
https://mail.python.org/mailman/listinfo/python-list


Re: copy.copy

2021-11-22 Thread ast

Le 22/11/2021 à 16:02, Jon Ribbens a écrit :

On 2021-11-22, ast  wrote:




For immutable types, copy(foo) just returns foo.



ok, thx
--
https://mail.python.org/mailman/listinfo/python-list


Re: Unexpected behaviour of math.floor, round and int functions (rounding)

2021-11-23 Thread ast

Le 19/11/2021 à 21:17, Chris Angelico a écrit :

On Sat, Nov 20, 2021 at 5:08 AM ast  wrote:


Le 19/11/2021 à 03:51, MRAB a écrit :

On 2021-11-19 02:40, [email protected] wrote:

On 2021-11-18 at 23:16:32 -0300,
René Silva Valdés  wrote:





  >>> 0.3 + 0.3 + 0.3 == 0.9
False


That's because 0.3 is not 3/10. It's not because floats are
"unreliable" or "inaccurate". It's because the ones you're entering
are not what you think they are.

When will people understand this?

(Probably never. Sigh.)

ChrisA



I posted that to make people aware of danger of float comparison,
not because I was not understanding what happened.

We can see there is a difference on the lsb, due to rounding.

>>> (0.3+0.3+0.3).hex()
'0x1.cp-1'
>>> 0.9.hex()
'0x1.dp-1'
>>>

An isclose() function is provided in module math to do float
comparison safely.

>>> math.isclose(0.3+0.3+0.3, 0.9)
True
--
https://mail.python.org/mailman/listinfo/python-list


A problem with itertools.groupby

2021-12-17 Thread ast

Python 3.9.9

Hello

I have some troubles with groupby from itertools

from itertools import groupby

for k, grp in groupby("aahfffddnnb"):
print(k, list(grp))
print(k, list(grp))

a ['a', 'a']
a []
h ['h']
h []
f ['f', 'f', 'f']
f []
d ['d', 'd']
d []
s ['s', 's', 's', 's']
s []
n ['n', 'n']
n []
b ['b']
b []

It works as expected.
itertools._grouper objects are probably iterators
so they provide their datas only once. OK

but:

li = [grp for k, grp in groupby("aahfffddnnb")]
list(li[0])

[]

list(li[1])

[]

It seems empty ... I don't understand why, this is
the first read of an iterator, it should provide its
data.

This one works:

["".join(grp) for k, grp in groupby("aahfffddnnb")]

['aa', 'h', 'fff', 'dd', '', 'nn', 'b']

regards
--
https://mail.python.org/mailman/listinfo/python-list


Re: A strange list concatenation result

2016-08-14 Thread ast


"Mok-Kong Shen"  a écrit dans le message de 
news:[email protected]...

Am 13.08.2016 um 03:08 schrieb Steven D'Aprano:

On Sat, 13 Aug 2016 06:44 am, Mok-Kong Shen wrote:


list2 = [1,2,3]
list1 += [4,5,6]
print(list1, list2)

[1, 2, 3, 4, 5, 6] [1, 2, 3]


Does that help?


I don't yet understand why in my 2nd example list2 came out as
[1, 2, 3] outside.


Because you assign list2 = [1, 2, 3]. What did you expect it to be?


But in my function test() there is a code line "list2=list2+[4,5,6]".
Could you kindly explain why this didn't work?

M. K. Shen



Hello

list1 += [4, 5, 6 ] is slightly different than list1 = list1 + [4, 5, 6]

see:


list1 = [1, 2, 3]
id(list1)

45889616
list1 += [4, 5, 6 ]

id(list1)

45889616   # < -same address

list1

[1, 2, 3, 4, 5, 6]

so list1 += [4, 5, 6 ]  updates the existing list


list1 = [1, 2, 3]
id(list1)

45888656

list1 = list1 + [4, 5, 6]
id(list1)

45862424 # <- a new address

list1

[1, 2, 3, 4, 5, 6]

so list1 = list1 + [4, 5, 6] create a new list 


--
https://mail.python.org/mailman/listinfo/python-list


integer's methods

2016-08-18 Thread ast

Hello

I wonder why calling a method on an integer
doesn't work ?


123.bit_length()

SyntaxError: invalid syntax


123.to_bytes(3, 'big')

SyntaxError: invalid syntax

but it works with a variable


i = 123
i.bit_length()

7


i=123
i.to_bytes(3, 'big')

b'\x00\x00{'

I am working with pyhton 3.5.1

thx
--
https://mail.python.org/mailman/listinfo/python-list


Re: integer's methods

2016-08-18 Thread ast


"Marko Rauhamaa"  a écrit dans le message de 
news:[email protected]...

"ast" :


123.bit_length()

SyntaxError: invalid syntax


I fell into that trap myself.

CPython's lexical analyzer can't handle a dot after an integer literal
so you must add a space in between "123" and ".".


Marko


Indeed.

Maybe because of a confusion with the decimal point.

Thx 


--
https://mail.python.org/mailman/listinfo/python-list


Variables visibility for methods

2016-08-31 Thread ast

Hello

I made few experiments about variables visibility
for methods.

class MyClass:
   a = 1
   def test(self):
   print(a)

obj = MyClass()
obj.test()

Traceback (most recent call last):
 File "", line 1, in 
   obj.test()
 File "", line 4, in test
   print(a)
NameError: name 'a' is not defined

=== RESTART: Shell ==

a = 1

class MyClass:
   def test(self):
   print(a)

obj = MyClass()
obj.test()
1

So it seems that when an object's méthod is executed, variables
in the scope outside the object's class can be read (2nd example),
but not variables inside the class (1st example).

For 1st example, I know that print(MyClass.a) or print(self.a)
would have work.

Any comments are welcome. 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Variables visibility for methods

2016-08-31 Thread ast


"dieter"  a écrit dans le message de 
news:[email protected]...

"ast"  writes:




You are right. And it is documented this way.



Thank you 


--
https://mail.python.org/mailman/listinfo/python-list


Where to store finalized python programs

2016-09-09 Thread ast

hi

Is there a web site to store python programs
in order to make them accessible for every boby ?

I know pypy, but I understood that it is for modules
only.
--
https://mail.python.org/mailman/listinfo/python-list


Why searching in a set is much faster than in a list ?

2016-09-27 Thread ast

Hello

I noticed that searching in a set is faster than searching in a list.

from timeit import Timer
from random import randint

l = [i for i in range(100)]
s = set(l)

t1 = Timer("randint(0, 200) in l", "from __main__ import l, randint")
t2 = Timer("randint(0, 200) in s", "from __main__ import s, randint")

t1.repeat(3, 10)
[1.459111982109448, 1.4568229341997494, 1.4329947660946232]

t2.repeat(3, 10)
[0.8499233841172327, 0.854728743457656, 0.8618653348400471]

I tried a search in a tuple, it's not different that in a list.
Any comments ?
--
https://mail.python.org/mailman/listinfo/python-list


Re: Why searching in a set is much faster than in a list ?

2016-09-27 Thread ast


"ast"  a écrit dans le message de 
news:[email protected]...

Hello

I noticed that searching in a set is faster than searching in a list.

from timeit import Timer
from random import randint

l = [i for i in range(100)]
s = set(l)

t1 = Timer("randint(0, 200) in l", "from __main__ import l, randint")
t2 = Timer("randint(0, 200) in s", "from __main__ import s, randint")

t1.repeat(3, 10)
[1.459111982109448, 1.4568229341997494, 1.4329947660946232]

t2.repeat(3, 10)
[0.8499233841172327, 0.854728743457656, 0.8618653348400471]

I tried a search in a tuple, it's not different that in a list.
Any comments ?


I tried in an array which is supposed to be an optimised list, but it is 
slightly
slower

from array import array

a = array('H', [i for i in range(100)])
t3 = Timer("randint(0, 200) in a", "from __main__ import a, randint")

t3.repeat(3, 10)
[1.636356968114, 1.638082912772461, 1.6018925589704622] 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a way to change the closure of a python function?

2016-09-28 Thread ast


"jmp"  a écrit dans le message de 
news:[email protected]...

On 09/27/2016 04:01 PM, Peng Yu wrote:




Note: function are objects, and can have attributes, however I rarely see usage of these, there 
could be good reasons for that.




It could be use to implement a cache for example.

def fact1(n):

   if not hasattr(fact1, '_cache'):
   fact1._cache = {0:1}

   if n not in fact1._cache:
   fact1._cache[n] = n * fact1(n-1)

   return fact1._cache[n] 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Why searching in a set is much faster than in a list ?

2016-09-28 Thread ast


"Steven D'Aprano"  a écrit dans le message de 
news:[email protected]...

On Wednesday 28 September 2016 15:51, ast wrote:


Hello

I noticed that searching in a set is faster than searching in a list.

[...]

I tried a search in a tuple, it's not different that in a list.
Any comments ?



A list, array or tuple is basically a linear array that needs to be searched
one item at a time:

[ a | b | c | d | ... | x | y | z ]

To find x, Python has to start at the beginning and look at every item in turn,
until it finds x.

But a set is basically a hash table. It is an array, but laid out differently,
with blank cells:

[ # | # | h | p | a | # | m | y | b | # | # | f | x | ... | # ]

Notice that the items are jumbled up in arbitrary order. So how does Python
find them?

Python calls hash() on the value, which returns a number, and that points
directly to the cell which would contain the value if it were there. So if you
search for x, Python calls hash(x) which will return (say) 12. Python then
looks in cell 12, and if x is there, it returns True, and if it's not, it
returns False. So instead of looking at 24 cells in the array to find x, it
calculates a hash (which is usually fast), then looks at 1 cell.

(This is a little bit of a simplification -- the reality is a bit more
complicated, but you can look up "hash tables" on the web or in computer
science books. They are a standard data structure, so there is plenty of
information available.)

On average, if you have a list with 1000 items, you need to look at 500 items
before finding the one you are looking for. With a set or dict with 1000 items,
on average you need to look at 1 item before finding the one you are looking
for. And that is why sets and dicts are usually faster than lists.



--
Steven
git gets easier once you get the basic idea that branches are homeomorphic
endofunctors mapping submanifolds of a Hilbert space.



Thanks a lot, very interesting. 


--
https://mail.python.org/mailman/listinfo/python-list


static, class and instance methods

2016-10-05 Thread ast

Hello,

In a class there are three possible types of methods,
the static methods, the class methods and the
instance methods

* Class methods are decorated, eg:

@classmethod
def func(cls, a, b):
...

I read that the decorator tranforms 'func' as a descriptor,
and when this descriptor is read, it provided a new
function 'func' where the 1st parameter cls is already filled 
with the class. That's ok for me.



* For instance methods, there is no decorator:

def funct2(self, a, b):
...

self is automatically filled with the instance when we call
funct2 from an instance and not filled if funct2 is called from
a class.
But there is no decorator, why ? Is python doing the conversion
of funct2 to a descriptor itself, behind the scene ?


* static methods are decorated too

@staticmethod
def funct3(a, b):
...

The 1st argument is not supposed to be automatically filled
So what the decorator used for ? 
Just to distinguish funct3 from an instance method ?


regards




--
https://mail.python.org/mailman/listinfo/python-list


Re: static, class and instance methods (Reposting On Python-List Prohibited)

2016-10-06 Thread ast


"Lawrence D’Oliveiro"  a écrit dans le message de 
news:[email protected]...

On Thursday, October 6, 2016 at 7:54:08 PM UTC+13, ast wrote:

But there is no decorator, why ? Is python doing the conversion
of funct2 to a descriptor itself, behind the scene ?


Every function is already a descriptor. So you get the instance-method 
behaviour automatically.


* static methods are decorated too


This is to turn off the instance-method behaviour.



I do not understand your answer.
Consider this function:

def add(a, b):
   return a+b

You say that a function is always stored as
a descriptor object, so when I execute

sum = f(4, 6)

from which class it is supposed to come from ?






--
https://mail.python.org/mailman/listinfo/python-list


Re: static, class and instance methods (Reposting On Python-List Prohibited)

2016-10-06 Thread ast


"Steve D'Aprano"  a écrit dans le message de 
news:[email protected]...

On Thu, 6 Oct 2016 08:03 pm, ast wrote:


Consider this function:

def add(a, b):
return a+b

You say that a function is always stored as
a descriptor object, so when I execute

sum = f(4, 6)

from which class it is supposed to come from ?



It doesn't. The descriptor protocol only gets called by classes, so when you
call a function directly, the special __get__ method isn't used.




yes, it is clear, thanks to all
(I didn't know that functions were descriptors with a __get__ method) 


--
https://mail.python.org/mailman/listinfo/python-list


Re: static, class and instance methods (Reposting On Python-List Prohibited)

2016-10-06 Thread ast


"Gregory Ewing"  a écrit dans le message de 
news:[email protected]...

Lawrence D’Oliveiro wrote:


Every function is already a descriptor.


Which you can see with a simple experiment:

>>> def f(self):
...  print("self =", self)
...


I thought yesterday that every thing was clear. But I have
a doubt now with the following line:


>>> g = f.__get__(17, None)


The signature of  __get__ method is  __get__ (self, inst, owner)  so
once again the first parameter is filled automatically.
Is method __get__ itself a descriptor with an attribute __get__ to perform
the operation ? Hum, it would be endless ...

vars(f.__get__)
TypeError: vars() argument must have __dict__ attribute

no, so how does it work here ?







>>> g

>>> g()
self = 17

--
Greg 


--
https://mail.python.org/mailman/listinfo/python-list


Re: default argument value is mutable

2016-10-07 Thread ast


"Daiyue Weng"  a écrit dans le message de 
news:[email protected]...

Hi, I declare two parameters for a function with default values [],

def one_function(arg, arg1=[], arg2=[]):

PyCharm warns me:

Default argument value is mutable,

what does it mean? and how to fix it?

cheers


You could ignore this warning if you know what you
are doing, imho.
The default value being mutable it is possible to change
it inside the function. eg:

def test(x=[0]):
... print(x)
... x[0] += 1


test()

[0]


test()

[1]




--
https://mail.python.org/mailman/listinfo/python-list


Re: default argument value is mutable

2016-10-07 Thread ast


"jmp"  a écrit dans le message de 
news:[email protected]...

On 10/07/2016 01:38 PM, Daiyue Weng wrote:




So the rule of thumb for default argument value is "No mutable"

Cheers,



It can be used to store some variables from one call of
a function to an other one.

def test( _store={'x':0}):

   x = _store['x']
   . do some stuff
  _store['x'] = x






--
https://mail.python.org/mailman/listinfo/python-list


Re: default argument value is mutable

2016-10-07 Thread ast


"jmp"  a écrit dans le message de 
news:[email protected]...

On 10/07/2016 02:07 PM, ast wrote:


"jmp"  a écrit dans le message de
news:[email protected]...

On 10/07/2016 01:38 PM, Daiyue Weng wrote:




So the rule of thumb for default argument value is "No mutable"

Cheers,



It can be used to store some variables from one call of
a function to an other one.

def test( _store={'x':0}):

x = _store['x']
. do some stuff
   _store['x'] = x


For personal dirty scripts, possibly, for all other situations, never.


not so dirty in my opinion


Especially since there's nothing in the code above that cannot be solved using 
standard idioms .


Yes, putting _store dictionnary outside

_store={'x':0}

def test( ):

   x = _store['x']
   . do some stuff
   _store['x'] = x


or using a global variable, but you pollute in both case
the global scope unnecessary.



That is if you care about anyone reading your code ;)

jm








--
https://mail.python.org/mailman/listinfo/python-list


Re: default argument value is mutable

2016-10-07 Thread ast


"jmp"  a écrit dans le message de 
news:[email protected]...

On 10/07/2016 03:45 PM, ast wrote:


"jmp"  a écrit dans le message de
news:[email protected]...

On 10/07/2016 02:07 PM, ast wrote:


"jmp"  a écrit dans le message de
news:[email protected]...

On 10/07/2016 01:38 PM, Daiyue Weng wrote:




So the rule of thumb for default argument value is "No mutable"

Cheers,



It can be used to store some variables from one call of
a function to an other one.

def test( _store={'x':0}):

x = _store['x']
. do some stuff
   _store['x'] = x


For personal dirty scripts, possibly, for all other situations, never.


not so dirty in my opinion


You made a point, it's not that dirty, it's an "advanced technique" that is often actually an 
error when you don't know what you're doing. See the OP's code.


I'm in an environment where people use python as a tool more than an effective powerful language 
to write complex applications. That's probably why I'm bias on this issue and prefer the cautious 
approach.



Especially since there's nothing in the code above that cannot be
solved using standard idioms .


Yes, putting _store dictionnary outside

_store={'x':0}

def test( ):

x = _store['x']
. do some stuff
_store['x'] = x


or using a global variable, but you pollute in both case
the global scope unnecessary.


What about

def test():
  if not hasattr(test, '_store'): test._store={'x':0}
  test._store['x'] += 1

Neither you pollute the global namespace, nor you pollute the function signature with 
implementation specifics.


jm



OK

There is this solution too we often see:


def test(x):
 x = some stuff
 return(x)

x=0
x = test(x)


--
https://mail.python.org/mailman/listinfo/python-list


Local variables to a function doesn't disapear after function execution. Why ?

2016-10-12 Thread ast

Hello, here is the small program:

from tkinter import *

class Test:
   def __init__(self):
   root = Tk()
   label = Label(root, text="this is a test")
   label.pack()
   root.mainloop()

test=Test()

I dont understand why this program works. After execution
of function __init__, local variables 'root' and 'label' should 
disapear and the widgets Tk and Label should be garbage 
collected. But it's not the case, the window Tk is still on the 
screen with the label inside it. Why ?


Usually, we write:

class Test:
   def __init__(self):
   self.root = Tk()
   self.label = Label(self.root, text="this is a test")
   self.label.pack()
   self.root.mainloop()

test = Test()

to keep some references to Tk() and Label()
--
https://mail.python.org/mailman/listinfo/python-list


Re: Local variables to a function doesn't disapear after function execution. Why ?

2016-10-12 Thread ast


"Christian Gollwitzer"  a écrit dans le message de 
news:[email protected]...

Am 12.10.16 um 13:18 schrieb ast:


Because the Test() call does never terminate. You have the mainloop inside of your constructor. As 
long as this loop runs, your program exists. Try it by putting


test=Test()
print("Now I am here")

and you'll see.

Christian


Ah yes, mainloop() is an endless loop.
Thanks 


--
https://mail.python.org/mailman/listinfo/python-list


__prepare__ metaclass's method

2016-10-28 Thread ast

Hi

On python doc here: 


https://docs.python.org/3.4/reference/datamodel.html

it is said about __prepare__ metaclass's method:

If the metaclass has a __prepare__ attribute, it is called as 
namespace = metaclass.__prepare__(name, bases, **kwds) 
where the additional keyword arguments, if any, come from

the class definition.

I don't understand what they call the "class definition".

So I took their example and add a print(kwds)

class OrderedClass(type):

@classmethod
def __prepare__(metacls, name, bases, **kwds):
   print(kwds)
   return collections.OrderedDict()

def __new__(cls, name, bases, namespace, **kwds):
   result = type.__new__(cls, name, bases, dict(namespace))
   result.members = tuple(namespace)
   return result

class A(metaclass=OrderedClass):
   def one(self): pass
   def two(self): pass
   def three(self): pass
   def four(self): pass

but print(kwds) outputs an empty dictionnary {}

So what kwds is supposed to contains ?

Thx
--
https://mail.python.org/mailman/listinfo/python-list


Re: __prepare__ metaclass's method

2016-10-28 Thread ast


"Peter Otten" <[email protected]> a écrit dans le message de 
news:[email protected]...

ast wrote:



class T(type):

... def __new__(*args, **kw): return type.__new__(*args)
... def __prepare__(*args, **kw):
... print(kw)
... return {}
... def __init__(*args, **kw):
... pass
...

class A(metaclass=T, answer=42):

... pass
...
{'answer': 42}

Adapted from
<http://martyalchin.com/2011/jan/20/class-level-keyword-arguments/>.



Thanks,

Could these class-level keyword arguments be useful for standard classes
(those whose metaclass is type) ?

eg:

class Test(option = True)
   make use of "option" here ?

it seems no

--
https://mail.python.org/mailman/listinfo/python-list


Entering a very large number

2018-03-23 Thread ast

Hi

I found this way to put a large number in
a variable.

C = int(
"28871482380507712126714295971303939919776094592797"
"22700926516024197432303799152733116328983144639225"
"94197780311092934965557841894944174093380561511397"
"4215424169339729054237110027510420801349667317"
"5515285922696291677532547505856101949404200039"
"90443211677661994962953925045269871932907037356403"
"22737012784538991261203092448414947289768854060249"
"76768122077071687938121709811322297802059565867")

It works but is it not optimal since there is a
string to int conversion.

I was not able to put an integer directly because
character '\' for line cut doesnt work inside an
integer

C = \
28871482380507712126714295971303939919776094592797\
22700926516024197432303799152733116328983144639225\
...
76768122077071687938121709811322297802059565867

doesn't work

Do you have a better idea ?

Thx


--
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-23 Thread ast

Le 23/03/2018 à 13:43, Rustom Mody a écrit :

On Friday, March 23, 2018 at 5:46:56 PM UTC+5:30, ast wrote:

Hi

I found this way to put a large number in
a variable.


What stops you from entering the number on one single (v long) line?



It is not beautiful and not very readable. It is better to
have a fixed number of digits per line (eg 50)

import this

Beautiful is better than ugly.
Readability counts.




In case there is a religious commitment to PEP 8 dicta, the recommended
meditation is this line (also from PEP8):

"However, know when to be inconsistent -- sometimes style guide recommendations just 
aren't applicable"



Yes I am using pylint which flags too long lines (80 characters)
--
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-23 Thread ast

Le 23/03/2018 à 13:30, Wolfgang Maier a écrit :

On 03/23/2018 01:16 PM, ast wrote:




A very simple improvement would be to use a single
triple-quoted string. Assuming you are copy/pasting
the number from somewhere that will save a lot of your
time.


no, it seems that sone \n are inserted inside the number

>>> C = int("""
1234
5678""")

Traceback (most recent call last):
  File "", line 3, in 
5678""")
ValueError: invalid literal for int() with base 10: '\n1234\n5678'


--
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-23 Thread ast

Le 23/03/2018 à 13:55, Wolfgang Maier a écrit :

On 03/23/2018 01:30 PM, Wolfgang Maier wrote:

On 03/23/2018 01:16 PM, ast wrote:




n = int(
     ''.join("""
37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629

...


45876576172410976447339110607218265236877223636045
17423706905851860660448207621209813287860733969412
""".split())
)



yes, good idea

--
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-23 Thread ast

Le 23/03/2018 à 14:16, Antoon Pardon a écrit :

On 23-03-18 14:01, ast wrote:

Le 23/03/2018 à 13:43, Rustom Mody a écrit :

On Friday, March 23, 2018 at 5:46:56 PM UTC+5:30, ast wrote:




What meaningful information from number can you easily retrieve from
representing the number in some kind of table form that you can't from
just writing the number on one line?



digit n° 103 is 1
digit n° 150 is 7
...

--
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-25 Thread ast

Le 25/03/2018 à 03:47, Steven D'Aprano a écrit :

On Sun, 25 Mar 2018 00:05:56 +0100, Peter J. Holzer wrote:






The Original Poster (OP) is concerned about saving, what, a tenth of a
microsecond in total? Hardly seems worth the effort, especially if you're
going to end up with something even slower.




I regret that many answers are malicious, as your.

The question was how to enter a large number without
going through a string, no matter why.
This question is absolutely legitimate, contrary to
some people think.
It seems that it is not feasible unless writting it in
a single line, which is awful.
OK, go on with the string, and Wolfgang solution using
triple quote is good.





--
https://mail.python.org/mailman/listinfo/python-list


round

2018-06-07 Thread ast

Hi

round is supposed to provide an integer when
called without any precision argument.

here is the doc:

>>> help(round)

round(number[, ndigits]) -> number

Round a number to a given precision in decimal digits (default 0 digits).
This returns an int when called with one argument, otherwise the
same type as the number

but in some circumstances it provides a float

import numpy as np

M = np.array([[0, 9],[2, 7]], dtype=int)
np.linalg.det(M)
-18.004
round(np.linalg.det(M))
-18.0 # i was expecting an integer -18, not a float

# same problem with np.round
np.round(np.linalg.det(M))
-18.0
--
https://mail.python.org/mailman/listinfo/python-list


Speed of animation with matplotlib.animation

2018-06-19 Thread ast

Hello

I noticed that the speed of animations made
with module matplotlib.animation always seems
wrong.

Here is a small example for demonstration purpose:


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
ax = fig.add_subplot(111)
txt = ax.text(0.5, 0.5, "", transform=ax.transAxes)

dt = 0.1  # 100 ms

def animate(i):
txt.set_text("time= %.1f" % (i*dt))
return txt,


ani = animation.FuncAnimation(fig=fig,
  func=animate,
  frames = 200,
  interval = dt,
  blit = True,
  repeat=False)

plt.show()

--
so function animate is ran every interval=dt=100ms
with i=0, 1, 2, ..., 200 and it simply prints time
(i*dt) on the figure.

The animation should last 20s, but on my computer
it is twice faster

A link to FuncAnimation doc: https://bit.ly/2t5UKjA

interval : number, optional

Delay between frames in milliseconds. Defaults to 200.


What's wrong ?
--
https://mail.python.org/mailman/listinfo/python-list


Re: Speed of animation with matplotlib.animation

2018-06-19 Thread ast

Le 19/06/2018 à 10:57, Peter Otten a écrit :

ast wrote:


I noticed that the speed of animations made
with module matplotlib.animation always seems
wrong.



dt = 0.1  # 100 ms
  

interval : number, optional

  Delay between frames in milliseconds. Defaults to 200.


What's wrong ?



From the above I would conclude that you get a 100 ms delay with


dt = 100




So the animation should last 200*0.1 = 20s
but it is twice faster
--
https://mail.python.org/mailman/listinfo/python-list


Re: Speed of animation with matplotlib.animation

2018-06-19 Thread ast

Le 19/06/2018 à 11:47, Peter Otten a écrit :

ast wrote:


Le 19/06/2018 à 10:57, Peter Otten a écrit :

ast wrote:






No, with dt = 100 it should last

200 * 100ms = 20.000ms = 20s

with dt = 0.1 it should last

200 * 0.1ms = 20ms = 0.02s

but your computer is probably not fast enough for that.




You are right. I didn't noticed that interval was in ms
Ty
--
https://mail.python.org/mailman/listinfo/python-list


Permutations using a recursive generator

2018-09-18 Thread ast

Hello

I found a smart and very concise code to
generate all permutations of a list.
I put it here if someone is interested to
figure out how it works


def permut(li, prefix=[]):

if len(li)==1:
yield prefix + li
else:
for elt in li:
li2 = li.copy()
li2.remove(elt)
yield from S(li2, prefix+[elt])


exemple of usage

>>> list(permut(['a', 'b', 'c']))
[['a', 'b', 'c'], ['a', 'c', 'b'], ['b', 'a', 'c'], ['b', 'c', 'a'], 
['c', 'a', 'b'], ['c', 'b', 'a']]


>>> list(permut([0,1,2,3]))
[[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], 
[0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3], [1, 2, 3, 0], 
[1, 3, 0, 2], [1, 3, 2, 0], [2, 0, 1, 3], [2, 0, 3, 1], [2, 1, 0, 3], 
[2, 1, 3, 0], [2, 3, 0, 1], [2, 3, 1, 0], [3, 0, 1, 2], [3, 0, 2, 1], 
[3, 1, 0, 2], [3, 1, 2, 0], [3, 2, 0, 1], [3, 2, 1, 0]]

--
https://mail.python.org/mailman/listinfo/python-list


Re: Permutations using a recursive generator

2018-09-18 Thread ast

Le 18/09/2018 à 17:01, ast a écrit :

error: permut instead of S


     yield from permut(li2, prefix+[elt])

--
https://mail.python.org/mailman/listinfo/python-list


Re: Adding borders to ttk radiobuttons

2016-03-30 Thread ast


"Mark Lawrence"  a écrit dans le message de 
news:[email protected]...

I believe something like this should suffice to display borders around the 
radiobuttons.

import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
style = ttk.Style()
style.configure('BW.TRadiobutton', borderwidth=5)
buttonVar = tk.IntVar()
rb1 = ttk.Radiobutton(text='Hello mum', variable=buttonVar, value=1)
rb1.configure(style='BW.TRadiobutton')
rb1.grid(row=0, column=0)
rb2 = ttk.Radiobutton(text='Hello dad', variable=buttonVar, value=2)
rb2.configure(style='BW.TRadiobutton')
rb2.grid(row=1, column=0)
root.mainloop()

Sadly no borders :(  What have I missed?  Python 3.5.1 on Windows 10.



it seems there is no border on the radio button


style.layout('BW.TRadiobutton')


[('Radiobutton.padding', {'children': [('Radiobutton.indicator', {'side': 'left', 'sticky': ''}), 
('Radiobutton.focus', {'side': 'left', 'sticky': '', 'children': [('Radiobutton.label', {'sticky': 
'nswe'})]})], 'sticky': 'nswe'})] 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Adding borders to ttk radiobuttons

2016-03-30 Thread ast


"ast"  a écrit dans le message de 
news:[email protected]...


"Mark Lawrence"  a écrit dans le message de 
news:[email protected]...

I believe something like this should suffice to display borders around the 
radiobuttons.

import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
style = ttk.Style()
style.configure('BW.TRadiobutton', borderwidth=5)
buttonVar = tk.IntVar()
rb1 = ttk.Radiobutton(text='Hello mum', variable=buttonVar, value=1)
rb1.configure(style='BW.TRadiobutton')
rb1.grid(row=0, column=0)
rb2 = ttk.Radiobutton(text='Hello dad', variable=buttonVar, value=2)
rb2.configure(style='BW.TRadiobutton')
rb2.grid(row=1, column=0)
root.mainloop()

Sadly no borders :(  What have I missed?  Python 3.5.1 on Windows 10.



it seems there is no border on the radio button


style.layout('BW.TRadiobutton')


[('Radiobutton.padding', {'children': [('Radiobutton.indicator', {'side': 'left', 'sticky': ''}), 
('Radiobutton.focus', {'side': 'left', 'sticky': '', 'children': [('Radiobutton.label', {'sticky': 
'nswe'})]})], 'sticky': 'nswe'})]


for more help:
http://www.tkdocs.com/tutorial/styles.html 


--
https://mail.python.org/mailman/listinfo/python-list


module alias in import statement

2016-04-04 Thread ast

hello


import tkinter as tk
import tk.ttk as ttk


Traceback (most recent call last):
 File "", line 1, in 
   import tk.ttk as ttk
ImportError: No module named 'tk'


of course


import tkinter.ttk as ttk


works

Strange, isn't it ?
--
https://mail.python.org/mailman/listinfo/python-list


Label behavior's difference between tkinter and ttk

2016-04-05 Thread ast

Hello

I currently migrate a GUI from tkinter to ttk and I found a problem

Here is a piece of code, with comments which explain what is 
wrong.


import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()

BITMAP0 = """
#define zero_width 24
#define zero_height 32
static char zero_bits[] = {
0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x3c,0x0f, 0xf0,0x3c,0x0f,
0xf0,0x3c,0x0f, 0xf0,0x3c,0x0f, 0x00,0x00,0x00, 0x00,0x00,0x00,
0xf0,0x00,0x0f, 0xf0,0x00,0x0f, 0xf0,0x00,0x0f, 0xf0,0x00,0x0f,
0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x00,0x0f, 0xf0,0x00,0x0f,
0xf0,0x00,0x0f, 0xf0,0x00,0x0f, 0x00,0x00,0x00, 0x00,0x00,0x00,
0xf0,0x00,0x0f, 0xf0,0x00,0x0f, 0xf0,0x00,0x0f, 0xf0,0x00,0x0f,
0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x3c,0x0f, 0xf0,0x3c,0x0f,
0xf0,0x3c,0x0f, 0xf0,0x3c,0x0f, 0x00,0x00,0x00, 0x00,0x00,0x00
};
"""

img = tk.BitmapImage(data=BITMAP0, foreground='white', background='black')

# This Label comes from ttk

label = ttk.Label(root, image=img)

# This Label comes from tk. To be uncommented to test behavior'difference
# label = tk.Label(root, image=img)

label.pack()

# The graphic is not refreshed after entering following commands
# when Label comes from ttk. You have to fly over the label with 
# the mouse to get the right color.

# The graphic is immediately updated when Label comes from tk

# Enter these commands by hand, in a shell

img.config(foreground='red')
img.config(foreground='lime')
img.config(foreground='yellow')


It looks like a ttk bug, isn't it ?
I am using python 3.5.1

I tried a root.update_idletasks() to refresh the graphic
but it changed nothings.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Label behavior's difference between tkinter and ttk

2016-04-05 Thread ast


"Kevin Walzer"  a écrit dans le message de 
news:[email protected]...
In general, the "img.config" syntax is suitable for the classic Tk widgets, not the themed ttk 
widgets. They have a very different (and very gnarly) syntax for indicating changed state. I am 
not inclined to see a bug here.


--
Kevin Walzer
Code by Kevin/Mobile Code by Kevin
http://www.codebykevin.com
http://www.wtmobilesoftware.com


BitmapImage comes from tkinter. It doesn't rxist
in ttk 


--
https://mail.python.org/mailman/listinfo/python-list


Checking function's parameters (type, value) or not ?

2016-04-06 Thread ast

Hello

I would like to know if it is advised or not to test
a function's parameters before running it, e.g
for functions stored on a public library ?

Example:

def to_base(nber, base=16, use_af=True, sep=''):

   assert isinstance(nber, int) and nber >= 0
   assert isinstance(base, int) and base >= 2
   assert isinstance(use_af, bool)
   assert isinstance(sep, str) and len(sep) == 1

  tbc

With these tests, you are sure that the function to_base is
well used. But it slows down the program.
Without, python interpreter may crash later in the function
or worse provide a meaningless result.

What library designers do ?
   


--
https://mail.python.org/mailman/listinfo/python-list


Re: Checking function's parameters (type, value) or not ?

2016-04-06 Thread ast


"Mark Lawrence"  a écrit dans le message de 
news:[email protected]...

On 06/04/2016 14:07, ast wrote:




Please see 
http://ftp.dev411.com/t/python/python-list/13bhcknhan/when-to-use-assert




Thanks for this paper

Running Python with the -O or -OO optimization flags
removes the assert. This has to be known. 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Checking function's parameters (type, value) or not ?

2016-04-06 Thread ast


"Chris Angelico"  a écrit dans le message de 
news:[email protected]...

On Thu, Apr 7, 2016 at 12:18 AM, ast  wrote:

"Mark Lawrence"  a écrit dans le message de
news:[email protected]...


On 06/04/2016 14:07, ast wrote:






Running Python with the -O or -OO optimization flags
removes the assert. This has to be known.


Exactly. So your two options are not "remove the assertions" and "keep
the assertions"; they are "remove the assertions" and "replace the
assertions with explicit exception raising". My recommendation is
still on simply removing them, but if you are to keep the checks,
they'll look something like this:

def to_base(nber, base=16, use_af=True, sep=''):
   """docstring goes here (don't forget that)"""
   nber = int(nber)
   if nber < 0: raise ValueError("Negative numbers not supported")
   base = int(base)
   if base < 2: raise ValueError("base must be at least 2")
   use_af = bool(use_af)
   sep = str(sep)


These are either conversions or assertions, depending on your point of
view. Actually, it would be better for these to have some kind of
"ensure that this is X" call; you could replace int(x) with
operator.index(x), but there's no equivalent for str - any object can
be converted to a string. You could perhaps do that one with
isinstance. (IMO bool is fine as it is.)

But I would just leave out this code altogether. Less code means less
chance of bugs creeping in; you might change the code elsewhere to
require, for instance, that base not exceed 36, and then you'd have to
come and change this code too. Without the checks, you'd only make
that change in one place.

ChrisA


thanks for these informations 


--
https://mail.python.org/mailman/listinfo/python-list


Re: Serious error in int() function?

2016-04-13 Thread ast


 a écrit dans le message de 
news:[email protected]...

Hi,

there may be a serious error in python's int() function:

print int(float(2.8/0.1))

yields

27

instead of 28!!

I am using Python Python 2.7.6, GCC 4.8.2 on Linux Ubuntu.

Is that known?
Best,
Martin



I have a similar question, so I post my message here.
Hope this will not annoy the OP


Is it sure that the square root of a square number is always
an integer ?

I would not like to get a result as 345.

from math import sqrt


sqrt(16)

4.0

sqrt(16).is_integer()

True


for n in range(100):

... if not sqrt(n**2).is_integer():
... print(sqrt(n**2))

it seems to work ... but does it work for all integers ?



--
https://mail.python.org/mailman/listinfo/python-list


Why float('Nan') == float('Nan') is False

2019-02-13 Thread ast

Hello

>>> float('Nan') == float('Nan')
False

Why ?

Regards

--
https://mail.python.org/mailman/listinfo/python-list


Re: Why float('Nan') == float('Nan') is False

2019-02-13 Thread ast

Le 13/02/2019 à 14:21, ast a écrit :

Hello

 >>> float('Nan') == float('Nan')
False

Why ?

Regards



Thank you for answers.

If you wonder how I was trapped with it, here
is the failing program.


r = float('Nan')

while r==float('Nan'):
inp = input("Enter a number\n")
try:
r = float(inp)
except ValueError:
r = float('Nan')
--
https://mail.python.org/mailman/listinfo/python-list


sys.modules

2019-02-21 Thread ast

Hello

Is it normal to have 151 entries in dictionary sys.modules
just after starting IDLE or something goes wrong ?

>>> import sys
>>> len(sys.modules)
151

Most of common modules seems to be already there,
os, itertools, random 

I thought that sys.modules was containing loaded modules
with import command only.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Dictionary

2019-02-25 Thread ast

Le 24/02/2019 à 05:21, Himanshu Yadav a écrit :

fibs={0:0,1:1}
def rfib(n):
   global fibs
if not fibs.get(n):
 fibs[n]=rfib(n-2)+rfib(n-1)
 return fibs[n]

Why it is gives error??



Nothing to do with the malfunction, but you dont need
to define fibs as global since you dont remap "fibs"
in side the function.

As explained by Peter, when n equals 0, not fibs.get(n)
will return True and recursivity goes on with n=-1, -2
until you reach the maximum allowed number of recursion
depth
--
https://mail.python.org/mailman/listinfo/python-list


Quirk difference between classes and functions

2019-02-25 Thread ast

Hello

I noticed a quirk difference between classes and functions

>>> x=0
>>>
>>> class Test:
x = x+1
print(x)
x = x+1
print(x)

1
2
>>> print(x)
0

Previous code doesn't generate any errors.
x at the right of = in first "x = x+1" line is
the global one (x=0), then x becomes local

within a function, this is not allowed

>>> x = 0
>>>
>>> def f():
x = x+1

>>> f()
UnboundLocalError: local variable 'x' referenced before assignment

Since x is written inside the function, it is considered as a local
variable and x in x+1 is undefined so this throw an exception

Any comment ?
--
https://mail.python.org/mailman/listinfo/python-list


dash/underscore on name of package uploaded on pypi

2019-02-28 Thread ast

Hello

I just uploaded a package on pypi, whose name is "arith_lib"

The strange thing is that on pypi the package is renamed "arith-lib"
The underscore is substitued with a dash

If we search for this package:

pip search arith

arith-lib (2.0.0) - A set of functions for miscellaneous arithmetic
(so a dash)

For installation both:

pip install -U arith_lib
pip install -U arith-lib

are working well

and in both case I got a directory with an underscore

C:\Program Files\Python36-32\Lib\site-packages

28/02/2019  16:57  arith_lib
28/02/2019  16:57  arith_lib-2.0.0.dist-info

What happens ?
--
https://mail.python.org/mailman/listinfo/python-list


File not closed

2019-03-20 Thread ast

Hello

In the following snippet, a file is opened but
without any variable referring to it.
So the file can't be closed.

[line.split(":")[0]
 for line in open('/etc/passwd')
 if line.strip() and not line.startswith("#")]

What do you think about this practice ?



--
https://mail.python.org/mailman/listinfo/python-list


How python knows where non standard libraries are stored ?

2019-09-07 Thread ast

Hello

List sys.path contains all paths where python shall
look for libraries.

Eg on my system, here is the content of sys.path:

>>> import sys
>>> sys.path
['',
'C:\\Users\\jean-marc\\Desktop\\python',
'C:\\Program Files\\Python36-32\\python36.zip',
'C:\\Program Files\\Python36-32\\DLLs',
'C:\\Program Files\\Python36-32\\lib',
'C:\\Program Files\\Python36-32',
'C:\\Program Files\\Python36-32\\lib\\site-packages']

The last path is used as a location to store libraries
you install yourself.

If I am using a virtual environment (with venv) this last
path is different

'C:\\Users\\jean-marc\\Desktop\\myenv\\lib\\site-packages'

I looked for windows environment variables to tell python
how to fill sys.path at startup but I didn't found.

So how does it work ?
--
https://mail.python.org/mailman/listinfo/python-list


UserList from module collections

2019-09-10 Thread ast

Hello

I read in a course that class UserList from module
collections can be used to create our own custom list

Example

>>> from collections import UserList
>>> class MyList(UserList):
... def head(self):
... return self.data[0]
... def queue(self):
... return self.data[1:]
...
>>> l = MyList([1, 2, 3])
>>> l.append(4)
>>> l
[1, 2, 3, 4]
>>> l.head()
1
>>> l.queue()
[2, 3, 4]


But I can do exactly the same without UserList


>>> class MyList(list):
def head(self):
return self[0]
def queue(self):
return self[1:]

>>> l = MyList([1, 2, 3])
>>>  l.append(4)
>>> l
[1, 2, 3, 4]
>>> l.head()
1
>>> l.queue()
[2, 3, 4]


So what UserList is used for ?
--
https://mail.python.org/mailman/listinfo/python-list


Re: Get Count of function arguments passed in

2019-09-11 Thread ast

Le 11/09/2019 à 12:11, Sayth Renshaw a écrit :

Hi

I want to allow as many lists as needed to be passed into a function.
But how can I determine how many lists have been passed in?

I expected this to return 3 but it only returned 1.

matrix1 = [[1, -2], [-3, 4],]
matrix2 = [[2, -1], [0, -1]]
matrix3 = [[2, -1], [0, -1]]
# print(add(matrix1, matrix2))

def add(*matrix):
 print(len(locals()))

add(matrix1,matrix2,matrix3)

Cheers

Sayth



It returns 1 because there is only 1 local variable
inside function add. It's a list matrix which contains
the 3 matrix

If you want the number of arguments passed, then
just call: len(matrix)

def add(*matrix):
print(len(matrix))



--
https://mail.python.org/mailman/listinfo/python-list


Re: itertools product(infinite iterator) hangs

2019-09-13 Thread ast

Le 14/09/2019 à 04:26, Oscar Benjamin a écrit :

I've been staring at this for a little while:

from itertools import product

class Naturals:
 def __iter__(self):
 i = 1
 while True:
 yield i
 i += 1

N = Naturals()
print(iter(N))
print(product(N))  # <--- hangs

When I run the above the call to product hangs but I can't see why. I
would expect that since I'm not iterating over the product it would
just call iter(N) but clearly not since iter(N) returns a generator
instantly where as product(N) hangs.

What am I missing?

Oscar



here is a pseudo code for product:

def product(*args, repeat=1):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)


clearly "tuple(pool)" hangs with an infinite iterable pool


--
https://mail.python.org/mailman/listinfo/python-list


Re: what's the differences: None and null?

2019-09-15 Thread ast

Le 14/09/2019 à 03:40, Random832 a écrit :

On Fri, Sep 13, 2019, at 21:22, Hongyi Zhao wrote:

what's the differences: None and null?


null isn't really a concept that exists in Python... while None fills many of 
the same roles that null does in some other languages, it is a proper object, 
with __str__ and __repr__ methods (that return 'None'), __hash__ (that returns 
an arbitrary value), etc.




I add that None is a singleton. There is only one None object.
So testing if a variable is None is done with identity check:

if var is None:
pass
--
https://mail.python.org/mailman/listinfo/python-list


Strange Class definition

2019-09-16 Thread ast

Hello

Following syntax doesn't generate any errors:

>>> foo=0
>>> Class Foo:
   foo

But class Foo seems empty

Is it equivalent to ?

>>> class Foo:
pass



--
https://mail.python.org/mailman/listinfo/python-list


Exception

2019-09-24 Thread ast

Hi

It is not clear to me why the following code
generates 2 exceptions, ZeroDivisionError and
ArithmeticError. Since ZeroDivisionError is
catched, it shoud not bubble out.

Found here:
https://www.pythonsheets.com/notes/python-new-py3.html

>>> def func():
... try:
... 1 / 0
... except ZeroDivisionError:
... raise ArithmeticError
...
>>> func()
Traceback (most recent call last):
  File "", line 3, in func
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "", line 1, in 
  File "", line 5, in func
ArithmeticError


There is a work around (python >= 3.3)

>>> def func():
... try:
... 1 / 0
... except ZeroDivisionError:
... raise ArithmeticError from None
...
>>> func()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 5, in func
ArithmeticError
--
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   >