ex4nicegui icon indicating copy to clipboard operation
ex4nicegui copied to clipboard

Weird behavior when working with numpy

Open ShannonZ opened this issue 1 year ago • 5 comments

Except for attribute bindings of UI elements that do not require the use of to_value, is it necessary to add to_value in all other places where fields are used?

from ex4nicegui import rxui,to_value
from nicegui import ui
import numpy as np

class BalanceParameter(rxui.ViewModel):
    GAstart:float = 0.0
    GAend:float = 50.0
    NG:int = 8
    GAList = []
    BAList = []
    
    def __init__(self):
        super().__init__()
        self.update_GAList()
    
    def update_GAList(self):
        print('update')
        self.GAList = np.linspace(to_value(self.GAstart),to_value(self.GAend),to_value(self.NG),endpoint=True).tolist()
        self.BAList = np.linspace(self.GAstart,self.GAend,self.NG,endpoint=True).tolist()
        print(to_value(self.GAList)) # works as expected
        print(to_value(self.BAList))  # lost the last element 
        print(self.BAList)                 # empty
p = BalanceParameter()
ui.button('Play')

rxui.number(value=p.NG,format='%d',min=1,max=100,suffix='ttt').props('standout label-color="blue" ').style('width:160px')
ui.run(port=8088)

The output:

update
[0.0, 7.142857142857143, 14.285714285714286, 21.42857142857143, 28.571428571428573, 35.714285714285715, 42.85714285714286, 50.0]
[0.0, 7.142857142857143, 14.285714285714286, 21.42857142857143, 28.571428571428573, 35.714285714285715, 42.85714285714286, <ex4nicegui.utils
.proxy.float.FloatProxy object at 0x0000027D2F226360>]
[]
NiceGUI ready to go on http://localhost:8088, http://172.16.10.175:8088, and http://192.168.0.9:8088

ShannonZ avatar Jan 03 '25 08:01 ShannonZ

@ShannonZ Question 1: I did not experience any issue with losing the last element on my side. I ran the code you provided and the output is :

update
[0.0, 7.142857142857143, 14.285714285714286, 21.42857142857143, 28.571428571428573, 35.714285714285715, 42.85714285714286, 50.0]
[0.0, 7.142857142857143, 14.285714285714286, 21.42857142857143, 28.571428571428573, 35.714285714285715, 42.85714285714286, 50.0]
[]

CrystalWindSnake avatar Jan 04 '25 07:01 CrystalWindSnake

@ShannonZ Question 2: This problem is probably caused by a bug in the proxy. rxui.ViewModel is intended to simplify the process, but if you find it confusing, you could use deep_ref instead.

The following code have the same effect.


from ex4nicegui import rxui,  deep_ref

class BalanceParameterWithRef:
    def __init__(self):
        self.GAstart = deep_ref(0.0)
        self.GAend = deep_ref(50.0)
        self.NG = deep_ref(8)
        self.GAList = deep_ref([])
        self.BAList = deep_ref([])

        self.update_GAList()

    def update_GAList(self):
        print("update")
        self.GAList.value = np.linspace(
            self.GAstart.value,
            self.GAend.value,
            self.NG.value,
            endpoint=True,
        ).tolist()
        self.BAList.value = np.linspace(
            self.GAstart.value, self.GAend.value, self.NG.value, endpoint=True
        ).tolist()
        print(self.GAList.value)
        print(self.BAList.value)


p = BalanceParameterWithRef()
ui.button("Play")

rxui.number(value=p.NG, label="个数", format="%d", min=1, max=100, suffix="ttt").props(
    'standout label-color="blue" '
).style("width:160px")

CrystalWindSnake avatar Jan 04 '25 07:01 CrystalWindSnake

@ShannonZ Question 1: I did not experience any issue with losing the last element on my side. I ran the code you provided and the output is :

update
[0.0, 7.142857142857143, 14.285714285714286, 21.42857142857143, 28.571428571428573, 35.714285714285715, 42.85714285714286, 50.0]
[0.0, 7.142857142857143, 14.285714285714286, 21.42857142857143, 28.571428571428573, 35.714285714285715, 42.85714285714286, 50.0]
[]

I'm not sure if this issue is related to the versions of these libraries.

ex4nicegui         0.8.6
nicegui            2.9.0
numpy              2.2.1

ShannonZ avatar Jan 06 '25 00:01 ShannonZ

@ShannonZ Question 2: This problem is probably caused by a bug in the proxy. rxui.ViewModel is intended to simplify the process, but if you find it confusing, you could use deep_ref instead.

The following code have the same effect.

from ex4nicegui import rxui,  deep_ref

class BalanceParameterWithRef:
    def __init__(self):
        self.GAstart = deep_ref(0.0)
        self.GAend = deep_ref(50.0)
        self.NG = deep_ref(8)
        self.GAList = deep_ref([])
        self.BAList = deep_ref([])

        self.update_GAList()

    def update_GAList(self):
        print("update")
        self.GAList.value = np.linspace(
            self.GAstart.value,
            self.GAend.value,
            self.NG.value,
            endpoint=True,
        ).tolist()
        self.BAList.value = np.linspace(
            self.GAstart.value, self.GAend.value, self.NG.value, endpoint=True
        ).tolist()
        print(self.GAList.value)
        print(self.BAList.value)


p = BalanceParameterWithRef()
ui.button("Play")

rxui.number(value=p.NG, format="%d", min=1, max=100, suffix="ttt").props(
    'standout label-color="blue" '
).style("width:160px")

After using deep_ref, this code works as expected, but it doesn't result in less code compared to using to_value. IMOO, the getters of these XXXProxy classes should be designed to be transparent to users (one feels they are using regular types). This will make the user experience more seamless and easier to promote.

ShannonZ avatar Jan 06 '25 00:01 ShannonZ

The issue of empty print output is a bug in the proxy, which will be fixed in the next version.

CrystalWindSnake avatar Jan 06 '25 05:01 CrystalWindSnake