How do I use rx with datetime?

Since this works:

import pandas as pd
import param

from param import rx
URL = 'https://datasets.holoviz.org/penguins/v1/penguins.csv'
url = rx(URL)
df = rx(pd.read_csv)(url)
display(df)

url.rx.value = 'https://datasets.holoviz.org/gapminders/v1/gapminders.csv'

I expected:

import datetime
import param
from param import rx

tz = rx("US/Eastern")
dt = rx(datetime.datetime.now)(tz)
display(dt)

tz.rx.value = "US/Western"

This to work too, but I don’t think it changes.

Also curious about how to select a value from a widget and use it to format a float

import param
import panel as pn

format_select = pn.widgets.Select(options=["%.0f", "%.1f", "%.2f", "%.3f", "%.4f"])
output = param.rx(0.12345)

I want to do equivalent of this in rx:

import panel as pn
pn.extension()

def format_float(num, fmt):
    return f"{num:{fmt}}"


format_select = pn.widgets.Select(options=[".0f", ".1f", ".2f", ".3f", ".4f"])
output = 0.12345
pn.Column(
    format_select,
    pn.bind(format_float, output, fmt=format_select)
)

For the last one:

import param
import panel as pn


def format_float(num, fmt):
    return f"{num:{fmt}}"


format_select = pn.widgets.Select(options=[".0f", ".1f", ".2f", ".3f", ".4f"])
output = param.rx(0.12345).rx.pipe(format_float, format_select)
output
1 Like

Okay so my first impression is use pipe as the lambda for bind func

Shorter; not sure if any more readable:

import param, panel as pn

format_select = pn.widgets.Select(options=[".0f", ".1f", ".2f", ".3f", ".4f"])
param.rx(0.12345).rx.pipe((lambda n,f: f"{n:{f}}"), format_select)

For the datetime one, You are getting an error because you have a normal Python exception. Like you can’t run this datetime.datetime.now(tz="US/Eastern")

My (ugly) attempt using .rx this:

import datetime
import param
import pytz

tz = param.rx("US/Eastern")
dt = param.rx(datetime.datetime.now)(tz=param.rx(pytz.timezone)(tz))
dt

# New cell
tz.rx.value = "US/Pacific"

Is it possible to support format strings more naturally in .rx()? E.g. both of these two format strings give the same error output:

import param, panel as pn

format_select = pn.widgets.Select(options=[".0f", ".1f", ".2f", ".3f", ".4f"])
i=param.rx(0.12345)
#f"{i:{format_select}}"
f"{i:.2f}"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[20], line 6
      4 i=param.rx(0.12345)
      5 #f"{i:{format_select}}"
----> 6 f"{i:.2f}"

TypeError: unsupported format string passed to rx.__format__

Does that mean rx.__format__ could be fixed?

Same thing as len, here it must return a str

image

So TypeError: unsupported format string passed to rx.__format__ could be fixed, but it doesn’t matter, because then we’d hit TypeError: __format__ must return a str, not param.rx(). if trying to solve Andrew’s original problem? Seems like we should fix f"{i:.2f}" to work even if we can’t fix f"{i:{format_select}}".

The format_spec is passed as strings into the format argument and not the object in the scope:

F-strings definitely cannot be made to work, I’ve tried.

Would welcome some brainstorming around how we can make string formatting easier though.

1 Like

Is this doable?

a = 1
b = 2
template = rx("{a} {b}")
template.rx.format(a=a, b=b)

Or

from param import rx

a = rx(1)
b = rx(2)
template = rx("{a} {b}")
rx(template).format(a=a, b=b)

^ this seems to work initially, but changing
a.value = 3
doesn’t update

That already works but should be a.rx.value =3.

Oops! I wonder if that could be a point of confusion for panel users, e.g. used to widget.value = ... and then when switching to rx, they need to do var.rx.value = ... to set?

Would it be possible to alias var.valuevar.rx.value or warn if var.value is not an existing attr?

Yes, we should be warning on errors, which also would have shown up for your initial issue in this post.