Re: Observations on the List - "Be More Kind"

2018-10-09 Thread jfong
Chris Angelico at 2018.10.10 UTC+8 AM 10:31:33 wrote:
> On Wed, Oct 10, 2018 at 1:21 PM  wrote:
> > I switched from comp.lang.python to mailing list a few months ago for those 
> > spam threads there. Now it seems a bad decision because 1) replied mail can 
> > be lost  or duplicated or even banned. 2) look at each separately mail is 
> > not as comfortable as at a single thread. 3) Google group is a more free 
> > land to live.
> >
> > So, have to switch back to comp.lang.python to get ride of all these 
> > problems.
> >
> 
> Well, just be aware that a lot of people block ALL posts that come
> from Google Groups. The signal-to-noise ratio there is sufficiently
> low that it's often just not worth carrying that traffic. So you're
> welcome to switch over to there to get freedom, but you're basically
> getting the Wild West, where spammers run free and the lawless rule...
> and the genteel avoid the place.
> 
> ChrisA

Wild West? haha.. nice metaphor, thanks for reminding. But, in cyberspace, I 
prefer more freedom than more safety:-)

--Jach

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


Re: Observations on the List - "Be More Kind"

2018-10-09 Thread jfong
Richard Damon at 2018.10.9 UTC+8 PM 8:40:29 wrote:
> Moderators are generally appointed by those who do 'pay the bill' for
> the mailing list they are moderators for, and serve at their pleasure.
> Mailing List are generally 'private property', though often made open to
> the public for general use. The owners of that property, generally have
> rights to establish rules for the public to use that property (perhaps
> somewhat constrained by whatever laws are applicable at the physical
> location that the mailing list server, owner or moderator resides at).
> 
> Shoot, as in physically, generally no such right; metaphorically, as in
> sever discipline in list operations, generally yes, though perhaps
> limited from some grounds based on applicable Laws.

Then, I respect their right of doing this if it's a 'private property'.

I switched from comp.lang.python to mailing list a few months ago for those 
spam threads there. Now it seems a bad decision because 1) replied mail can be 
lost  or duplicated or even banned. 2) look at each separately mail is not as 
comfortable as at a single thread. 3) Google group is a more free land to live.

So, have to switch back to comp.lang.python to get ride of all these problems.

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


Re: Observations on the List - "Be More Kind"

2018-10-09 Thread jfong
I am wondering the role of the moderator.

Does he own the server or pay the bill? Where he get the power to suspending 
people? Is he a police or judge? Can he shoot someone just because he has any 
reason?

What will happen if his power was limited? Will the forum be end in disorder? 
No, I don't think so. We are mature enough to keep it running.

--Jach


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


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread jfong
Chris Angelico於 2018年4月12日星期四 UTC+8下午4時05分29秒寫道:
> On Thu, Apr 12, 2018 at 4:20 PM,   wrote:
> > Chris Angelico於 2018年4月12日星期四 UTC+8下午1時31分35秒寫道:
> >> On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
> >> > This C function returns a buffer which I declared it as a 
> >> > ctypes.c_char_p. The buffer has size 0x1 bytes long and the valid 
> >> > data may vary from a few bytes to the whole size.
> >> >
> >> > In every call I know how much the valid data size is, but I suppose I 
> >> > can't use slice to get it because there may be zero byte in it. What to 
> >> > do?
> >> >
> >>
> >> You suppose? Or have you tested it?
> >>
> >> ChrisA
> >
> > Yes, I had test it once before. Now, I re-do it again to make sure. After a 
> > call which returns 3 bytes of data, I use len(buf) to check the length and 
> > get the number 24. I can see the first 24 bytes of data by using buf[:30] 
> > but buf[24] will cause an "index out of range" error. I don't know how to 
> > see what the buf[24] exactly is but I suppose it might be a zero byte.
> >
> 
> If you have 24 bytes, they're numbered 0 through 23. So there is no byte at 
> 24.
> 
> ChrisA

Using a technique you mentioned in subject "how to memory dump an object?" at 
16/5/21, I confirm the length of buf was decided by a \x00 byte:

>>> len(buf)
24
>>> id(buf)
13553888
>>> ptr = ctypes.cast(id(buf), ctypes.POINTER(ctypes.c_ubyte))
>>> buf[:24]
b'\x05ALLOTNPUT_BUFFER_SIZE\x02+'
>>> bytes([ptr[i] for i in range(50)])
b'\x02\x00\x00\x00X\xa1%\x1e\x18\x00\x00\x00\xff\xff\xff\xff\x05ALLOTNPUT_BUFFER_SIZE\x02+\x00\n\x00\x00\x00\x00\x00\x00\xb0\x9b'
>>>

but it won't help on solving my problem. Still need someone's help:-)

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


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread jfong
Chris Angelico於 2018年4月12日星期四 UTC+8下午1時31分35秒寫道:
> On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
> > This C function returns a buffer which I declared it as a ctypes.c_char_p. 
> > The buffer has size 0x1 bytes long and the valid data may vary from a 
> > few bytes to the whole size.
> >
> > In every call I know how much the valid data size is, but I suppose I can't 
> > use slice to get it because there may be zero byte in it. What to do?
> >
> 
> You suppose? Or have you tested it?
> 
> ChrisA

Yes, I had test it once before. Now, I re-do it again to make sure. After a 
call which returns 3 bytes of data, I use len(buf) to check the length and get 
the number 24. I can see the first 24 bytes of data by using buf[:30] but 
buf[24] will cause an "index out of range" error. I don't know how to see what 
the buf[24] exactly is but I suppose it might be a zero byte.

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


How to write partial of a buffer which was returned from a C function to a file?

2018-04-11 Thread jfong
This C function returns a buffer which I declared it as a ctypes.c_char_p. The 
buffer has size 0x1 bytes long and the valid data may vary from a few bytes 
to the whole size.

In every call I know how much the valid data size is, but I suppose I can't use 
slice to get it because there may be zero byte in it. What to do?


Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Is pdb suitable for debugging asyncio module?

2018-04-04 Thread jfong
I have a module below and run it under pdb, the result seems not easy to xplain.
(Note: the sleep periods are in reverse order)
---
# asyncio_as_completed.py

import asyncio

@asyncio.coroutine
def phase(i):
print('in phase {}'.format(i))
yield from asyncio.sleep(0.5 - (0.1 * i))
print('done with phase {}'.format(i))
return 'phase {} result'.format(i)

@asyncio.coroutine
def main(num_phases):
print('starting main')
phases = [
phase(i)
for i in range(num_phases)
]
print('waiting for phases to complete')
results = []
for next_to_complete in asyncio.as_completed(phases):
answer = yield from next_to_complete  # <--set breakpoint here
print('received answer {!r}'.format(answer))
results.append(answer)
print('results: {!r}'.format(results))
return results

event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(3))
finally:
event_loop.close()
---

D:\Works\Python>py -m pdb asyncio_as_completed.py
> d:\works\python\asyncio_as_completed.py(3)()
-> import asyncio
(Pdb) n
> d:\works\python\asyncio_as_completed.py(5)()
-> @asyncio.coroutine
(Pdb) b 22
Breakpoint 1 at d:\works\python\asyncio_as_completed.py:22
(Pdb) c
starting main
waiting for phases to complete
> d:\works\python\asyncio_as_completed.py(22)main()
-> answer = yield from next_to_complete

(Pdb) n
in phase 1
in phase 0
in phase 2
Internal StopIteration# <---
> d:\works\python\asyncio_as_completed.py(8)phase()
-> yield from asyncio.sleep(0.5 - (0.1 * i))
(Pdb) n
> d:\works\python\asyncio_as_completed.py(9)phase()
-> print('done with phase {}'.format(i))
(Pdb) n
done with phase 2
> d:\works\python\asyncio_as_completed.py(10)phase()
-> return 'phase {} result'.format(i)

(Pdb) n
Internal StopIteration: phase 2 result
> d:\works\python\asyncio_as_completed.py(22)main()
-> answer = yield from next_to_complete
(Pdb) n
> d:\works\python\asyncio_as_completed.py(23)main()
-> print('received answer {!r}'.format(answer))
(Pdb) n
received answer 'phase 2 result'# <---
> d:\works\python\asyncio_as_completed.py(24)main()
-> results.append(answer)
(Pdb) n
> d:\works\python\asyncio_as_completed.py(21)main()
-> for next_to_complete in asyncio.as_completed(phases):
(Pdb) n
> d:\works\python\asyncio_as_completed.py(22)main()
-> answer = yield from next_to_complete

(Pdb) n
Internal StopIteration# <---
> d:\works\python\asyncio_as_completed.py(8)phase()
-> yield from asyncio.sleep(0.5 - (0.1 * i))
(Pdb) n
> d:\works\python\asyncio_as_completed.py(9)phase()
-> print('done with phase {}'.format(i))
(Pdb) n
done with phase 1
> d:\works\python\asyncio_as_completed.py(10)phase()
-> return 'phase {} result'.format(i)

(Pdb) n
Internal StopIteration# <---
> d:\works\python\asyncio_as_completed.py(8)phase()
-> yield from asyncio.sleep(0.5 - (0.1 * i))
(Pdb) n
> d:\works\python\asyncio_as_completed.py(9)phase()
-> print('done with phase {}'.format(i))
(Pdb) n
done with phase 0
> d:\works\python\asyncio_as_completed.py(10)phase()
-> return 'phase {} result'.format(i)

(Pdb) n
Internal StopIteration: phase 1 result# <---
> d:\works\python\asyncio_as_completed.py(22)main()
-> answer = yield from next_to_complete
(Pdb) n
> d:\works\python\asyncio_as_completed.py(23)main()
-> print('received answer {!r}'.format(answer))
(Pdb) n
received answer 'phase 1 result'
> d:\works\python\asyncio_as_completed.py(24)main()
-> results.append(answer)
(Pdb) n
> d:\works\python\asyncio_as_completed.py(21)main()
-> for next_to_complete in asyncio.as_completed(phases):
(Pdb) n
> d:\works\python\asyncio_as_completed.py(22)main()
-> answer = yield from next_to_complete

(Pdb) n
> d:\works\python\asyncio_as_completed.py(23)main()
-> print('received answer {!r}'.format(answer))
(Pdb) n
received answer 'phase 0 result'
> d:\works\python\asyncio_as_completed.py(24)main()
-> results.append(answer)
(Pdb) n
> d:\works\python\asyncio_as_completed.py(21)main()
-> for next_to_complete in asyncio.as_completed(phases):

(Pdb) n
> d:\works\python\asyncio_as_completed.py(25)main()
-> print('results: {!r}'.format(results))
(Pdb) n
results: ['phase 2 result', 'phase 1 result', 'phase 0 result']
> d:\works\python\asyncio_as_completed.py(26)main()
-> return results
(Pdb) n
The program finished and will be restarted
> d:\works\python\asyncio_as_completed.py(3)()
-> import asyncio
(Pdb)


I saw three "Internal StopIteration" lines which match the three "phase" tasks, 
it's OK. But there are only two "Internal StopIteration: phase x result" lines, 
the "phase 0" was missed. Why is that?

Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-03 Thread jfong
Ian於 2018年4月3日星期二 UTC+8下午1時38分57秒寫道:
> On Mon, Apr 2, 2018 at 9:01 PM,   wrote:
> 
> def run_forever(self):
> """Run until stop() is called."""
>try:
> events._set_running_loop(self)
> while True:
> self._run_once()
> if self._stopping:
> break
> finally:
> self._stopping = False
> events._set_running_loop(None)
>
What's the purpose of resetting self._stopping back to False in finally clause?

--Jach

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


Re: In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-02 Thread jfong
Ian於 2018年4月2日星期一 UTC+8下午9時37分08秒寫道:
> On Mon, Apr 2, 2018 at 5:32 AM,   wrote:
> > I am new to the asyncio subject, just trying to figure out how to use it. 
> > Below is the script I use for testing:
> > -
> > # asyncio_cancel_task2.py
> >
> > import asyncio
> >
> > @asyncio.coroutine
> > def task_func():
> > print('in task_func, sleeping')
> > try:
> > yield from asyncio.sleep(1)
> > except asyncio.CancelledError:
> > print('task_func was canceled')
> > raise
> > print('return result')
> > return 'the result'
> >
> > def task_canceller(task):
> > task.cancel()
> > print('canceled the task')
> >
> > @asyncio.coroutine
> > def main(loop):
> > print('first, scheduling a task')
> > task = loop.create_task(task_func())
> > print('second, scheduling its cancellation')
> > loop.call_later(0.5, task_canceller, task)
> > try:
> > print('waiting task to complete')
> > yield from task
> > except asyncio.CancelledError:
> > print('main() also sees task as canceled')
> >
> >
> > event_loop = asyncio.get_event_loop()
> > try:
> > event_loop.run_until_complete(main(event_loop))
> > finally:
> > print('wait 3 seconds before closing event_loop')
> > asyncio.sleep(3)
> 
> This won't actually wait 3 seconds. It just instantiates a sleep
> coroutine and then discards it. Inside the event loop you would need
> to await or yield from it. Outside the event loop, in order to sleep
> you have to block the thread, e.g. using time.sleep. That said, there
> is no reason to wait before closing the event loop.
> 
Thank you for reminding my mistake. I shouldn't use asyncio.sleep there.

> > print('event_loop was closed')
> > event_loop.close()
> > ---
> >
> > It schedules two tasks, the task_func and the task_canceller, in main. 
> > Before the task_func completed, the task_canceller was fired to cancel it. 
> > Hence its output below seems reasonable.
> >
> > D:\Works\Python>py
> > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 
> > bit (Intel)] on win32
> > Type "help", "copyright", "credits" or "license" for more information.
>  import asyncio_cancel_task2
> > first, scheduling a task
> > second, scheduling its cancellation
> > waiting task to complete
> > in task_func, sleeping
> > canceled the task
> > task_func was canceled
> > main() also sees task as canceled
> > wait 3 seconds before closing event_loop
> > event_loop was closed
> 
> >
> > Then, I changed the call_later delay from 0.5 to 1.5, expect it to be 
> > called after the task_func completed and before the event loop closed. The 
> > output seems not quite right. Why the task_canceller hasn't been called?
> >
>  import asyncio_cancel_task2
> > first, scheduling a task
> > second, scheduling its cancellation
> > waiting task to complete
> > in task_func, sleeping
> > return result
> > wait 3 seconds before closing event_loop
> > event_loop was closed
> 
> 
> Because, as your thread title suggests, after run_until_complete
> returns, the event loop is not running. How could it? It needs a
> thread to run on, but it doesn't create one, so whenever it returns
> from running it is relinquishing the thread and can't do anything
> unless it gets it back, since that thread is now running outer code.
> If you want to, you can restart the event loop by calling one of the
> run methods again; everything that was previously scheduled and
> everything that was scheduled after it stopped will remain scheduled.
> 
I also do a quick check, with call_later delay keeps at 1.5, to see what the 
event loop status is after run_until_complete returns. Strangely, both 
is_closed and is_running return a False.

try:
event_loop.run_until_complete(main(event_loop))
finally:
print(event_loop.is_closed())  # print(event_loop.is_running())


It's not closed(OK, the event_loop.close hasn't be executed yet) and neither 
it's running(quote your words, "it is relinquishing the thread and can't do 
anything")!

Event loop, coroutine, task, yield from, ...etc, all these words' interaction 
makes asyncio has more mystery than I think:-(

> So, you can't have the event loop running in the background while also
> doing things within the code that started the loop in the same thread.
> If you really want this you can create a second thread to run the
> event loop on. However it is usually better to do that sort of thing
> within a coroutine running in the event loop, since single-threaded
> concurrency is the whole point of asyncio. The code that started the
> event loop will then only be used for cleanup after it terminates.

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


In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-02 Thread jfong
I am new to the asyncio subject, just trying to figure out how to use it. Below 
is the script I use for testing:
-
# asyncio_cancel_task2.py

import asyncio

@asyncio.coroutine
def task_func():
print('in task_func, sleeping')
try:
yield from asyncio.sleep(1)
except asyncio.CancelledError:
print('task_func was canceled')
raise
print('return result')
return 'the result'

def task_canceller(task):
task.cancel()
print('canceled the task')

@asyncio.coroutine
def main(loop):
print('first, scheduling a task')
task = loop.create_task(task_func())
print('second, scheduling its cancellation')
loop.call_later(0.5, task_canceller, task)
try:
print('waiting task to complete')
yield from task
except asyncio.CancelledError:
print('main() also sees task as canceled')


event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(event_loop))
finally:
print('wait 3 seconds before closing event_loop')
asyncio.sleep(3)
print('event_loop was closed')
event_loop.close()
---

It schedules two tasks, the task_func and the task_canceller, in main. Before 
the task_func completed, the task_canceller was fired to cancel it. Hence its 
output below seems reasonable.

D:\Works\Python>py
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio_cancel_task2
first, scheduling a task
second, scheduling its cancellation
waiting task to complete
in task_func, sleeping
canceled the task
task_func was canceled
main() also sees task as canceled
wait 3 seconds before closing event_loop
event_loop was closed
>>>

Then, I changed the call_later delay from 0.5 to 1.5, expect it to be called 
after the task_func completed and before the event loop closed. The output 
seems not quite right. Why the task_canceller hasn't been called?

>>> import asyncio_cancel_task2
first, scheduling a task
second, scheduling its cancellation
waiting task to complete
in task_func, sleeping
return result
wait 3 seconds before closing event_loop
event_loop was closed
>>>

Best Regards,
Jach Fong

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


Re: {:2X} didn't output what I expected

2018-03-19 Thread jfong
Chris Angelico於 2018年3月20日星期二 UTC+8上午8時06分05秒寫道:
> On Tue, Mar 20, 2018 at 10:46 AM,   wrote:
> > D:\Temp>py
> > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 
> > bit (Intel)] on win32
> > Type "help", "copyright", "credits" or "license" for more information.
>  '{:02X}'.format(256)
> > '100'
> 
> > What I expected is '00'. Am I wrong?
> >
> 
> Python avoids losing data. If you really want to enforce that this is
> two characters long, you can either restrict the data first (maybe
> with "% 256"), or trim the resulting string:
> 
> >>> '{:02X}'.format(256)[-2:]
> '00'
> 
> ChrisA

I had overlooked the document there it says "width ... defining the minimum 
field width...'. I was wrong, it's not a demand. Thank you, ChrisA.

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


{:2X} didn't output what I expected

2018-03-19 Thread jfong
D:\Temp>py
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> '{:02X}'.format(256)
'100'
>>>
What I expected is '00'. Am I wrong?

Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2018-02-22 Thread jfong
Lew Pitcher於 2018年2月23日星期五 UTC+8上午9時43分19秒寫道:
> jf...@ms4.hinet.net wrote:
> 
> > ast於 2018年2月22日星期四 UTC+8下午8時33分00秒寫道:
> >> 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   |   +   +
> > 
> > What the "write after seek" means?
> 
> It /should/ mean that programs are permitted to seek to a point in the file, 
> and then write from that point on.
> 
> A write to a read mode ("r") file isn't permitted at all,
> so neither is "write after seek" to a read mode file.
> 
> A write to an append mode ("a" and "a+") file always write to the end of the 
> file, effectively negating any seek.
> 
> HTH
> 
> -- 
> Lew Pitcher
> "In Skills, We Trust"
> PGP public key available upon request

Thank you for explanation.

Mode 'r+', 'a' and 'a+' all can be seek and write, but only 'r+' was marked in 
the table. That's why I was confused. This row seems redundant to me:-)

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


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

2018-02-22 Thread jfong
ast於 2018年2月22日星期四 UTC+8下午8時33分00秒寫道:
> 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   |   +   +

What the "write after seek" means?

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


Re: How to exec a string which has an embedded '\n'? (Posting On Python-List Prohibited)

2017-12-31 Thread jfong
Lawrence D’Oliveiro於 2018年1月1日星期一 UTC+8上午7時56分02秒寫道:
> On Sunday, December 31, 2017 at 11:04:19 PM UTC+13, jf...@ms4.hinet.net wrote:
> >
> > This answer makes me think about '\' more thoughtful:-)
> 
> Python generating HTML containing JavaScript which generates HTML:
> 
> out.write \
>   (
> "\nfunction %(paramname)s_UpdateProjects()\n"
> # /* refreshes the project list to show enabled and/or disabled 
> projects as appropriate. */
> "  {\n"
> "var IncludeEnabled = document.forms[\"%(formname)s\"]."
> "elements[\"%(paramname)s_show_enabled\"].checked\n"
> "var IncludeDisabled = document.forms[\"%(formname)s\"]."
> "elements[\"%(paramname)s_show_disabled\"].checked\n"
> "var TheList = \"\"\n"
> "for (var i = 0; i < %(paramname)s_ProjectList.length; ++i)\n"
> "  {\n"
> "var ThisProject = %(paramname)s_ProjectList[i]\n"
> "if (ThisProject.enabled ? IncludeEnabled : 
> IncludeDisabled)\n"
> "  {\n"
> "TheList += \" " \"\\\"\" + (ThisProject.selected ? \" SELECTED\" : \"\") + 
> \">\" +"
> " ThisProject.name + \"\\n\"\n"
> "  } /*if*/\n"
> "  } /*for*/\n"
> "DocumentElt(\"%(formname)s_%(paramname)s_list\").innerHTML 
> =\n"
> "\" SIZE=\\\"5\\\"\"%(on_selection_changed)s"
> " + \">\\n\" + TheList + \"\\n\"\n"
> "  } /*%(paramname)s_UpdateProjects*/\n"
> %
> {
> "formname" : FormName,
> "paramname" : ParamName,
> "on_selection_changed" : OnSelectionChanged,
> }
>   )

I don't even dare to read through this code:-( 

How to run it?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to exec a string which has an embedded '\n'?

2017-12-31 Thread jfong
Random832於 2017年12月31日星期日 UTC+8下午1時25分50秒寫道:
> On Sat, Dec 30, 2017, at 23:57, jf...@ms4.hinet.net wrote:
> > I have a multiline string, something like '''...\nf.write('\n')\n...'''
> > when pass to exec(), I got
> > SyntaxError: EOL while scanning string literal
> > 
> > How to get rid of it?
> 
> Use \\n for this case, since you want the \n to be interpreted by the exec 
> parser rather than the newline being part of the string.

Thank you, it's very helpful. This answer makes me think about '\' more 
thoughtful:-)

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


How to exec a string which has an embedded '\n'?

2017-12-30 Thread jfong
I have a multiline string, something like '''...\nf.write('\n')\n...'''
when pass to exec(), I got
SyntaxError: EOL while scanning string literal

How to get rid of it?

Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to modify this from Python 2.x to v3.4?

2017-11-12 Thread jfong
Thomas Jollans於 2017年11月12日星期日 UTC+8下午5時17分38秒寫道:
> By all means, port ctypesgen to Python 3 (and publish your port) if you
> want to, 

I am not the right person because I have never use Python2 before:-)

> but you might want to consider whether it's easier to port your
> code from ctypes/ctypesgen to cffi instead.

CFFI seems is a little complex, at least to me. I had read its document but 
didn't get through yet:-(

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


Re: How to modify this from Python 2.x to v3.4?

2017-11-12 Thread jfong
Rick Johnson於 2017年11月12日星期日 UTC+8上午11時07分20秒寫道:
> `print` was changed from a statement to a function, so it's
> just a matter of converting it to a function call. If you
> read the docs for the new print function, it should be
> relatively easy to translate. I don't understand why you're
> having so much trouble.
> 
> 
> https://docs.python.org/3/whatsnew/3.0.html?highlight=print#common-stumbling-blocks

It's a shame I didn't read its doc in v3.4 thoughtfully:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) 

I thought position argument is essential, but it's not in this function:

If no objects are given, print() will just write end.

Thanks for your reminder.

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


Re: How to modify this from Python 2.x to v3.4?

2017-11-11 Thread jfong
Ned Batchelder於 2017年11月11日星期六 UTC+8下午8時49分27秒寫道:
> This looks like fairly advanced code.  It will be difficult to port to 
> Python 3 *without* understanding some of the old history.  There seem to 
> be forks on GitHub, including one with a pull request about Python 3 
> made in the last few days: 
> https://github.com/davidjamesca/ctypesgen/pull/58 .  I'd recommend 
> working with others on this.

Thank you, Ned.

As I remember that I had opened a thread here last year, trying to use "2To3" 
tool to convert the ctypesgen package, but didn't success.
https://groups.google.com/forum/#!topic/comp.lang.python/9G0FJXmtwbA

This time, somehow I find this "ctypesgen-python-3" package and can't wait to 
give it a try, but is disappointed again. I suppose there are many v3.x users 
who like to use ctypesgen to ease the using of ctypes. But obviously, it's not 
an easy work to do, convert 2 to 3:-)

By the way, does anyone know what the following codes does? (in printer.py 
file) and how to convert it to v3.x?

class WrapperPrinter:
def __init__(self,outpath,options,data):
...
...
self.print_header()
print >>self.file

self.print_preamble()
print >>self.file

self.print_loader()
print >>self.file
...
...

--Jach

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


How to modify this from Python 2.x to v3.4?

2017-11-11 Thread jfong
I learned python start from using v3.4 and never has any v2.x experience. There 
is a Pypi project "ctypesgen" I like to use, but it seems is for v2.x. 
(un)Fortunately I found one of its branch on github which announced is for 
Python3, but strangely it still use some v2.x words, for example, print. Its 
last update was at July 2009, maybe at the early age of v3? The one below which 
I can't figure out how to modify. Can someone show me the answer? (I don't want 
to spend time on learning the old history:-)

-
# Available instance types.  This is used when lexers are defined by a class.
# It's a little funky because I want to preserve backwards compatibility
# with Python 2.0 where types.ObjectType is undefined.

try:
   _INSTANCETYPE = (types.InstanceType, types.ObjectType)
except AttributeError:
   _INSTANCETYPE = types.InstanceType
   class object: pass   # Note: needed if no new-style classes present
...
...
...
if module:
# User supplied a module object.
if isinstance(module, types.ModuleType):
ldict = module.__dict__
elif isinstance(module, _INSTANCETYPE):
_items = [(k,getattr(module,k)) for k in dir(module)]
...
...
---

Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to debug an unfired tkinter event?

2017-10-21 Thread jfong
Terry Reedy at 2017-10-20 UTC+8 AM 7:37:59 wrote:
> On 10/19/2017 5:07 AM, jf...@ms4.hinet.net wrote:
> 
> > I got some info below each time when I squeeze the table:
> > .
> > .5006
> > .5006.50712528
> > .5006.50712496
> > .5006.50712464
> > .5006.50712144
> > .5006.50712528.50712560.50782256
> > .5006.50712528.50712560.50782256.50783024
> > .5006.50712528.50712560.50782256
> > .5006.50712528.50712560.50782256.50783024
> > 
> > How to change these number(is it a widget ID?) to a meaning name?
> 
> The number strings as names are the defaults that came from tkinter, not 
> tcl/tk.  In 3.6, the default names were changed to be versions of the 
> class name.
> 
>  >>> import tkinter as tk
>  >>> r = tk.Tk()
>  >>> b = tk.Button(r)
>  >>> b
> 
>  >>> b2 = tk.Button(r)
>  >>> b2
> 
> 
I have a question about this change. When there are multiple buttons in the 
same widget hierarchy level and a ".xxx.yyy.!button2" showing up, how to figure 
out which button it means?

By the way, where is the document of this change? Now it doesn't fit the 
description in the "tkinter 8.5 reference manual" anymore.

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


Re: How to debug an unfired tkinter event?

2017-10-19 Thread jfong
Terry Reedy於 2017年10月20日星期五 UTC+8上午7時37分59秒寫道:
> On 10/19/2017 5:07 AM, jf...@ms4.hinet.net wrote:
> 
> > I got some info below each time when I squeeze the table:
> > .
> > .5006
> > .5006.50712528
> > .5006.50712496
> > .5006.50712464
> > .5006.50712144
> > .5006.50712528.50712560.50782256
> > .5006.50712528.50712560.50782256.50783024
> > .5006.50712528.50712560.50782256
> > .5006.50712528.50712560.50782256.50783024
> > 
> > How to change these number(is it a widget ID?) to a meaning name?
> 
> The number strings as names are the defaults that came from tkinter, not 
> tcl/tk.  In 3.6, the default names were changed to be versions of the 
> class name.
> 
>  >>> import tkinter as tk
>  >>> r = tk.Tk()
>  >>> b = tk.Button(r)
>  >>> b
> 
>  >>> b2 = tk.Button(r)
>  >>> b2
> 
> 
> -- 
> Terry Jan Reedy

It's very nice to have this improvment.

What it will be to the previous number output format, say, .5006.50712528? 
Will it become something like this:



then, that's really great:-)

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


Re: How to debug an unfired tkinter event?

2017-10-19 Thread jfong
Peter Otten於 2017年10月20日星期五 UTC+8上午4時37分10秒寫道:
> jf...@ms4.hinet.net wrote:
> 
> > Peter Otten於 2017年10月19日星期四 UTC+8下午6時04分39秒寫道:
> >> jf...@ms4.hinet.net wrote:
> >> 
> >> > Peter Otten at 2017-10-19 UTC+8 PM 3:24:30 wrote:
> >> >> It's not clear to me what you mean with this. Did you place the table
> >> >> from the recipe elsewhere inside a window that you created or did you
> >> >> make changes in the recipe's code?
> >> > 
> >> > Thank you, Peter. I am using Python 3.4.4 under WinXP.
> >> > 
> >> > When running the file directly from download, I get a table scrolling
> >> > vertically only. If its Table class's __init__ parameter
> >> > "scroll_horizontally" changed to True, it can be scrolled horizontally
> >> > also. But there is a problem when scrolled horizontally, the header
> >> > field will not align with data field anymore. I make some modifications
> >> > to make it does. So far so good.
> >> > 
> >> > Later, I want to make the table also has a vertical header. The first
> >> > step I had taken was to move all 2nd top-level widgets(not much, just
> >> > four) to right one column further to make room for this new widget. I
> >> > though it's a simple work, just increase their grid column value by 1.
> >> > But Murphy's Law comes, the xscrollbar even don't show up when the
> >> > table was squeezed horizontally.
> >> 
> >> Thank you for the clarification; I understand your problem much better
> >> now.
> >> 
> >> > 
> >> >> > The canvas has a binding:
> >> >> > self.canvas.bind('', self._on_canvas_configure)
> >> >> > 
> >> >> > After this movement, the callback was only triggered when dragging
> >> >> > the root widget to resize canvas vertically, but not horizontally.
> >> >> > 
> >> >> > Event seems has OS involved(it's MS Windows XP in my case). How to
> >> >> > debug this kind of problem, under pdb?
> >> >> 
> >> >> I don't know, but if you can post a small example script that
> >> >> demonstrates the problem, and you are lucky, someone will see the
> >> >> problem.
> >> > 
> >> > This is a ~5xx lines file and I think it's not fare to ask forum
> >> > members to look through it. So I decide to ask for help on how to debug
> >> > it, instead of the solution.
> >> > 
> >> > I try to change the binding to
> >> >  self.bind_all('', self._on_canvas_configure)
> >> > and add a line into the callback
> >> >  print(event.widget)
> >> > 
> >> > I got some info below each time when I squeeze the table:
> >> > .
> >> > .5006
> >> > .5006.50712528
> >> > .5006.50712496
> >> > .5006.50712464
> >> > .5006.50712144
> >> > .5006.50712528.50712560.50782256
> >> > .5006.50712528.50712560.50782256.50783024
> >> > .5006.50712528.50712560.50782256
> >> > .5006.50712528.50712560.50782256.50783024
> >> > 
> >> > How to change these number(is it a widget ID?) to a meaning name?
> >> 
> >> That's the name of the widget in the underlying tcl/tk. You can specify
> >> it in Python:
> >> 
> >> >>> import tkinter as tk
> >> >>> print(tk.Button())
> >> .139817813335904
> >> >>> print(tk.Button(name="mybutton"))
> >> .mybutton
> >> 
> >> You have to ensure that names are unique.
> > 
> > Thank you. It's very helpful information.
> > 
> > By the way, I just found this problem can be easily seen by not modifing
> > the original file too much with the following steps:
> > 
> > 1. copy and get the file from the link.
> > 2. change the "scroll_horizontally" parameter in the "Table" class's
> > __init__ method to "True"
> > 
> > Running it you will see it perform correctly.
> > 
> > 3. Change the "column=x" at line 268, 282, 288, 292, 303 to "column=x+1"
> > 
> > Now it has the problem.
> 
> There may be other less obvious places that are affected by your 
> modifications. Does changing
> 
> self.grid_columnconfigure(0, weight=1)
> 
> to
> 
> self.grid_columnconfigure(1, weight=1)
> 
> in Table.__init__() help?

There is description about those numbers in the "tkinter 8.5 reference manual" 
section 5.11 Window names. It can be read by w.winfo_name().

After I give every widget a name(using the same Python instance name), the 
utput looks better. Below is the output of the failed one when squeezed 
horizontally:

.table
.table.scrolling_area
.table.yscrollbar
.table.xscrollbar
.table.canvasH
.table.scrolling_area.canvas.innerframe
.table.scrolling_area.canvas.innerframe._body
.table.scrolling_area.canvas.innerframe
.table.scrolling_area.canvas.innerframe._body

Compared to the output of a good one:

.table
.table.scrolling_area
.table.yscrollbar
.table.xscrollbar
.table.canvasH
.table.scrolling_area.canvas

It shows, when the size changed, the failed one fires onto the wrong 
widgets(the innerframe and innerframe._body), not the canvas. The canvas widget 
didn't absorb the space changing!!

That's prove your intuition is correct. The problem is at the column's weight 
setting. After does the changes according to your suggestion, the problem is 
solved. La la!

Thank yo

Re: How to debug an unfired tkinter event?

2017-10-19 Thread jfong
Peter Otten於 2017年10月19日星期四 UTC+8下午6時04分39秒寫道:
> jf...@ms4.hinet.net wrote:
> 
> > Peter Otten at 2017-10-19 UTC+8 PM 3:24:30 wrote:
> >> It's not clear to me what you mean with this. Did you place the table
> >> from the recipe elsewhere inside a window that you created or did you
> >> make changes in the recipe's code?
> > 
> > Thank you, Peter. I am using Python 3.4.4 under WinXP.
> > 
> > When running the file directly from download, I get a table scrolling
> > vertically only. If its Table class's __init__ parameter
> > "scroll_horizontally" changed to True, it can be scrolled horizontally
> > also. But there is a problem when scrolled horizontally, the header field
> > will not align with data field anymore. I make some modifications to make
> > it does. So far so good.
> > 
> > Later, I want to make the table also has a vertical header. The first step
> > I had taken was to move all 2nd top-level widgets(not much, just four) to
> > right one column further to make room for this new widget. I though it's a
> > simple work, just increase their grid column value by 1. But Murphy's Law
> > comes, the xscrollbar even don't show up when the table was squeezed
> > horizontally.
> 
> Thank you for the clarification; I understand your problem much better now.
> 
> > 
> >> > The canvas has a binding:
> >> > self.canvas.bind('', self._on_canvas_configure)
> >> > 
> >> > After this movement, the callback was only triggered when dragging the
> >> > root widget to resize canvas vertically, but not horizontally.
> >> > 
> >> > Event seems has OS involved(it's MS Windows XP in my case). How to
> >> > debug this kind of problem, under pdb?
> >> 
> >> I don't know, but if you can post a small example script that
> >> demonstrates the problem, and you are lucky, someone will see the
> >> problem.
> > 
> > This is a ~5xx lines file and I think it's not fare to ask forum members
> > to look through it. So I decide to ask for help on how to debug it,
> > instead of the solution.
> > 
> > I try to change the binding to
> >  self.bind_all('', self._on_canvas_configure)
> > and add a line into the callback
> >  print(event.widget)
> > 
> > I got some info below each time when I squeeze the table:
> > .
> > .5006
> > .5006.50712528
> > .5006.50712496
> > .5006.50712464
> > .5006.50712144
> > .5006.50712528.50712560.50782256
> > .5006.50712528.50712560.50782256.50783024
> > .5006.50712528.50712560.50782256
> > .5006.50712528.50712560.50782256.50783024
> > 
> > How to change these number(is it a widget ID?) to a meaning name?
> 
> That's the name of the widget in the underlying tcl/tk. You can specify it 
> in Python:
> 
> >>> import tkinter as tk
> >>> print(tk.Button())
> .139817813335904
> >>> print(tk.Button(name="mybutton"))
> .mybutton
> 
> You have to ensure that names are unique.

Thank you. It's very helpful information.

By the way, I just found this problem can be easily seen by not modifing the 
original file too much with the following steps:

1. copy and get the file from the link.
2. change the "scroll_horizontally" parameter in the "Table" class's __init__ 
method to "True"

Running it you will see it perform correctly.

3. Change the "column=x" at line 268, 282, 288, 292, 303 to "column=x+1"

Now it has the problem.

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


Re: How to debug an unfired tkinter event?

2017-10-19 Thread jfong
Peter Otten at 2017-10-19 UTC+8 PM 3:24:30 wrote:
> It's not clear to me what you mean with this. Did you place the table from 
> the recipe elsewhere inside a window that you created or did you make 
> changes in the recipe's code?

Thank you, Peter. I am using Python 3.4.4 under WinXP. 

When running the file directly from download, I get a table scrolling 
vertically only. If its Table class's __init__ parameter "scroll_horizontally" 
changed to True, it can be scrolled horizontally also. But there is a problem 
when scrolled horizontally, the header field will not align with data field 
anymore. I make some modifications to make it does. So far so good.

Later, I want to make the table also has a vertical header. The first step I 
had taken was to move all 2nd top-level widgets(not much, just four) to right 
one column further to make room for this new widget. I though it's a simple 
work, just increase their grid column value by 1. But Murphy's Law comes, the 
xscrollbar even don't show up when the table was squeezed horizontally.

> > The canvas has a binding:
> > self.canvas.bind('', self._on_canvas_configure)
> > 
> > After this movement, the callback was only triggered when dragging the
> > root widget to resize canvas vertically, but not horizontally.
> > 
> > Event seems has OS involved(it's MS Windows XP in my case). How to debug
> > this kind of problem, under pdb?
> 
> I don't know, but if you can post a small example script that demonstrates 
> the problem, and you are lucky, someone will see the problem.

This is a ~5xx lines file and I think it's not fare to ask forum members to 
look through it. So I decide to ask for help on how to debug it, instead of the 
solution.

I try to change the binding to
 self.bind_all('', self._on_canvas_configure)
and add a line into the callback
 print(event.widget)

I got some info below each time when I squeeze the table:
.
.5006
.5006.50712528
.5006.50712496
.5006.50712464
.5006.50712144
.5006.50712528.50712560.50782256
.5006.50712528.50712560.50782256.50783024
.5006.50712528.50712560.50782256
.5006.50712528.50712560.50782256.50783024

How to change these number(is it a widget ID?) to a meaning name?

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


How to debug an unfired tkinter event?

2017-10-18 Thread jfong
In last few days, I tried to experiment with the scrolling table implemented in 
canvas, started from this example: 
http://code.activestate.com/recipes/580793-tkinter-table-with-scrollbars/. 
Everything works fine until I moved the scrolling_area instance (which the 
canvas is in) from column=0 to column=1.

The canvas has a binding:
self.canvas.bind('', self._on_canvas_configure)

After this movement, the callback was only triggered when dragging the root 
widget to resize canvas vertically, but not horizontally.

Event seems has OS involved(it's MS Windows XP in my case). How to debug this 
kind of problem, under pdb?

Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Ask for help about a tkinter problem

2017-08-20 Thread jfong
Peter Otten at 2017/8/20 UTC+8 PM 5:52:24 wrote:
> jf...@ms4.hinet.net wrote:
> 
> > I am running a tkinter tutor downloaded from web,
> > https://github.com/daleathan/widget-tour-py3. there are two files
> > involved:
> > 
> > 
> > #file button.py
> > 
> > from tkinter import *
> > from tkinter.ttk import *
> > import infrastructure
> > ...
> > class ButtonsDemoWindow( infrastructure.DemoWindow ):
> > ...
> > def __init__( self ):
> > ...
> > ...
> > for c in ('Peach Puff', 'Light Blue', 'Sea Green', 'Yellow' ):
> > b = Button(self.frame, text=c)
> > b['command'] = infrastructure.callit( self.callback, c )
> > b.pack( side=TOP, expand=YES, pady=2 )
> > 
> > def callback(self, color):
> > self.frame['background']=color
> > 
> > def runDemo():
> > ButtonsDemoWindow()
> > 
> > --
> > #file infrastructure.py
> > ...
> > class DemoWindow( Toplevel ):
> > ...
> > ...
> > class callit:
> > def __init__(self, function, *args ):
> > self.f = function
> > self.args = args
> > 
> > def __call__(self, *ignored):
> > self.f( *self.args)
> > 
> > 
> > I run it under the DOS box:
> > 
> > D:\Works\Python\widget-tour-py3-master>python
> > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600
> > 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or
> > "license" for more information.
> > >>> import button
> > >>> button.runDemo()
> > 
> > after the window shows up, I pressed one of the buttons and get the error
> > below:
> > 
>  Exception in Tkinter callback
> > Traceback (most recent call last):
> >   File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__
> > return self.func(*args)
> >   File "D:\Works\Python\widget-tour-py3-master\infrastructure.py", line
> >   216, in __call__
> > self.f( *self.args)
> >   File "D:\Works\Python\widget-tour-py3-master\button.py", line 39, in
> >   callback
> > self.frame['background']=color
> >   File "C:\Python34\lib\tkinter\__init__.py", line 1331, in __setitem__
> > self.configure({key: value})
> >   File "C:\Python34\lib\tkinter\__init__.py", line 1324, in configure
> > return self._configure('configure', cnf, kw)
> >   File "C:\Python34\lib\tkinter\__init__.py", line 1315, in _configure
> > self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
> > _tkinter.TclError: unknown option "-background"
> > 
> > 
> > When I looked into the file tkinter\__init__.py, I found there is codes
> > which add conditionally a '-' onto the original cnf argument:
> 
> That is just a peculiarity of TCL; a "-" is added to the option by the 
> Python wrapper before passing it along
>  
> > 1305  def _configure(self, cmd, cnf, kw):
> > 1306  """Internal function."""
> > ...
> > ...
> > 1313  if isinstance(cnf, str):
> > 1314  return self._getconfigure1(_flatten((self._w, cmd,
> > '-'+cnf)))
> > 
> > Is it the reason this exception raised? Why is that?
> 
> I can confirm the problem. It looks like the bug was introduced when the 
> example was converted from stock tkinter to the new ttk widget set.
> 
> While
> 
> frame["background"] = color
> 
> works when frame is a tkinter.Frame widget the newer tkinter.ttk.Frame 
> widget uses "styles" to configure its appearance. 
> 
> I have not used that new feature, but with the help of
> 
> http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-style-layer.html
> 
> and some trial and error I modified the example to use a style:
> 
> $ diff -u button.py button_fixed.py 
> --- button.py   2017-08-20 11:44:33.841839812 +0200
> +++ button_fixed.py 2017-08-20 11:44:04.032426163 +0200
> @@ -25,7 +25,9 @@
>  
>  infrastructure.DemoWindow.__init__(self, intro, 'button.py' )
>  
> -self.frame=Frame(self)
> +self.style = Style(self)
> +self.frame=Frame(self, style="foo.TFrame")
> +
>  self.frame.pack(expand=YES, fill=BOTH )
>  for c in ('Peach Puff', 'Light Blue',
>'Sea Green', 'Yellow' ):
> @@ -36,7 +38,7 @@
>  
>  
>  def callback(self, color):
> -self.frame['background']=color
> +self.style.configure("foo.TFrame", background=color)
>  
>  
>  def runDemo():
> $ 
> 
> However, I'm not sure if this is the canonical way to write it...

Thank you for your answer. I try not to use the ttk by comment the line "from 
tkinter.ttk import *", and also try your "Style" modification codes, both 
work:-)

> That is just a peculiarity of TCL; a "-" is added to the option by the
> Python wrapper before passing it along

This extra "-" confuses people when showing up in the Traceback info. Can't 
figure out why the author want to do this.

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


Ask for help about a tkinter problem

2017-08-20 Thread jfong
I am running a tkinter tutor downloaded from web, 
https://github.com/daleathan/widget-tour-py3. there are two files involved:


#file button.py

from tkinter import *
from tkinter.ttk import *
import infrastructure
...
class ButtonsDemoWindow( infrastructure.DemoWindow ):
...
def __init__( self ):
...
...
for c in ('Peach Puff', 'Light Blue', 'Sea Green', 'Yellow' ):
b = Button(self.frame, text=c)
b['command'] = infrastructure.callit( self.callback, c )
b.pack( side=TOP, expand=YES, pady=2 )

def callback(self, color):
self.frame['background']=color

def runDemo():
ButtonsDemoWindow()

--
#file infrastructure.py
...
class DemoWindow( Toplevel ):
...
...
class callit:
def __init__(self, function, *args ):
self.f = function
self.args = args

def __call__(self, *ignored):
self.f( *self.args)


I run it under the DOS box:

D:\Works\Python\widget-tour-py3-master>python
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 
bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import button
>>> button.runDemo()

after the window shows up, I pressed one of the buttons and get the error below:

>>> Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__
return self.func(*args)
  File "D:\Works\Python\widget-tour-py3-master\infrastructure.py", line 216, in 
__call__
self.f( *self.args)
  File "D:\Works\Python\widget-tour-py3-master\button.py", line 39, in callback
self.frame['background']=color
  File "C:\Python34\lib\tkinter\__init__.py", line 1331, in __setitem__
self.configure({key: value})
  File "C:\Python34\lib\tkinter\__init__.py", line 1324, in configure
return self._configure('configure', cnf, kw)
  File "C:\Python34\lib\tkinter\__init__.py", line 1315, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-background"


When I looked into the file tkinter\__init__.py, I found there is codes which 
add conditionally a '-' onto the original cnf argument:

1305  def _configure(self, cmd, cnf, kw):
1306  """Internal function."""
...
...
1313  if isinstance(cnf, str):
1314  return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf)))

Is it the reason this exception raised? Why is that?

Best Regards,
Jach Fong

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


Re: Call a class A method from a class B instance? Do I miss something?

2017-08-18 Thread jfong
Rick Johnson at 2017/8/18 UTC+8 AM 11:43:06 wrote:
> jf...@ms4.hinet.net wrote:
> > I study some codes of a tutorial about tkinter
> >
> > [snip code]
> >
> > My question is that the object which was left by
> > callit(self.demoenter_callback, tag) is a callit instance,
> > and the method it calls is a DemoMainWindow's method. How
> > it is possible?
> 
> Why would it _not_ be possible? Functions are first class
> objects, after all. Google it.
> 
> All the code is doing here is passing around a function
> reference and argument list like a baton in a foot race. No
> real magic here, just a lot of academic smoke and mirrors
> really. Or maybe this is more like a rat maze? Or a hot
> potato? Opinions may vary...
> 
> But short of obfuscation for the _sake_ of obfuscation, i
> don't understand what the tutorial author is intending to
> teach you here. Sheesh, the same goal could be achieved much
> more clearly by wrapping the argument-laden callback in an
> anonymous function or using a functools.partial, as the
> _true_goal_ here is to avoid premature execution of the
> argument-laden callback.
> 
> I absolutely detest superfluity!
> 
> --

According to the explanation above Ian had done, this method was already bound 
by "self". To set my mind ease, I follow your suggestion and implement a 
closure to replace the class:

def callit(function, *args):
def inner(*ignored):
return function(*args)
return inner

or even a lambda to get rid of callit:

lambda *ignored, a=tag: self.demoenter_callback(a)

I didn't try functools.partial but I think it will work too.

Thanks for your point of view.

--Jach

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


Re: Call a class A method from a class B instance? Do I miss something?

2017-08-18 Thread jfong
Ian於 2017年8月18日星期五 UTC+8上午10時41分44秒寫道:
> On Thu, Aug 17, 2017 at 6:03 PM,   wrote:
> > I study some codes of a tutorial about tkinter 
> > (https://github.com/daleathan/widget-tour-py3) and can't figure out how it 
> > works.
> >
> > Below is the codes from its two major files:
> > 
> > # file infrastructure.py
> > ...
> > ...
> > class callit:
> > def __init__(self, function, *args ):
> > self.f = function
> >
> > self.args = args
> >
> >
> > def __call__(self, *ignored):
> > self.f(*self.args)
> >
> > ...
> >
> > 
> > # file widget.py
> > ...
> > from infrastructure import *
> > ...
> > class DemoMainWindow(Frame):
> > ...
> > def _fill_textarea(self):
> > ...
> > # bind events
> > self.text.tag_bind(tag, '',
> >
> >  callit(self.demoenter_callback, tag) )
> > ...
> >
> > def demoenter_callback(self, tag):
> > ...
> > self.text.configure(cursor='hand2')
> > ...
> >
> > --
> > My question is that the object which was left by 
> > callit(self.demoenter_callback, tag) is a callit instance, and the method 
> > it calls is a DemoMainWindow's method.
> > How it is possible?
> 
> Methods are just functions with a bit of magic [1] that binds the self
> argument to them.
> 
> DemoMainWindow.demoenter_callback is an unbound method object
> (although in Python 3, it's just an ordinary function). When
> self.demoenter_callback is evaluated, the result is not the same
> unbound method object. Instead you get a different *bound* method
> object, which binds the self argument to the DemoMainWindow instance.
> The important point is that this binding happens when
> self.demoenter_callback is evaluated, not when the method is called.
> 
> This bound method object gets passed to the callit object, which saves
> it as self.f. Later, it calls self.f() which calls the method that is
> still bound to the same DemoMainWindow instance. Note that evaluating
> self.f does not *rebind* the method object. Bound method objects never
> get rebound; they are only created from unbound methods.
> 
> So when self.f() is called the bound DemoMainWindow instance is used
> as the value of the self argument. The fact that it was actually
> called from a method of callit doesn't matter.
> 
> [1] This magic is called the descriptor protocol, and if you want to
> play with it you can use it to create your own method types! This is a
> topic usually presented to intermediate-level Python programmers.

Thank you for your explaination about the bound/unbound method. I had read them 
in various document many times before but never pay attention to it becasue it 
seems didn't matter much in real world coding. 

>The important point is that this binding happens when
>self.demoenter_callback is evaluated, not when the method is called.

All I had learned about the "self" argument is that it's a hidden argument and 
was passed as the first argument at the time when method was called, never 
though it can be used to "bind" a method alone. It's completely new to me.

>So when self.f() is called the bound DemoMainWindow instance is used
>as the value of the self argument. The fact that it was actually
>called from a method of callit doesn't matter.

It seems there is a hard homework waiting for me. Any hint?

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


Call a class A method from a class B instance? Do I miss something?

2017-08-17 Thread jfong
I study some codes of a tutorial about tkinter 
(https://github.com/daleathan/widget-tour-py3) and can't figure out how it 
works. 

Below is the codes from its two major files:

# file infrastructure.py
...
...
class callit:
def __init__(self, function, *args ):
self.f = function

self.args = args


def __call__(self, *ignored):
self.f(*self.args)

...


# file widget.py
...
from infrastructure import *
...
class DemoMainWindow(Frame):
...
def _fill_textarea(self):
...
# bind events
self.text.tag_bind(tag, '',

 callit(self.demoenter_callback, tag) )
...

def demoenter_callback(self, tag):
...
self.text.configure(cursor='hand2')
...

--
My question is that the object which was left by 
callit(self.demoenter_callback, tag) is a callit instance, and the method it 
calls is a DemoMainWindow's method.
How it is possible?


Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Strang thing in tkinter, and pdb too?

2017-06-11 Thread jfong
Terry Reedy於 2017/06/12 UTC+8 12:04:18PM wrote:
> Right.  I got this with IDLE tests before using ttk.  Good luck tracing 
> this to its origin.

A little progress. If I remove temp.destroy() at line 34 then that message is 
gone. hmm...trying to find another way of doing it:-)

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


Strang thing in tkinter, and pdb too?

2017-06-11 Thread jfong
I had donwload wdiget-tour-py3.tar.gz examples from this site:
http://www.hullsvle.ch/moodle/mod/resource/view.php?id=6697
and run one of its scripts canvasruler.py, I get stange result.

First, when I run it in the cmd box, although I get a message in the box,
but everything else is fine. The GUI works correctly.

D:\Temp\widget-tour-py3>python canvasruler.py
can't invoke "event" command: application has been destroyed
while executing
"event generate $w <>"
(procedure "ttk::ThemeChanged" line 6)
invoked from within
"ttk::ThemeChanged"

Second, I try to find out where is this message comes from. I insert
a statement "import pdb; pdb.set_trace()" at the source line 33:

33 import pdb; pdb.set_trace()
34 #
35 # Note : to execute the Tk command, I need to create a Toplevel window
36 # I guess I could use the toplevel create in widget.py, buth then this
37 # module would not run stand-alone
38 #
39 temp = Tk()
40 STIPPLE_BITMAP = temp.tk.eval(
41  'image create bitmap @%s' % STIPPLE_BITMAP_FILE )
42 ## Now I can delete the spurious window
43 temp.destroy()
44
45
46 TAB_NORMAL_STYLE = {'fill':'black', 'stipple':''}
47 TAB_INRANGE_STYLE = {'fill':'green', 'stipple':''}
48 TAB_OUTOFRANGE_STYLE = {'fill':'red', 'stipple':STIPPLE_BITMAP}
49
50
51 class RulerCanvas (Canvas):

and run this script under interpreter, it stops at the point correctly and
I can step through to reach the line 51 without seeing that message appear.

D:\Temp\widget-tour-py3>python
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 
bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import canvasruler
> d:\work\python\widget-tour-py3\canvasruler.py(39)()
-> temp = Tk()
(Pdb) next
> d:\work\python\widget-tour-py3\canvasruler.py(40)()
-> STIPPLE_BITMAP = temp.tk.eval(
(Pdb) until 51
> d:\work\python\widget-tour-py3\canvasruler.py(51)()
-> class RulerCanvas (Canvas):
(Pdb)

Third, I moved the set_trace() to line 50 and run again. This time I saw that 
message appears in the cmd box.

D:\Temp\widget-tour-py3>python
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 
bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import canvasruler
> d:\work\python\widget-tour-py3\canvasruler.py(51)()
-> class RulerCanvas (Canvas):
(Pdb) can't invoke "event" command: application has been destroyed
 while executing
"event generate $w <>"
(procedure "ttk::ThemeChanged" line 6)
invoked from within
"ttk::ThemeChanged"

(Pdb) list
 46 TAB_NORMAL_STYLE = {'fill':'black', 'stipple':''}
 47 TAB_INRANGE_STYLE = {'fill':'green', 'stipple':''}
 48 TAB_OUTOFRANGE_STYLE = {'fill':'red', 'stipple':STIPPLE_BITMAP}
 49
 50 import pdb; pdb.set_trace()
 51  -> class RulerCanvas (Canvas):
 52
 53 def __init__(self, master ):
 54 Canvas.__init__(self, master, width=200+RULER_LENGTH, 
height=100 )
 55 self.draw_ruler()
 56 self.draw_well()
(Pdb)

My problem is why the difference? and how to find out where that message comes 
from?

PS. I also run this test under a Win8.1/64bit machine, get the same result.
PSS. I had scan files in the whole example directory and found there is
 no any file using ttk module.
 
Best Regards,
Jach Fong
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What is the difference between x[:]=y and x=y[:]?

2017-04-12 Thread jfong
Peter Otten at 2017/4/12 UTC+8 PM 8:13:53 wrote:
> I should add that you can write
> 
>  lr = [[1], [0]]
>  lx = []
>  for i in range(len(lr)):
> > ... lx = lr[i][:]
> > ... lx.append(0)
> > ... lr[i].append(1)
> > ... lr.append(lx)
> > ...
>  lr
> >[[1, 1], [0, 1], [1, 0], [0, 0]]
> > 
> 
> idiomatially as
> 
> >>> lr = [[1], [0]]
> >>> [inner + tail for tail in [[1], [0]] for inner in lr]
> [[1, 1], [0, 1], [1, 0], [0, 0]]
> 
> Note that there is a difference -- the resulting list does not share any 
> lists with the original `lr` as concatenating two lists produces a new one:
> 
> >>> a = [1]
> >>> b = [2]
> >>> c = a + b
> >>> a is c
> False
> >>> b is c
> False

I was a little embarrassed when looking at my codes. It may take me a long time 
to get used to thinking in the "Pythonic" way:-( But definitely I have learned 
much from this forum:-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What is the difference between x[:]=y and x=y[:]?

2017-04-12 Thread jfong
Peter Otten at 2017/4/12 UTC+8 PM 4:41:36 wrote:
> jf...@ms4.hinet.net wrote:
> 
> Assuming both x and y are lists
> 
> x[:] = y 
> 
> replaces the items in x with the items in y while
> 
> 
> x = y[:]
> 
> makes a copy of y and binds that to the name x. In both cases x and y remain 
> different lists, but in only in the second case x is rebound. This becomes 
> relevant when initially there are other names bound to x. Compare:
> 
> 
> >>> z = x = [1, 2]
> >>> y = [10, 20, 30]
> >>> x[:] = y # replace the values, z affected
> >>> z
> [10, 20, 30]
> 
> 
> >>> z = x = [1, 2]
> >>> y = [10, 20, 30]
> >>> x = y[:] # rebind. x and z are now different lists
> >>> z
> [1, 2]

Thank you Peter, I think I know the problem now. The append(lx) method actually 
append a link to the name lx, not append a copy of lx. When use lx[:]=lr[i]. 
the lx's content changes and it also reflected to the lr. When use lx=lr[i][:], 
a new lx was created and it will not affect the old one linked in the lr. 

Anyway it seems as better to use append(lx[:]) for this sake:-)

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


What is the difference between x[:]=y and x=y[:]?

2017-04-12 Thread jfong
I have a list of list and like to expand each "list element" by appending a 1 
and a 0 to it. For example, from "lr = [[1], [0]]" expand to "lr = [[1,1], 
[0,1], [1,0], [0,0]]".

The following won't work:

Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> lr = [[1], [0]]
>>> lx = []
>>> for i in range(len(lr)):
... lx[:] = lr[i]
... lx.append(0)
... lr[i].append(1)
... lr.append(lx)
...
>>> lr
[[1, 1], [0, 1], [0, 0], [0, 0]]
>>>

But the following does:

>>> lr = [[1], [0]]
>>> lx = []
>>> for i in range(len(lr)):
... lx = lr[i][:]
... lx.append(0)
... lr[i].append(1)
... lr.append(lx)
...
>>> lr
[[1, 1], [0, 1], [1, 0], [0, 0]]
>>>

After stepping through the first one manually:

>>> lr = [[1], [0]]   
>>> lx[:] = lr[0] 
>>> lx.append(0)  
>>> lx
[1, 0]
>>> lr[0].append(1)   
>>> lr
[[1, 1], [0]] 
>>> lr.append(lx) 
>>> lr
[[1, 1], [0], [1, 0]] 
>>>   

So far so good...

>>> lx[:] = lr[1]
>>> lx.append(0) 
>>> lx   
[0, 0]   
>>> lr[1].append(1)  
>>> lr   
[[1, 1], [0, 1], [0, 0]] 
>>>

Woops! What's wrong?

--Jach Fong

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


Re: help on "from deen import *" vs. "import deen"

2016-11-20 Thread jfong
Tristan B. Kildaire at 2016/11/20 8:23:37PM wrote:
> From deen import * imports all the things in deen but accessable with no 
> `deen.`

These "accessible" objects become read-only even if it's mutable. For immutable 
objects, you can't even create a new one in the deen's namespace.

> import deen imports all of deen but accessible via `deen.thing` 

:-)

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


Re: How to append a modified list into a list?

2016-11-19 Thread jfong
Peter Otten at 2016/11/19 5:40:34PM wrote:
> And now for something completely different ;)
> 
> What if you only record the changes to the list? For a long list that would 
> save space at the expense of calculation time. For example:

Excellent! Although not 100% fit into my application, I must study how this 
Class works. Thank you.

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


Re: help on "from deen import *" vs. "import deen"

2016-11-19 Thread jfong
Chris Angelico at 2016/11/19 2:58:41PM wrote:
> On Sat, Nov 19, 2016 at 3:34 PM, Steve D'Aprano
>  wrote:
> > What happens if you do this?
> >
> > spam = eggs = cheese = obj
> >
> > Is that different from:
> >
> > spam = obj
> > eggs = obj
> > cheese = obj
> >
> >
> > or from this?
> >
> > spam = obj
> > eggs = spam
> > cheese = eggs
> > ...
> > These aren't silly questions.
> 
> Indeed, they are not silly. It surprised me (as a C programmer) that
> the assignments happen left-to-right, rather than right-to-left (in C,
> cheese would be set first, then eggs, then spam). These are questions
> filled with subtleties.
> 
> ChrisA

Why this conversation makes me feel like a fool? Are they different?

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


Re: How to append a modified list into a list?

2016-11-18 Thread jfong
Oh, I don't know slice well enough:-(

So, slice tbl[:] will create a new object (a copy of tbl) which can be passed 
as a function argument
m.append(tbl[:])

or bind to a new name
w=tbl[:]

or re-bind to itself
w[:]=tbl

Thanks you, Ian and Steve.

Steve D'Aprano at 2016/11/19 11:01:26AM wrote:
> In newer versions of Python, you can do this:
> m.append(tbl.copy())

I like it:-)

--Jach

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


How to append a modified list into a list?

2016-11-18 Thread jfong
I have a working list 'tbl' and recording list 'm'. I want to append 'tbl' into 
'm' each time when the 'tbl' was modified. I will record the change by append 
it through the function 'apl'.

For example:

>>>tbl=[0,0]
>>>m=[]

>>>tbl[0]=1
>>>apl(tbl)
>>>m
[[1,0]]

>>>tbl[1]=2
>>>apl(tbl)
>>>m
[[1,0], [1,2]]

How to define this function properly?

Obviously the most intuitive way doesn't work.
def apl0(tbl):
m.append(tbl)

and introducing a local variable will not help either.
def apl1(tbl):
w=tbl
m.append(w)

I figure out a workable way, but looks ugly.
def apl2(tbl):
w=[]
w[:]=tbl
m.append(w)

I know those binding tricks between names and objects. Just wondering if there 
is an elegant way of doing this:-)

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


Re: help on "from deen import *" vs. "import deen"

2016-11-17 Thread jfong
Michael Torrie at 2016/11/18 11:03:12AM wrote:
> >> Python's variables are different from other languages, but in an
> >> understandable way.  
> > 
> > Unfortunately it's also different from human language.
> 
> How so? I don't find this to be true at all.

The fact that most novices will stumble on Python variable many times until it 
becomes his "second nature" proves it's different from the human language:-)

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


Re: help on "from deen import *" vs. "import deen"

2016-11-17 Thread jfong
Michael Torrie at 2016/11/17 11:38:32PM wrote:
> Like I said, whether the names you use are appropriate is completely up
> to you.  But this statement seems to imply you're still not getting it
> and still thinking of variables as boxes like they are in other
> languages, rather than labels that can only point to one thing at a
> time.

As a knowledge, I do know the re-bind tricky Python had on its variable, and 
that's mostly I stumbled so far when writing Python codes.

> Python's variables are different from other languages, but in an
> understandable way.  

Unfortunately it's also different from human language.

> As Dennis said, understanding Python variables,
> though not difficult, needs to be second nature to you or you'll be
> fighting Python and hating the experience.

That's the point: to build a second nature.

But it won't be easy because of we use human language used everyday:-(

--Jach



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


Re: help on "from deen import *" vs. "import deen"

2016-11-17 Thread jfong
Steven D'Aprano at 2016/11/17 4:04:04PM wrote:
> The most important thing you should learn from this thread is:
> 
> - avoid using "from module import *" as it is usually more trouble 
>   than it is worth.
> 
> 
> It is confusing and leads to more problems than it solves. If Python was 
> being 
> invented now, rather than 20 years ago, I would expect that there would be no 
> "import *" in the language.

It's the greatest advice I ever had in Python:-)

--Jach

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


Re: help on "from deen import *" vs. "import deen"

2016-11-16 Thread jfong
Steven D'Aprano at 2016/11/17 12:06:19PM wrote:
> You understand how this works?

Yes, thank you for your detail explanation.

> import russia as _tmp
> president = _tmp.president
> del _tmp

This one I can understand. But the previous one

>>_tmp = int('5')
>>for name in dir(_tmp):
>>if not name.startswith('_'):
>>locals()[name] = getattr(_tmp, name)
>>del _tmp

which I am still on scratching my head.

Now the question moves from "how" to "why":

Why "del _tmp" at the last step? The only reason I can thought of is 
"information hiding", but from whom? A global variable has its reason to be as 
a global. It may need to be modified later to influence others behavior. Using 
delete to hide the name seems unnecessary and redundant. If someone really 
want, he can follow the solution Chris had provided in his reply.

>>from deen import *
>>...
>>import deen
>>deen.some_name = new_value

A little strange, but effective:-)

--Jach

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


Re: help on "from deen import *" vs. "import deen"

2016-11-16 Thread jfong
Michael Torrie at 2016/11/16 11:15:11AM wrote:
> ... The globals object is a dictionary and is itself
> mutable.  But when we assign a new object to a particular dictionary
> key, it tosses out the old reference and makes the key now refer to the
> new object.  It does not do anything to the old object itself.

The last question: Is it possible, in the current Python version, to re-bind a 
global name in module "deen" after it was imported "from deen import *"?

> > That's one problem I was concerned. Human beings are very deeply
> > binding on words (names?). We think in words, talk in words,
> > communicate in words. Actually we are living in words. I really don't
> > like that when I said "John is a boy" and was told "No, John is a dog
> > now":-)
> 
> Not quite sure where you're going with that. I would think the idea of
> labels on objects would be fairly natural. I could stick a label that
> says "chair" on a chair, and then later move that label to the couch.
> Same label, different object.  Whether the label makes sense is up to you.

I mean it might be better to have two labels to label chair and couch 
separately, instead of one:-)

--Jach

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


Re: help on "from deen import *" vs. "import deen"

2016-11-16 Thread jfong
Steve D'Aprano at 2016/11/16 8:33:23AM wrote:
> `import foo` imports the module foo, that is all. (To be pedantic: it is
> *nominally* a module. By design, it could be any object at all.)
> 
> `from foo import *` imports all the visible public attributes of foo.
> 
> They do completely different things, equivalent to something similar to:
> 
> five = int('5')
> 
> 
> versus:
> 
> 
> _tmp = int('5')
> for name in dir(_tmp):
> if not name.startswith('_'):
> locals()[name] = getattr(_tmp, name)
> del _tmp

This is far beyond my comprehension:-(

--Jach

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


Re: help on "from deen import *" vs. "import deen"

2016-11-15 Thread jfong
Michael Torrie at 2016/11/15 10:43:58PM wrote:
> Seems like you're still not understanding Python variables.

I do, just not get used to it yet:-)

>  However once
> you assign to these names in your current module you are breaking this
> link to the deen module and assigning a new object to these names in
> your current module's namespace.

Why? the name "tblm" is already exist and is a mutable one, should be changed 
intuitional by "tblm=tbli". If I really need a new list, I can create one by 
using a new name. Python shouldn't have its finger in my pie:-(

> You're getting hung up on the names,
> when you should be concentrating on what the names refer to.

That's one problem I was concerned. Human beings are very deeply binding on 
words (names?). We think in words, talk in words, communicate in words. 
Actually we are living in words. I really don't like that when I said "John is 
a boy" and was told "No, John is a dog now":-)

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


Re: help on "from deen import *" vs. "import deen"

2016-11-14 Thread jfong
MRAB at 2016/11/15 11:31:41AM wrote:
> When you say "from deen import *" you're copying names and their 
> references from the module's namespace to your local namespace:
> 
>  [module deen]   [locally]
> 
>  tblm > [0, 0, 0] <- tblm
> 
>  tbli > [102, 39, 208] < tbli

hmm...I always thought that the picture of "from deen import *" is

[locally]

 [0, 0, 0] <- tblm

 [102, 39, 208] < tbli

But obviously it's not. The compiled code of function gpa is still reference to 
a hidden deen.tblm 'global' object which I can't access anymore. A bad news:-(

--Jach

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


Re: help on "from deen import *" vs. "import deen"

2016-11-14 Thread jfong
Ned Batchelder at 2016/11/15 6:33:54AM wrote:
> > But I get a wrong answer this way:
> > >>> from deen import *
> > >>> tblm = tbli
> > >>> gpa(0x7d)
> > 125  # it's 0x7d, the tblm[2] is 0
> > 
> > Why? why! why:-(
> 
> Here you are assigning a value to your own tblm, not deen.tblm,
> so gpa does not see the new value.
> 
Hi Ned, below is the capture of my terminal screen:

D:\Temp>python
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

>>> from deen import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__',
 'gpa', 'tbli', 'tblm']
>>> tblm
[0, 0, 0]
>>> tblm=tbli
>>> tblm
[102, 39, 208]
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__',
 'gpa', 'tbli', 'tblm']
>>>

Do you mean the last 'tblm' is my own? How it can be? The 'tblm' already exist 
before the assignment and this assignment shouldn't create a new one, right? 
and how do I assign the 'deen.tblm' under this circumstance?

--Jach

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


help on "from deen import *" vs. "import deen"

2016-11-13 Thread jfong
Running the following codes (deen.py) under Win32 python 3.4.4 terminal:

tbli = [0x66, 0x27, 0xD0]
tblm = [0 for x in range(3)]
def gpa(data):
td = data ^ tblm[2]
return td

I can get a correct answer this way:
>>> import deen
>>> deen.tblm = deen.tbli
>>> deen.gpa(0x7d)
173  # 0xad (= 0x7d ^ 0xd0) is decimal 173

But I get a wrong answer this way:
>>> from deen import *
>>> tblm = tbli
>>> gpa(0x7d)
125  # it's 0x7d, the tblm[2] is 0

Why? why! why:-(

--Jach

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


Re: Is it possible Python can distinguish capital letter and small letter in the path of Windows?

2016-10-11 Thread jfong
wxjm...@gmail.com at 2016/10/11 9:40:21PM wrote:
> If you are about to modify your registry, do not
> forget to switch your Windows in a *utf-8 mode*.

Have no idea how to "switch" Windows in a "utf-8 mode"? What will happens if 
not? Can you give a simple example? Thanks ahead.

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


Re: Is it possible Python can distinguish capital letter and small letter in the path of Windows?

2016-10-11 Thread jfong
Hi, eryk, thanks for your solution.

I had try to find the document of the _winapi module, but can't find any in my 
installed Python directory. Can you give me a link to look for?

> This alone doesn't make the Windows API case sensitive, but it does
> enable individual CreateFile calls to be case sensitive, via the POSIX
> semantics flag.

Does it means that an application program which uses the POSIX semantics flag 
in its API call will perform case-sensitive automatically after the 
"obcaseinsensitive" flag was modified by the user?

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


Is it possible Python can distinguish capital letter and small letter in the path of Windows?

2016-10-11 Thread jfong
I have two files in the Q:\lib directory:

Q:\lib>dir
2007/03/11 AM 08:025,260  lib_MARK.so
2007/03/11 AM 08:024,584  lib_mark.so

Under Python 3.4.4 I got:

>>> f = open('lib_MARK.so', 'br')
>>> data = f.read()
>>> f.close()
>>> len(data)
4584

I know Windows won't, but can Python make it true?

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


Re: How to make a foreign function run as fast as possible in Windows?

2016-10-01 Thread jfong
Chris Angelico at 2016/10/1 11:25:03AM wrote:
> What's it doing? Not every task can saturate the CPU - sometimes they
> need the disk or network more.
> 
This function has no I/O or similar activity, just pure data processing, and it 
takes less than 200 bytes of data area to work with.

My CPU is an i3 (4 threads/2 cores). I suppose after this job was assigned to 
run on a particular core, the OS shouldn't bother it by other system related 
tasks anymore. If it does, won't be this OS designed stupidly?

I was puzzled why the core has no 100% usage? Why always has some percentage of 
idle?

--Jach

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


Re: How to make a foreign function run as fast as possible in Windows?

2016-09-30 Thread jfong
Paul  Moore at 2016/9/30 7:07:35PM wrote:
> OK. So if your Python code only calls the function once, the problem needs to 
> be fixed in the external code (the assembly routine). But if you can split up 
> the task at the Python level to make multiple calls to the function, each to 
> do a part of the task, then you could set up multiple threads in your Python 
> code, each of which handles part of the task, then Python merges the results 
> of the sub-parts to give you the final answer. Does that make sense to you? 
> Without any explicit code, it's hard to be sure I'm explaining myself clearly.
> 

That's what I will do later, to split the task into multiple cores by passing a 
range parameter (such as 0~14, 15~29, ..) to each instance. Right now, I just 
embedded the range in the function to make it simple on testing.

At this moment my interest is how to make it runs at 100% core usage. Windows 
task manager shows this function takes only ~70% usage, and the number varies 
during its execution, sometimes even drop to 50%.

I also had test a batch file (copied from another discussion forum):
@echo off
:loop
goto loop
It takes ~85% usage, and the number is stable.

The result is obviously different. My question is how to control it:-)

--Jach

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


Re: How to make a foreign function run as fast as possible in Windows?

2016-09-28 Thread jfong
Paul  Moore at 2016/9/28 11:31:50PM wrote:
> Taking a step back from the more detailed answers, would I be right to assume 
> that you want to call this external function multiple times from Python, and 
> each call could take days to run? Or is it that you have lots of calls to 
> make and each one takes a small amount of time but the total time for all the 
> calls is in days?
> 
> And furthermore, can I assume that the external function is *not* written to 
> take advantage of multiple CPUs, so that if you call the function once, it's 
> only using one of the CPUs you have? Is it fully utilising a single CPU, or 
> is it actually not CPU-bound for a single call?
> 
> To give specific suggestions, we really need to know a bit more about your 
> issue.

Forgive me, I didn't notice these detail will infulence the answer:-)

Python will call it once. The center part of this function was written in 
assembly for performance. During its execution, this part might be called 
thousands of million times. The function was written to run in a single CPU, 
but the problem it want to solve can be easily distributed into multiple CPUs.

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


Re: How to make a foreign function run as fast as possible in Windows?

2016-09-28 Thread jfong
eryk sun at 2016/9/28 1:05:32PM wrote:
> In Unix, Python's os module may have sched_setaffinity() to set the
> CPU affinity for all threads in a given process.
> 
> In Windows, you can use ctypes to call SetProcessAffinityMask,
> SetThreadAffinityMask, or SetThreadIdealProcessor (a hint for the
> scheduler). On a NUMA system you can call GetNumaNodeProcessorMask(Ex)
> to get the mask of CPUs that are on a given NUMA node. The cmd shell's
> "start" command supports "/numa" and "/affinity" options, which can be
> combined.

Seems have to dive into Windows to understand its usage:-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to make a foreign function run as fast as possible in Windows?

2016-09-27 Thread jfong
eryk sun at 2016/9/27 11:44:49AM wrote:
> The threads of a process do not share a single core. The OS schedules
> threads to distribute the load across all cores

hmmm... your answer overthrow all my knowledge about Python threads 
completely:-( I actually had ever considered using ProcessPoolExecutor to do it.

If the load was distributed by the OS schedules across all cores, does it means 
I can't make one core solely running a piece of codes for me and so I have no 
contol on its performance?
-- 
https://mail.python.org/mailman/listinfo/python-list


How to make a foreign function run as fast as possible in Windows?

2016-09-26 Thread jfong
This function is in a DLL. It's small but may run for days before complete. I 
want it takes 100% core usage. Threading seems not a good idea for it shares 
the core with others. Will the multiprocessing module do it? Any suggestion?

Thanks ahead.

--Jach

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


Re: Iteration, while loop, and for loop

2016-06-30 Thread jfong
Steven D'Aprano at 2016/6/30 7:59:40AM wrote:
> py> mi = list('bananas')
> py> for char in mi:
> ... if char == 'a':
> ... mi.extend(' yum')
> ... print(char, end='')
> ... else:  # oh no, the feared for...else!
> ... # needed to prevent the prompt overwriting the output
> ... print()
> ...
> bananas yum yum yum
> py> 
> 
> 
> This example shows two things:
... 
> (2) Anyone who says that for...else without break is useless is wrong.

Haha...you win.

By the way, I never said "else" without "break" is illegal or useless, I said 
it will cause confusion semantically, just like this(it reminds me the IOCCC:-):

import math
pass
import os
pass
import sys 

Think of the "try ...except ...else ..." where the situation is similar but 
luckily it was mandatory.

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


Re: "for/while ... break(by any means) ... else" make sense?

2016-06-29 Thread jfong
Steven D'Aprano at 2016/6/29 UTC+8 10:43:52AM wrote:
> The "else" in for...else has nothing to do with any "if" inside the for
> block.

Yes, the "else" has nothing to do with "break" syntactically in Python 
language, but semantically in English it cause confusion. When I said "insane", 
I just want to emphasis this situation. 

"else" should appear only when there is a "break" in the "for" block, then "for 
...break... else ..." become perfectly alright semantically. Never think of it 
in "for ...else ..." or the confusion bond to come up:-)

--Jach


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


"for/while ... break(by any means) ... else" make sense?

2016-06-28 Thread jfong
Anyone who wrote the code below must be insane:-)

for x in range(3):
print(x)
else:
print('I am done')

But here it seems perfectly OK:

for x in range(3):
print(x)
if x == 1:  break
else:
print('I am done')

To me, the "else" was bonded with "break" (or return, or raise, or...),
not "for". It make sense:-)

--Jach

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


Re: Guys, can you please share me some sites where we can practice python programs for beginners and Intermediate.

2016-06-21 Thread jfong
Pushpanth Gundepalli at 2016/6/21 7:03:28PM wrote:
> Guys, can you please share me some sites where we can practice python 
> programs for beginners and Intermediate.

Is this you want? http://pythontutor.com/

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


Re: How to memory dump an object?

2016-05-21 Thread jfong
Make a quick experiment under version 3.4.4 through this simple "tool" Chris 
had provided, now I know how the unicode string was stored in memory:-)

>>> s1 = '\x80abc'
>>> s1
'\x80abc'
>>> len(s1)
4
>>> sys.getsizeof(s1)
41
>>> s1ptr = ctypes.cast(id(s1), ctypes.POINTER(ctypes.c_uint8))
>>> bytes([s1ptr[i] for i in range(41)])
b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x00\x04\xff\x04&\xa4\x00\x00d\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80abc\x00'
>>>
# a simple unicode string, each code point can be stored in one byte

>>> s2 = '\u0080abc'
>>> s2
'\x80abc'
>>> len(s2)
4
>>> sys.getsizeof(s2)
41
>>> s2ptr = ctypes.cast(id(s2), ctypes.POINTER(ctypes.c_uint8))
>>> bytes([s2ptr[i] for i in range(41)])
b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x00\x04\xff\x04&\xa4\x00\x00|\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80abc\x00'
>>>
# Python change it automatically to store each code point into one byte

>>> s3 = '\u07b4abc'
>>> s3
'\u07b4abc'
>>> len(s3)
4
>>> sys.getsizeof(s3)
46
>>> s3ptr = ctypes.cast(id(s3), ctypes.POINTER(ctypes.c_uint8))
>>> bytes([s3ptr[i] for i in range(46)])
b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x00\x19n\x93]\xa8\x00\x00dd\r\x1d\x02\x
00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\xb4\x07a\x00b\x00c\x00\x00\x00'
>>>
# use two bytes to store each code point, even the end-of-string mark

>>> s4 = '\U00025049abc'
>>> s4
'\U00025049abc'
>>> len(s4)
4
>>> sys.getsizeof(s4)
56
>>> s4ptr = ctypes.cast(id(s4), ctypes.POINTER(ctypes.c_uint8))
>>> bytes([s4ptr[i] for i in range(56)])
b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x003\xdd\xa7"\xb0\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00IP\x02\x00a\x00\x00\x00b\x
00\x00\x00c\x00\x00\x00\x00\x00\x00\x00'
>>>
# use four bytes to store each code point

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


Re: How to memory dump an object?

2016-05-20 Thread jfong
Sorry, forget to mention that I am working on version 3.4

Following the steps given in Chris's reply, I get the result from bytes string:

>>> b1 = b'\x80abc'
>>> ctypes.cast(id(b1), ctypes.c_voidp)
c_void_p(35495992)
>>> sys.getsizeof(b1)
21
>>> b1ptr = ctypes.cast(id(b1), ctypes.POINTER(ctypes.c_uint8))
>>> bytes([b1ptr[i] for i in range(21)])
b'\x01\x00\x00\x00X\xa1e^\x04\x00\x00\x00\x04\xff\x04&\x80abc\x00'
>>>

It obviously has the same "content" as the s1 string has and the object's 
structure are much different as expected (77 vs 21 bytes:-)

If I do this as Ned suggested:

>>> b2 = b1

I get:

>>> bytes([b1ptr[i] for i in range(21)])
b'\x02\x00\x00\x00X\xa1e^\x04\x00\x00\x00\x04\xff\x04&\x80abc\x00'
>>>

So, at least, we know where the reference count was stored:-)

It's amazing the "tool" is so simple. Actually I feel a little embarrassed that 
I do know every statements in it but just no idea of combining them together. 
Thanks a lot, Chris.

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


How to memory dump an object?

2016-05-20 Thread jfong
Is there any tools which can do the memory dump of an object so I can view 
their content or implementation? For example,

>>> s1 = '\x80abc'
>>> b1 = b'\x80abc'

What are exactly stored in memory for each of them? Is their content really the 
same? This kind of tool should be helpful "for me" to learn the inner detail of 
Python. 


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


Re: You gotta love a 2-line python solution

2016-05-02 Thread jfong
Stephen Hansen at 2016/5/3 11:49:22AM wrote:
> On Mon, May 2, 2016, at 08:27 PM, jf...@ms4.hinet.net wrote:
> > But when I try to get this forum page, it does get a html file but can't
> > be viewed normally.
> 
> What does that mean?
> 
> -- 
> Stephen Hansen
>   m e @ i x o k a i . i o

The page we are looking at:-)
https://groups.google.com/forum/#!topic/comp.lang.python/jFl3GJbmR7A

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


Re: You gotta love a 2-line python solution

2016-05-02 Thread jfong
DFS at 2016/5/3 9:12:24AM wrote:
> try
> 
> from urllib.request import urlretrieve
> 
> http://stackoverflow.com/questions/21171718/urllib-urlretrieve-file-python-3-3
> 
> 
> I'm running python 2.7.11 (32-bit)

Alright, it works...someway.

I try to get a zip file. It works, the file can be unzipped correctly.

>>> from urllib.request import urlretrieve
>>> urlretrieve("http://www.caprilion.com.tw/fed.zip";, "d:\\temp\\temp.zip")
('d:\\temp\\temp.zip', )
>>>

But when I try to get this forum page, it does get a html file but can't be 
viewed normally.

>>> urlretrieve("https://groups.google.com/forum/#!topic/comp.lang.python/jFl3GJ
bmR7A", "d:\\temp\\temp.html")
('d:\\temp\\temp.html', )
>>>

I suppose the html is a much complex situation where more processes need to be 
done before it can be opened by a web browser:-)

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


Re: You gotta love a 2-line python solution

2016-05-02 Thread jfong
DFS at 2016/5/2 UTC+8 11:39:33AM wrote:
> To save a webpage to a file:
> -
> 1. import urllib
> 2. urllib.urlretrieve("http://econpy.pythonanywhere.com
>  /ex/001.html","D:\file.html")
> -
> 
> That's it!

Why my system can't do it?

Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from urllib import urlretrieve
Traceback (most recent call last):
  File "", line 1, in 
ImportError: cannot import name 'urlretrieve'

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


Re: Dictionary is really not easy to handle

2016-04-28 Thread jfong
I was overwhelmed that three gurus inspire me in three different ways in their 
own flavour:-) That's really appreciated! Now I understand why it's so, thanks 
to all of you.

To Peter:
> With that information, can you predict what

> for k, v in {(1, 2): "three"}: print(k, v)

> will print? 

It's 1 2.

(Although Rustom had given the answer in his reply, I didn't figure out until 
after reading you and Steven's answers:-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Dictionary is really not easy to handle

2016-04-28 Thread jfong
I have a dictionary like this:

>>> dct ={1: 'D', 5: 'A', 2: 'B', 3: 'B', 4: 'E'}

The following code works:

>>> for k in dct: print(k, dct[k])
...
1 D
2 B
3 B
4 E
5 A

and this one too:

>>> for k,v in dct.items(): print(k,v)
...
1 D
2 B
3 B
4 E
5 A

But...this one?

>>> for k,v in dct: print(k,v)
...
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' object is not iterable

No idea what the error message means:-( Can anyone explain it? Thanks ahead.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: how to create a dictionary from csv file?

2016-04-26 Thread jfong
Just curious:-) why everyone here open the csv file without using newline='' as 
suggested in Python 3.4.4 document section 14.1?
-- 
https://mail.python.org/mailman/listinfo/python-list


What is the common technique used to cross-reference in module's method?

2016-03-19 Thread jfong
There are two modules (say model.py and piece.py) which has methods need to 
refer to each other module's methods. I saw in a book using the way below, by 
assigning one (the Model) object to an attribute of the other (the Piece) bject.
-
##model.py
import piece
...
class Model(dict):
...
def all_occupied_positions(self):
...

def reset_to_initial_locations(self):
self.clear()
for position, value in START_PIECES_POSITION.items():
self[position] = piece.create_piece(value)
self[position].model = self
...

##piece.py
...
def create_piece(value):  # Note: it's a function
   ...
   return eval(...)  # the returned object is a Piece object

class Piece():
...
def moves_available(self):
model = self.model
...
if item not in model.all_occupied_positions():
...
...
---
Is it a common way of doing this?

Why the author use the same module name "model" for those attribute and local 
names? Is it a good idea or bad?

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


Re: Any comment on using ctypesgen package?

2016-03-06 Thread jfong
Mark Lawrence at 2016/3/5  UTC+8 8:01:06PM wrote:
> 
> HTH http://python3porting.com/problems.html

OK, now I understand what "from .cparset import *" means, but it didn't help on 
solving this import error:-(

Thanks for the link, although it seems not help on this problem either:-)

--Jach

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


Re: Any comment on using ctypesgen package?

2016-03-05 Thread jfong
Chris Angelico at 2016/3/5  UTC+8 1:50:05PM wrote:
> Your conclusion may well be correct. However, the exact issue you're
> looking at here might be easily enough fixed; it looks like it's
> trying to sort things by length, so you can simply use "key=len" (and
> maybe "reverse=True").

After Chris gave this suggestion, I can't withstand the temptation of running 
the setup again. This time, strangely, it reports error on import. Won't the 
import statement easy enough to be handled by 2To3? Here is the result (where 
the whole "ctypesgencore" directory had been processed by 2To3 and the "parser" 
is a sub-directory under it):

--
D:\Patch\ctypesgen-master>python setup.py install
Traceback (most recent call last):
  File "setup.py", line 13, in 
import ctypesgencore
  File "D:\Patch\ctypesgen-master\ctypesgencore\__init__.py", line 55, in 
from . import parser
  File "D:\Patch\ctypesgen-master\ctypesgencore\parser\__init__.py", line 17, in
 
from .datacollectingparser import DataCollectingParser
  File "D:\Patch\ctypesgen-master\ctypesgencore\parser\datacollectingparser.py",
 line 10, in 
from . import ctypesparser
  File "D:\Patch\ctypesgen-master\ctypesgencore\parser\ctypesparser.py", line 15
, in 
from .cparser import *
  File "D:\Patch\ctypesgen-master\ctypesgencore\parser\cparser.py", line 21, in

from . import cgrammar
  File "D:\Patch\ctypesgen-master\ctypesgencore\parser\cgrammar.py", line 25, in
 
from . import ctypesparser
ImportError: cannot import name 'ctypesparser'


Just curious, is there a recursive-import happen on handling the "parser" 
directory?

After checking the files, I had noticed that all the import statements had been 
changed by 2To3. Mostly the changes are, such as, from "import cgrammar" to 
"from . import cgrammar", or "from cparser import *" to "from .cparset import 
*". I can understand the former, but can't figure out the latter:-(

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


Re: Any comment on using ctypesgen package?

2016-03-04 Thread jfong
Peter Otten 2016/3/4  UTC+8 8:36:02PM worte:
> """
> The 2to3 route is not likely to apply since ctypesgen actually writes Python 
> code and the 2to3 utility will probably miss a good portion of that logic.
> """
> 
> But as someone else seems to have done the work already
> 
> https://github.com/davidjamesca/ctypesgen/issues/51
> 
> I'd try his version first.

Following this link, it says "Make output python3-compatible". So it still run 
under 2.x but generate codes for 3.x:-(

After taking Chris's suggestion, the installation is pushing forward a little 
and then bump into another error:
--
File "D:\Patch\ctypesgen-master\ctypesgencore\parser\pplexer.py", line 123, in  
punctuator_regex
punctuator_regexes.sort(lambda a, b: -cmp(len(a), len(b)))
TypeError: must use keyword argument for key function
--
This error has been mentioned in "Sorting HOW TO" section in 3.4 document,
"In Py3.0, the cmp parameter was removed entirely"
"To convert to a key function, just wrap the old comparison function:"
"In Python 3.2, the functools.cmp_to_key() function was added to the 
functools module in the standard library."

Oh, goodness! do I have to dive into 2.x?

Based on the assumptions below:
1. It might be not easy to upgrade it to 3.x (at least not just run 2To3), or 
else its author will not drop it.
2. I have to go back into 2.x jungle to study all these difference.
3. Even "Python setup.py install" passed, it's still not sure if the output 
will be correct.

I think it's better to drop it too. Thanks for your advice, Chris and Peter.

--Jach

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


Any comment on using ctypesgen package?

2016-03-04 Thread jfong
I try to test this package but with no luck. This module was written for Python 
2.x but mine is 3.4 so I use the 2To3 to "upgrade" it first (it seems OK). Then 
I run "python setup.py install" and get the following error:
   ...
   ...
   File "D:\Patch\ctypesgen-master\ctypesgencore\parser\lex.py", line 41, in 

_INSTANCETYPE = types.InstanceType
   AttributeError: 'module' object has no attribute 'InstanceType'

Below is the troubled codes in file lex.py:
Note: In original codes (before 2To3 modify), there is "types.ObjectType" 
instead of "object".
-
# Available instance types.  This is used when lexers are defined by a class.
# It's a little funky because I want to preserve backwards compatibility
# with Python 2.0 where types.ObjectType is undefined.
try:
_INSTANCETYPE = (types.InstanceType, object)
except AttributeError:
_INSTANCETYPE = types.InstanceType
class object: pass   # Note: needed if no new-style classes present 
---
The author had put some comments above these codes but I have no idea what he 
is talking about.

There is someone who had encountered the same problem last year and raise a 
question at its home page, but the author seems has no interest on doing 
anything on it anymore.
https://github.com/davidjamesca/ctypesgen/issues/53

Does anyone know how to fix it? or the whole job will be a mission impossible 
if no help from its author?

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


Re: How to know if an object is still be referenced?

2016-03-02 Thread jfong
sohca...@gmail.com at 2016/3/3  UTC+8 7:38:45AM wrote:
> "label" might be a local variable, but it's constructor includes a reference 
> to the frame in which it is going.  The frame object will create a reference 
> to the newly-created Label object.  At that point, there will be two 
> references to the new Label object.  When the function exits and "label" goes 
> out of scope, the object still exists because the frame still has a reference.
> 
It sound reasonable enough:-)

There is a page talking about why should keep a separate reference in tkinter.
http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm

I also saw almost every code on the web about it was written in this way:
label = Label(playbar_frame, image=photo)
label.image = photo
But why? Won't it be better if it was written as:
label = Label(playbar_frame, image=photo)
label.imgKeeper = photo
At least it makes the meaning more clear, not lead someone to a wrong 
direction:-(

Anyway, following Terry's suggestion might be a better idea, making it bind to 
an object which will live for as long as the application is.

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


Re: How to know if an object is still be referenced?

2016-03-02 Thread jfong
Terry Reedy at 2016/3/2  UTC+8 3:04:10PM wrote:
> On 3/1/2016 9:35 PM, jf...@ms4.hinet.net wrote:
> > Recently I was puzzled by a tkinter problem. The codes below (from a book) 
> > can display the picture correctly.
> >
> >  gifdir = "../gifs/"
> >  from tkinter import *
> >  win = Tk()
> >  photo = PhotoImage(file=gifdir + "ora-pp.gif")
> >  Button(win, image=photo).pack()
> >  win.mainloop()
> 
> Since photo is a global name, the binding remain until you explicitly 
> delete it or exit the app.
> 
> > And the codes below (from another book) will also work.
> >
> >  class DrumMachine:
> >  
> >  
> >  def create_play_bar(self):
> >  
> >  
> >  photo = PhotoImage(file='images/signature.gif')
> >  label = Label(playbar_frame, image=photo)
> >  label.image = photo
> >  label.grid(row=start_row, column=50, padx=1, sticky='w')
> >  
> >  
> 
> Here photo is a local name and the binding disappears when the function 
> exits.  I would rewrite it to follow pattern 1.
> 
>   self.photo = PhotoImage(file='images/signature.gif')
>   label = Label(playbar_frame, image=self.photo)
> 
> To me, saving an attribute reference is not worth the extra line.
> 
> > In the second example, I noticed that the "photo" was referenced two times
> > and I think it might be a redundancy so I remove the line "label.image = 
> > photo". But it fails then.
> 
> On another question, I made the same suggestion.  Oops.
> 
> -- 
> Terry Jan Reedy

Thanks, Terry. After reading your reply I noticed that I had make a mistake. 
The "image" is not an attribute of the Button. It's an option. The 
"label.image=photo" does a different thing. But it didn't help on solving my 
puzzle.

If the problem was caused by the "photo" is a local, then binding the "photo" 
to an local attribute ("label" is a local too) seems no meaning at all. But it 
did make difference! No idea how the underneath mechanism works.

I run this example under the pdb and it can display the picture correctly even 
without the "label.image=photo" statement. Why it fails on running at real 
time? tk event scheduling? I don't know.

--Jach

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


How to know if an object is still be referenced?

2016-03-01 Thread jfong
Recently I was puzzled by a tkinter problem. The codes below (from a book) can 
display the picture correctly.

gifdir = "../gifs/"
from tkinter import *
win = Tk()
photo = PhotoImage(file=gifdir + "ora-pp.gif")
Button(win, image=photo).pack()
win.mainloop()

And the codes below (from another book) will also work.

class DrumMachine:


def create_play_bar(self):


photo = PhotoImage(file='images/signature.gif')
label = Label(playbar_frame, image=photo)
label.image = photo
label.grid(row=start_row, column=50, padx=1, sticky='w')



In the second example, I noticed that the "photo" was referenced two times and 
I think it might be a redundancy so I remove the line "label.image = photo". 
But it fails then.

How can it be? one works and the other not.

I search for answers on the web and here are some links talking about it:

http://stackoverflow.com/questions/20812579/why-it-shows-blank-instead-of-picture-in-my-tkinter-program
http://effbot.org/tkinterbook/photoimage.htm

They all said that you have to keep a reference to the "photo" or else it will 
be garbage collected. Now, as I had learn Python so far, I know that a keyword 
argument passed in an object instantiation will bind this object to its 
attribute name, i.e. create a reference to this object. (and it should or the 
whole language will be in disaster)

Can anyone help me out?

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


Re: Will file be closed automatically in a "for ... in open..." statement?

2016-02-17 Thread jfong
The "for ... open ..." is definitely not a good design pattern. It opens a file 
at "for" block but leaves it closed somewhere in the sky.

> The garbage collector will:
> - reclaim the memory used by the object;
> - close the file. 

I suppose (IMO) that the primitive idea of garbage collection doing the 
file-close affair is to make itself a final defense to prevent the possible 
disaster. (after all it's not of his business:-) But some coding may abuse this 
advantage and forget its hidden danger.

It's better to drop this "for...open..." style completely and stick at "with".

Thanks for all you gurus clarify my puzzle. I deeply appreciated it.

--Jach

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


Re: Will file be closed automatically in a "for ... in open..." statement?

2016-02-16 Thread jfong
Thanks for these detailed explanation. Both statements will close file 
automatically sooner or later and, when considering the exceptions, "with" is 
better. Hope my understanding is right.

But, just curious, how do you know the "for" will do it? I can't find any 
document about it from every sources I know. Very depressed:-(

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


Will file be closed automatically in a "for ... in open..." statement?

2016-02-16 Thread jfong
I know

with open('foo.txt') as f:
...do something...

will close the file automatically when the "with" block ends. 

I also saw codes in a book:

for line in open('foo.txt'):
...do something...

but it didn't mention if the file will be closed automatically or not when the 
"for" block ends. Is there any document talking about this? and how to know if 
a file is in "open" or not?

--Jach Fong

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


Re: How this C function was called through ctypes this way?

2016-02-04 Thread jfong
eryk sun at 2016/2/4 UTC+8 7:35:17PM wrote:
> > _mod = ctypes.cdll.LoadLibrary(_path)
> 
> Calling ctypes.CDLL directly is preferable since it allows passing
> parameters such as "mode" and "use_errno".
> 
> IMO, the ctypes.cdll and ctypes.windll loaders should be avoided in
> general, especially on Windows, since their attribute-based access
> (e.g. windll.user32) caches libraries, which in turn cache
> function-pointer attributes. You don't want function pointer instances
> being shared across unrelated packages. They may not use compatible
> prototypes and errcheck functions. Each package, module, or script
> should create private instances of CDLL, PyDLL, and WinDLL for a given
> shared library.

Thank you for your detail and deep explanation.

I suppose the reason there are many cases using LoadLibrary() and 
attribute-based access is because it's the way the ctypes tutorial in Python 
document takes. Although both methods has been mentioned in the ctypes 
reference section, but no pros and cons was explained.

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


How this C function was called through ctypes this way?

2016-02-04 Thread jfong
Here is an example from "Python Cookbook, Third Edition(by David Beazley and 
Brian K. Jones)" Chapter 15.1. "Accessing C Code Using ctypes"

---
import ctypes
...
# Try to locate the .so file in the same directory as this file
...
_mod = ctypes.cdll.LoadLibrary(_path)
...
...
# void avg(double *, int n)
# Define a special type for the 'double *' argument
class DoubleArrayType:
def from_param(self, param):
typename = type(param).__name__
if hasattr(self, 'from_' + typename):
return getattr(self, 'from_' + typename)(param)
elif isinstance(param, ctypes.Array):
return param
else:
raise TypeError("Can't convert %s" % typename)

...
# Cast from array.array objects
def from_array(self, param):
...
...

# Cast from lists
def from_list(self, param):
val = ((ctypes.c_double)*len(param))(*param)
return val

# Cast from a numpy array
def from_ndarray(self, param):
...
...

DoubleArray = DoubleArrayType()
_avg = _mod.avg
_avg.argtypes = (DoubleArray, ctypes.c_int)
_avg.restype = ctypes.c_double

def avg(values):
return _avg(values, len(values))

avg([1,2,3])
--

The followings was quoted from the book which explain how it does:
"The DoubleArrayType class shows how to handle this situation. In this class, a 
single method from_param() is defined. The role of this method is to take a 
single parameter and narrow it down to a compatible ctypes object (a pointer to 
a ctypes.c_double, in the example). Within from_param(), you are free to do 
anything that you wish. In the solution, the typename of the parameter is 
extracted and used to dispatch to a more specialized method. For example, if a 
list is passed, the typename is list and a method from_list() is invoked."

What confuse me are:
(1) at line: _avg.argtypes = (DoubleArray, ctypes.c_int)
The "DoubleArry" is an instance of the class "DoubleArrayType", Can it appear 
at where a type was expected? 
(2) How the method "from_param" was invoked? I can't see any mechanism to reach 
it from the "_avg(values, len(values))" call.


Best Regards,
Jach Fong

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


Re: Which Python editor has this feature?

2016-01-13 Thread jfong
Terry Reedy at 2016/1/13 UTC+8 5:15:20PM wrote:
> This was a Windows specific problem that was fixed (for me) in all three 
> recent (last November/December) bugfix releases.  If you have a problem 
> with *current* IDLE, I would like to know.

I download/install the latest version 3.4.4 and it works perfectly.

It surprise me that how Python society is so active. I had version 3.4.3 
installed 4 months ago and now this problem had already been taken care of:-) 
Thank you.

--Jach Fong

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


Re: Which Python editor has this feature?

2016-01-12 Thread jfong
wxjm...@gmail.com at 2016/1/月12 4:29:08PM wrote:
> IDLE ?
> I need less than 10 seconds to make it crash.

Unwittingly or intentionally?

> The interesting aspect is not only to show that it crashes,
> the very interesting point is to explain why it is crashing.

Can you tell us (in a separate subject title)? I am willing to learn every 
aspects of Python.

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


Re: Which Python editor has this feature?

2016-01-12 Thread jfong
Terry Reedy at 2016/1/12 UTC+8 3:56:03PM wrote:
> Revamping IDLE to 1. use ttk widgets and 2. become a modern single 
> window app with multiple panes, including a tabbed editor pane, is a 
> goal for 2016.

That will be great, I'm looking forward to it.

By the way, when I was playing around with the IDLE editor yesterday, I had 
noticed that during the time the "Search Dialog" was opened, "Find Next" button 
will not highlight the item searched, unless the dialog was closed.

--Jach Fong

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


Re: Which Python editor has this feature?

2016-01-11 Thread jfong
Terry Reedy at 2016/1/12 UTC+8 5:22:35AM wrote:
> IDLE has an optional 'code context' feature that shows header lines that 
> have scrolled up off the top of the screen.  This would let you see 
> which class you are in,

Thanks, Terry. It's just what I am looking for:-)
By the way, do you know how to open file in a new tab, instead of in a separate 
window, in the IDLE editor?

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


Re: Which Python editor has this feature?

2016-01-11 Thread jfong
Gordon Levi at 2016/1/11 UTC+8 4:41:20PM wrote:
> Jetbrains Pycharm has "go to start of block" and "go to end of block"
> commands .

Thanks, Gordon. But this seems only jump between the current code block's start 
and end, not to the code one level above:-(

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


Re: Which Python editor has this feature?

2016-01-11 Thread jfong
Tim Chase at 2016/1/11 UTC+8 11:16:27AM wrote:
> On 2016-01-10 17:59, jf...@ms4.hinet.net wrote:
> > It lets you jump between the current cursor position and the line
> > the upper level indentation start, something like the bracket
> > matching in C editor. Because of Python use indentation as its code
> > block mark, It might be helpful if we can jump between different
> > level of it:-)
> 
> While not quite what you're asking for, vim offers an "indent text
> object" plugin[1] that allows you to use a block of indentation
> around the cursor as an object.  So you can use vim's grammar to issue
> commands like "dai" to delete the current indentation-defined block;
> or you can use ">ii" to add a level of indentation to the
> indentation-defined block.

Thanks, Tim.
I always admire people who can remember all those detail 
commands/parameters/options which a DOS-style editor as vim has. It's almost 
like a mission impossible to me:-(

> If you want to make a vim mapping that will jump up to the top of the
> previous level of indentation, the following should do the trick
> 
>   :nnoremap  Q '?^'.repeat(' ', (strlen(substitute(getline('.'), 
> '\S.*', '', ''))-&sw)).'\S?e'."\"

But, but... this line??? won't it goes too far for a human being to read?

--Jach

> There might be some edge-cases that I haven't caught there, but, as
> long as you edit with spaces rather than tabs, it should work,
> including the accommodation of your 'shiftwidth', even if it's not
> PEP8 4-spaces-per-indent.
> 
> -tkc
> 
> [1]
> https://github.com/michaeljsmith/vim-indent-object

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


Re: Which Python editor has this feature?

2016-01-11 Thread jfong
Chris Angelico at 2016/1/11  UTC+8 10:59:47AM wrote:
> On Mon, Jan 11, 2016 at 12:59 PM,   wrote:
> > It lets you jump between the current cursor position and the line the upper 
> > level indentation start, something like the bracket matching in C editor. 
> > Because of Python use indentation as its code block mark, It might be 
> > helpful if we can jump between different level of it:-)
> 
> I coded this up as a patch for SciTE/Scintilla at one point, but it
> didn't get accepted. It was used for a while at my work, but never
> really settled in as being useful. Python code tends not to be as big
> and complex as C code often is, so it's not as useful to have a
> feature like this.
> 
> If you want it, I can probably hunt down the patch file somewhere.
> 
> ChrisA

I am studying the PyUSB package now as the learning object of how to write a 
Python program in a "formal" way. In those modules, there are many comment 
inserted between codes to explain what it does. It's good to the user 
comprehension, but also easily makes a Class size expanded to over 100 lines. 
Also many Classes has the same named method such as __getitem__ etc. When 
searching a specific name I usually have to roll back the screen a few times to 
find out what Class I am looking at. That's really annoy.

But, just like you said, this feature may be not so useful to a Python 
programmer. I should try the editor I am using now to see if I can "patch" a 
such feature, just as you had did on SciTE before:-)

--Jach

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


Which Python editor has this feature?

2016-01-10 Thread jfong
It lets you jump between the current cursor position and the line the upper 
level indentation start, something like the bracket matching in C editor. 
Because of Python use indentation as its code block mark, It might be helpful 
if we can jump between different level of it:-)


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


Re: Is there a way importing a string object?

2016-01-04 Thread jfong
jf...@ms4.hinet.net at 2016/1/5  UTC+8 8:49:56AM wrote:
Thanks, Ian and Ben. This forum is really a good place for learning Python. I 
am glad I had join in.

To Ben,
> (Please make the body of your message complete. The "Subject" field
> should be a summary of your message's subject, and may not be read as
> the first line of your message.)

Yes, The "Subject" seems a little strange, read likes a part of the body.
I am bad on composition. Even after your reminder, I still can't think of a 
better one:-(


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


Is there a way importing a string object?

2016-01-04 Thread jfong
For example,

name = "test"  # test.py is a module's file
import name

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


Re: A newbie quesiton: local variable in a nested funciton

2015-12-27 Thread jfong
Chris Angelico at 2015/12/27  UTC+8 2:32:32PM wrote:
> On Sun, Dec 27, 2015 at 3:11 PM,   wrote:
> > Last night I noticed that Python does not resolve name in "def" during 
> > import, as C does in the compile/link stage, it was deferred until it was 
> > referenced (i.e. codes was executed). That's OK for Anyway codes has to be 
> > debugged sooner or later. I just have to get used to this style.
> >
> > But check these codes, it seems not.
> > ---
> > x = 1  # a global variable
> > print(x)
> >
> > class Test:
> > x = 4  # a class attribute
> > print(x)
> > def func(self):
> > print(x)
> >
> > x1 = Test()
> > x1.x = 41  # a instance's attribute
> > x1.func()  # it's 1 but 41 was expect:-(
> > 
> >
> > --Jach
> 
> When you import this module, it runs all top-level code. So the
> 'print' at the top will happen at import time.
> 
> Among the top-level statements is a class definition. When that gets
> run (to construct the class itself - distinct from instantiating it,
> which happens further down), it builds a class by executing all the
> statements in it, in order. That results in that value of x being
> printed, and then defines a function.
> 
> The function definition is being run at time of class construction,
> and it creates a new attribute on the Test class. At that time, the
> function body isn't actually executed (as you might expect). However,
> it's worth noting that the function does not inherit class scope. The
> unadorned name 'x' references the global. If you want to access
> class-scope names from inside methods, you need to say 'self.x', which
> also applies to instance attributes. That's what would do what you
> expect here.
> 
> ChrisA

Yea, right, it's in a method, not a function. A stupid mistake I had made:-(
Thanks for your kindly patient with me, and Happy New Year to you:-)

--Jach

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


Re: A newbie quesiton: local variable in a nested funciton

2015-12-26 Thread jfong
Last night I noticed that Python does not resolve name in "def" during import, 
as C does in the compile/link stage, it was deferred until it was referenced 
(i.e. codes was executed). That's OK for Anyway codes has to be debugged sooner 
or later. I just have to get used to this style.

But check these codes, it seems not.
---
x = 1  # a global variable
print(x)

class Test:
x = 4  # a class attribute
print(x)
def func(self):
print(x)

x1 = Test()
x1.x = 41  # a instance's attribute
x1.func()  # it's 1 but 41 was expect:-(


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


Re: A newbie quesiton: local variable in a nested funciton

2015-12-26 Thread jfong
Chris Angelico at 2015/12/26  UTC+8 5:50:07PM wrote:
> 11: Another normal assignment, because otherwise the rest of the work
> is pointless. :)

Thanks for this detailed example. As I had learned so far, Python really take 
"name" seriously, and every meaningful result you got have to assign to a name 
at last. This morning I played some codes on the http://pythonturor.com and 
found out that every objects which was not created at top-level of a module or 
in a class will disappear after import. A very "unusual" view. 

> Python's flexibility and simplicity are a huge part of why I love the
> language so much.

simplicity? Maybe because you are s familiar with Python. It's not to me, 
at least at this moment. Please see my next question follows.

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


<    1   2   3   >