Re: TKinter in Python - advanced notions

2023-06-22 Thread Diego Souza via Python-list
Have you considered improving the architecture itself, not your GUI library
skills?

I recommend you look at the Model View ViewModel (MVVM) concept and
implement something similar (this is largely used in the Android framework
nowadays). This would separate your program logic from the rendering and
visualization. It would also make your program more reactive, decoupled,
and easier to maintain. When you mentioned threads I immediately thought of
this because it is much easier to implement parallel jobs and present
results back in the GUI, as everything becomes reactive. This is overkill
for a small project such as the code you showed, but I recommend it for
larger projects.





On Wed, Jun 21, 2023 at 7:20 PM aapost via Python-list <
python-list@python.org> wrote:

> On 6/21/23 09:47, Dan Kolis wrote:
> > I've write a huge biotech program ( an IDE for synthetic biology ), and
> am slowly outgrowing TKINTER.
> >
> > Has anybody out there merged a little bit of TCL direct calls from
> Python 3.X to get more freedom then TKINTER for just some Windows ?
>
> > I wish it looked better, but its 'ok'. I believe X11 IO is considerably
> superior for serious work the HTML.  I mean 'serious' work. with lots of
> multi media windows. I am not talking about fb "Oh ! There is a window it
> opened inthe corner !"... trivial functionality.
>
>
> I don't know if it would help, but you can extend/add tcl/tk packages
>
> I don't remember the full instructions right off, but quickly reverse
> engineering my old stuff I think you just need to drop them in
> /usr/share/tcltk/ or equivalent.
>
> (I needed to do that to replace the terrible looking default file dialog
> for unix/linux with fsdialog.)
>
> then running something like the following from your Tk object
>
> self.eval('package require fsdialog')
>
> (reverse engineering the python tkinter source you can likely find other
> ways of doing more tcl direct stuff)
>
> I have not researched if there are some better, more featured
> (non-buggy) Text widgets implemented in tcl that can be dropped in, (I
> know several of the tcl drop in widgets I tried were lacking in
> refinement).
>
>  From what I can tell, once upon a time there were better, more
> interesting projects and tutorials on extending tkinter, such as WCK
> (tkinter3000), but the only remnants of those remain publicly available
> are outdated unmaintained archives.
>
> You might also consider looking at the Grail browser source for research
> purposes, as it does some interesting things with some of the widgets,
> (parsing html and such), even though it is 20 years old now (and written
> in python 1).
> The update attempts from 10+ years ago have disappeared. (it's license
> is considered questionable from what I understand, so not sure if that
> is an aspect of it, the other being one of it's main features, python
> applets, is unsafe and was not easily fixable)
>
> You might already be beyond some of these things though.
>
> I know what you mean as far is feeling like the little bit extra you
> need pushes beyond what tkinter can do / makes you feel like you have
> outgrown the module.
>
> (I had to take a break from one of my projects and send it to
> development hell until my UI knowledge/skills improve after I found
> myself considering using xml schema appinfo annotations to store json
> formatted widget specific information, lol.)
>
> I have felt that sense of lack with most of the UI modules I have tried
> though.
>
> I don't know of a clear better python-only solution though that fits my
> personal needs.
>
> So I have to lean toward improving my tcl / C in hopes that it might
> help steer me toward that extra (which seems to be in the spirit of what
> tcl/tk's intent is to begin with). That will be a while for me though if
> I get there.
>
>
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 
Diego Souza
Wespa Intelligent Systems
Rio de Janeiro - Brasil
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Multithreading? How?

2023-05-12 Thread Diego Souza
 knows the status of the system (think of a simple ON/OFF status).
> The user can retrieve the status of the system through MQTT: it sends a
> message to read/status MQTT topic and receive back a message with the
> current status on read/status/reply MQTT topic. Of course, they are just
> examples.
>
> On the contrary, when the app detects a status change reported from the
> serial bus (think of a transition from ON to OFF), it sends a MQTT message.
>
> I'm thinking to split the application in three classes: Bus, App and
> IoT. Bus and IoT are also threads.
> The thread of Bus manages the serial protocol, while the thread of IoT
> manages MQTT connection with the broker (the server).
>
> However I don't know if it could be a good architecture. Suppone Bus
> thread receives a new status from the system. In the context of
> ThreadBus, the object Bus could call a method of App object:
>
>app.set_status(new_status_from_the_bus)
>
> In the App I have:
>
>class App():
>  ..
>  def set_status(new_status):  # Could be called from ThreadBus
>if new_status != self.new_status:
>  self.new_status = new_status
>  # Do some actions on status change
>
>  def get_status():# Could be called from ThreadIoT
>return self.status
>
> Of course, IoT object needs to know the current status of the system
> when a message is received from MQTT. So ThreadIoT could call
> app.get_status().
>
> I think this architecture has some problems with race conditions or
> threads synchronization. What happens if IoT calls get_status() exactly
> when set_status() called by ThreadBus is executing? If status is a big
> data structure, set_status() could be interrupted by get_status() that
> could get a completely corrupted status, because it was only partly
> updated by set_status().
>
> I know I can use locks or semaphores in get_status() and set_status(),
> but I don't know if this is a good approach. Consider that the system is
> complex, it isn't composed by a simple single status. It has many many
> parameters that are collected from the serial bus. Should I use a lock
> for every [get|set]_status(), [get|set]_dimensions(),
> [get|set]_battery_level(), [get|set]_mains_present(), and so on?
>
>
> Another possibility is to use a Queue for Bus and a Queue for IoT. So
> the set_status(new_status) called from Bus object will be transformed in
> a put in the queue:
>
>app_queue.put({"type": "new_status", "data": ...})
>
> However how could be transformed the get_status() from IoT? How the
> return value (the current status) is real retrieved?
>
>class IoT():
>  ..
>  def status_request_from_MQTT():
>app_queue.put({"type": "get_status"})
># How to get the status to return?
>return current_status
>
> Should the app put the status on the same queue and should IoT waits for
> a new message in the Queue?
>
>  def status_request_from_MQTT():
>app_queue.put({"type": "get_status"})
>try:
>  current_status = app_queue.get(timeout=10)
>except Empty:
>  # What to do?
>return current_status
>
>
> Again another approach is to avoid multi-threading at all and create a
> single "main loop" function that waits at the same time for incoming
> events on the serial bus and MQTT (how?). I don't know if this could be
> done in my case, because I'm using awscrt Python module and it works
> through callbacks that I think is called from another thread.
>
>
> Any suggestions on this architecture?
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 
Diego Souza
Wespa Intelligent Systems
Rio de Janeiro - Brasil
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Asynchronous execution of synchronous functions

2022-09-26 Thread Diego Souza
Did you check the ThreadPoolExecutor or the ProcessPoolExecutor? They
won't give you atomic writes unless you add a Lock or a Condition, but
they will execute your code in another thread or process.

https://docs.python.org/3/library/concurrent.futures.html#threadpoolexecutor
https://docs.python.org/3/library/concurrent.futures.html#processpoolexecutor

Keep in mind that Python's threads have a global interpreter lock
(GIL) that prevents full parallelism. Processes work as expected, but
require IPC and pickable objects in and out.

-- 
Diego Souza
Wespa Intelligent Systems
Rio de Janeiro - Brasil


On Mon, Sep 26, 2022 at 1:01 PM  wrote:
> From: Axy 
> To: Python List 
> Date: Mon, 26 Sep 2022 12:17:47 +0100
> Subject: Asynchronous execution of synchronous functions
> Hi there,
>
> is there a library to call functions in context of a thread? For
> example, as in asyncsqlite which has a thread and a queue I mean has
> anyone generalized such an approach already?
>
> If not, I'll do it myself, no problem.
>
> It's a kind of tiny stuff, like atomicwrites, which is quite difficult
> to dig out with modern search engines that have already rolled down to
> hell a decade ago.
>
> Axy.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to replace an instance method?

2022-09-21 Thread Diego Souza
Another possibility would be to use a lambda function or a callable
object. This adds an overhead but would also allow you to inject new
parameters that go into the function call. It also does not require
any extra import.

obj.old_method_name = lambda *a, **kw: new_method_name(obj, *a, **kw)

A full example goes like this:

class C:

def __init__(self):
self.value = 21

def get(self):
return self.value

def new_get(self):
return self.value * 2

obj = C()
print(obj.get())
obj.get = lambda *a, **kw: new_get(obj, *a, **kw)
print(obj.get())

This would first output 21 and then 42.

--

What you are trying to do requires more than just replacing the
function _convert_cell. By default, OpenpyxlReader loads the workbook
in read_only mode, discarding all links. This means that the cell
object present in _convert_cell has no hyperlink attribute. There is
no option to make it load the links. To force it to be loaded, we need
to replace load_workbook as well. This method asks openpyxl to load
the workbook, deciding whether it will discard the links or not.

The second problem is that as soon as you instantiate an ExcelFile
object it will instantiate an OpenpyxlReader and load the file.
Leaving you with no time to replace the functions. Happily, ExcelFile
gets the engine class from a static dictionary called _engines. This
means that we can extend OpenpyxlReader, overwrite those two methods
and replace the reference in ExcelFile._engines. The full source is:

import pandas as pd

class MyOpenpyxlReader(pd.ExcelFile.OpenpyxlReader):

def load_workbook(self, filepath_or_buffer):
from openpyxl import load_workbook
return load_workbook(
filepath_or_buffer,
read_only=False,
data_only=False,
keep_links=True
)

def _convert_cell(self, cell, convert_float: bool):
value = super()._convert_cell(cell, convert_float)
if cell.hyperlink is None:
return value
else:
return (value, cell.hyperlink.target)


pd.ExcelFile._engines["openpyxl"] = MyOpenpyxlReader
df = pd.read_excel("links.xlsx")
print(df)

The source above worked on python 3.8.10, pandas 1.5.0, and openpyxl
3.0.10. The output for a sample xlsx file with the columns id, a page
name (with links), and the last access is shown next. The first
element in the second column's output tuple is the cell's text and the
second element is the cell's link:

id
  page   last access
0   1 (google, https://www.google.com/)  2022-04-12
1   2  (gmail, https://gmail.com/)  2022-02-06
2   3  (maps, https://www.google.com/maps)  2022-02-17
3   4  (bbc, https://bbc.co.uk/)  2022-08-30
4   5 (reddit, https://www.reddit.com/)  2022-12-02
5   6(stackoverflow, https://stackoverflow.com/)  2022-05-25

--

Should you do any of this? No.

1. What makes a good developer is his ability to create clear and
maintainable code. Any of these options are clearly not clear,
increase cognitive complexity, and reduce reliability.
2. We are manipulating internal class attributes and internal methods
(those starting with _). Internal elements are not guaranteed to stay
there over different versions, even minor updates. You should not
manipulate them unless you are working on a fixed library version,
like implementing tests and checking if the internal state has
changed, hacking it, or debugging. Python assumes you will access
these attributes wisely.
3. If you are working with other developers and you commit this code
there is a huge chance another developer is using a slightly different
pandas version that misses one of these elements. You will break the
build, your team will complain and start thinking you are a naive
developer.
4. Even if you adapt your code for multiple pandas versions you will
end up with multiple ifs and different implementations. You don't want
to maintain this over time.
5. It clearly takes more time to understand pandas' internals than
writing your reader using openpyxl. It is not cumbersome, and if it
changes the execution time from 20ms to 40ms but is much more reliable
and maintainable we surely prefer the latter.

The only scenario I see in which this would be acceptable is when you
or your boss have an important presentation in the next hour, and you
need a quick fix to make it work in order to demonstrate it. After the
presentation is over and people have validated the functionality you
should properly implement it.

Keep It Simple and Stupid (KISS)

-- 
Diego Souza
Wespa Intelligent Systems
Rio de Janeiro - Brasil

On Mon, Sep 19, 2022 at 1:00 PM  wrote:
>
>
> From: "Weatherby,Gerard" 
> Date: Mon, 19 Sep 2