Package hdict
Expand source code
# Copyright (c) 2023. Davi Pereira dos Santos
# This file is part of the hdict project.
# Please respect the license - more about this in the section (*) below.
#
# hdict is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# hdict is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with hdict. If not, see <http://www.gnu.org/licenses/>.
#
# (*) Removing authorship by any means, e.g. by distribution of derived
# works or verbatim, obfuscated, compiled or rewritten versions of any
# part of this work is illegal and it is unethical regarding the effort and
# time spent here.
#
from typing import TypeVar
from hdict.content.argument.apply import apply
from hdict.content.argument.field import field
from hdict.content.argument.sample import sample
from hdict.data.empty_ import Empty_
from hdict.content.value import value
from hdict.data.frozenhdict import frozenhdict
from hdict.data.hdict_ import hdict_
from hdict.data.self_ import Self_
from hdict.expression.step.cache import cache
__all__ = ["hdict", "_", "Ø", "apply", "field", "sample", "frozenhdict", "value", "cache"]
VT = TypeVar("VT")
class hdict(hdict_):
"""
Function id is reversed before application.
This is needed to enable handling a function as a value, under the original id.
>>> from hdict import hdict, apply, field
>>> from hdict.content.argument.default import default
>>> d = hdict({"x": 3}, y=5)
>>> d["alpha"] = 11
>>> d.show(colored=False)
{
x: 3,
y: 5,
alpha: 11,
_id: e6WGyTj7trk6AUUcdxGAefyG.T9j.SvBdEsHF.r5,
_ids: {
x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr,
y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
alpha: A1RyW.GoA3q9-iCbCvWyWClExm1J3wI.ok6UA3Nk
}
}
>>> d >>= {"beta": 12, "gamma": 17}
>>> d["p1", "q1"] = apply(lambda x, y=3: [x**y, x/y])
>>> d["pq"] = apply(lambda x, y=3: [x**y, x/y])
>>> d["p2", "q2"] = apply(lambda x=2, y=None: [x**y, x/y])
>>> f = lambda x, y: {"a": x**y, "b": x/y}
>>> d["z1", "w1"] = apply(f)
>>> d["z2":"a", "w2":"b"] = apply(f)
>>> d >>= {
... "r1": apply(lambda x: x**2),
... "r2": apply(lambda x: x**3),
... "r3": apply(lambda x: x**4),
... ("ra1", "rb1"): apply(f),
... (("ra2", "a"), ("rb2", "b")): apply(f),
... }
>>> d["z2"]
243
>>> d["zz1", "ww1"] = apply(f, field("r1"), y=field("r2"))
>>> d >>= {("zz2", "ww2"): apply(f, y=field("r2"), x=9)} # Define external value.
>>> d >>= {"zzzz": apply(f, y=13, x=9)}
>>> # Non-pickable custom classes need a custom 'hosh' attribute to be applied and also to be used as a value.
>>> from hosh import Hosh
>>> # Example of class that could be used as a value or as a function.
>>> from dataclasses import dataclass
>>> @dataclass
... class CustomClass:
... hosh = Hosh.fromid("Some.arbitrary.identifier.with.length.40")
... def __call__(self, x, y):
... return x + y, x / y
>>> custom = CustomClass()
>>> d["f"] = custom # Custom callable handled as a value.
>>> d["zzz1", "www1"] = apply(custom, 11, y=33) # Custom callable being applied.
>>> d["zzz2", "www2"] = apply(field("f"), field("r1"), y=44) # Callable field being applied.
>>> d.show(colored=False)
{
x: 3,
y: 5,
alpha: 11,
beta: 12,
gamma: 17,
p1: λ(x y)→0,
q1: λ(x y)→1,
pq: λ(x y),
p2: λ(x y)→0,
q2: λ(x y)→1,
z1: λ(x y)→0,
w1: λ(x y)→1,
z2: 243,
w2: λ(x y)→b,
r1: λ(x),
r2: λ(x),
r3: λ(x),
ra1: λ(x y)→0,
rb1: λ(x y)→1,
ra2: λ(x y)→a,
rb2: λ(x y)→b,
zz1: λ(x=r1 y=r2)→0,
ww1: λ(x=r1 y=r2)→1,
zz2: λ(9 y=r2)→0,
ww2: λ(9 y=r2)→1,
zzzz: λ(9 13),
f: "CustomClass()",
zzz1: λ(11 33)→0,
www1: λ(11 33)→1,
zzz2: λ(r1 44)→0,
www2: λ(r1 44)→1,
_id: i5wtTs5qggivS-y5TNuhnM5jwokjF132M7jF.49a,
_ids: {
x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr,
y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
alpha: A1RyW.GoA3q9-iCbCvWyWClExm1J3wI.ok6UA3Nk,
beta: WM5TbiaJ1gLqKRSFiY3VkZEu1PwQcaAokBKBPrWg,
gamma: yb-HU.jSxd496XfId1J..MkX7xfUPJOL1-07hHdt,
p1: Qs0J0I.AhR.brQjpYwUJqDNLk-zKd7FmG0g7gdd1,
q1: VOAVwyrrdC7eIsjnVkqdpsqUfhprKzKriATFEOQI,
pq: KtTWRcFQRKVgTJabGMgY-HAQWJ1TZGnOYw7NU.1K,
p2: qb0H0MqNit0rLwk6CsC4Q2bxpCmBQ581eoGI39sr,
q2: Sjsl-.MJJ3SK2.INLAJ-0R5BwlfG.tccIpxPFRtB,
z1: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4,
w1: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO,
z2: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4,
w2: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO,
r1: FO3NXIQIi7TBFw1FqLRJYo13EA.uu4Y-L17Fmx0z,
r2: HorxHsNCdpkm270yeTZ-vREjjFXWIYC99ALidDVU,
r3: bWc33lXvXHIJXix5Jw2.Nhw0EIsv3TuAa7t8Ix5q,
ra1: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4,
rb1: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO,
ra2: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4,
rb2: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO,
zz1: FB6W9j12qWZ34fUwyrBETzFuAXRB-xn7O1PGhr2j,
ww1: IhchjkRfjLXpnsC6zl-TFugIQrnUIdB7Wsgpnely,
zz2: LE5ohPby7q4dNu3qhqgucRcCt.pd87O.CyKWloqe,
ww2: -RBf-UiccAG3sTH0UFC6C.YFmYcpTRA.0PFP6Oun,
zzzz: Irbj-xVP8rEIPoylOTNmiuJ-lGdx0dpzIPgq-169,
f: Some.arbitrary.identifier.with.length.40,
zzz1: TBw0fUZZo1WlI9uczNuF0w4vC06u6YvzJyNPVEi1,
www1: WqqXpIpMwinaXxYNqRjj4qttDcKXN.gcGjARpOSh,
zzz2: .mJim0y-LMUYZi01GN8MTPkHj79JtFdREf7g40ug,
www2: jwtsaf1IZMG6sWqprXZnc.n-ilyfncwhL3Qr.-Md
}
}
>>> d["p1"]
243
>>> from hdict import value
>>> d.evaluate()
>>> d = hdict(x=2)
>>> g = lambda x, y: [x + y, x / y]
>>> d["z"] = apply(f, 2, y=3)
>>> d["w", "v"] = apply(f, field("x"), y=33)
>>> d["f"] = f
>>> d = d >> apply(field("f"), field("x"), y=default(3), nonexistent_parameter=7)("w3", "v3") # todo: : nonexistent parameter should raise an exception
>>> d >>= apply(field("f"), field("x"), y=default(3))("w", "v")
>>> d["w2", "v2"] = apply(field("f"), field("x"), y=default(3))
>>> d >>= {"z": apply(f, field("x"), y=3), ("w", "v"): apply(g, y=7)}
>>> d >>= apply(f, field("x"), y=3)("z9") * apply(g, y=7)("w9", "v9")
>>> pp = apply(f, field("x"), y=3)("z") >> apply(g, y=7)("w", "v")
>>> d >>= {"x": 3} >> pp >> apply(g, y=7)("w", "v")
>>> from hdict import _
>>> a1 = apply(f, y=_(1, 2, 4, ..., 128))
>>> a2 = apply(f, _(0, 3, 6, ..., 9), y=_(0, 3, 6, ..., 9))
>>> ppp = hdict() >> a2.sample()("k", "t")
>>> ppp.show(colored=False)
{
k: λ(9 9)→0,
t: λ(9 9)→1,
_id: dK-iumb4L5nkFVT9LCkdk3daQtuC.ORk6JwWMhnt,
_ids: {
k: rHTgwW.w2SsbcvBlSnWWddLH4vgyXlM1Fhxqr48f,
t: IldA8m-uSN9lJcE4TBtjTcY-sSiA33mzxQ2k-wpN
}
}
>>> ppp.k
387420489
>>> a1("z")
z=λ(x y=~[1 2 .*. 128])
>>> a2(w="a", v="b")
(('w', 'a'), ('v', 'b'))=λ(x=~[0 3 .+. 9] y=~[0 3 .+. 9])
>>> p = a1("z") >> a2(w="a", v="b")
>>> h = lambda a, b=4: 5
>>> app = apply(h, a=_(0, 3, 6, ..., 9))
>>> app
λ(a=~[0 3 .+. 9] b=default(4))
>>> app.c
c=λ(a=~[0 3 .+. 9] b=default(4))
>>> sampled = app.sample(0).c
>>> sampled
c=λ(9 b=default(4))
>>> r = hdict() >> sampled
>>> r.show(colored=False)
{
c: λ(9 b=4),
_id: Bbe5mzn0oCuHZ.Y84-jaEnh3jcrgD8av6IZezKEG,
_ids: {
c: 6EehD7OoZe2REI.1YsVLKxSF4hJoYxfOZJLbF.Aj
}
}
>>> r.evaluated.show(colored=False)
{
c: 5,
_id: Bbe5mzn0oCuHZ.Y84-jaEnh3jcrgD8av6IZezKEG,
_ids: {
c: 6EehD7OoZe2REI.1YsVLKxSF4hJoYxfOZJLbF.Aj
}
}
>>> from random import Random
>>> rnd = Random(0)
>>> p1 = p.sample(rnd)
>>> d["w"]
10
>>> d >>= p1
>>> d["z"] = apply(f, 2, y=3)
>>> d["w", "v"] = apply(f, _.x, y=_.x)
>>> d["w", "v"] = apply(_.f, _.x, y=default(3))
>>> d = hdict() >> {"z": apply(f, 7, y=3), ("w", "v"): apply(g, default(6), y=7)}
>>> d = hdict(w=6) >> (apply(f, _["w"], y=3)(z="z") >> apply(g, x=_(1,2,3,...,5), y=7)("ww", "v")).sample(0)
>>> p = apply(f, y=_(1, 2, 4, ..., 128))("z") >> apply(f, y=_(0, 3, 6, ..., 9))(w="a", v="b")
>>> d.show(colored=False)
{
w: 6,
z: λ(x=w 3)→z,
ww: λ(4 7)→0,
v: λ(4 7)→1,
_id: x4TxaVuAymsh97Yr.15Oc1ekllvlpECk091124RM,
_ids: {
w: CZ7Jm5fQMZ3fZJ3kAVOi0FYK-exFqPqgoYLsGxGl,
z: No1nN40OXnJ.zOyAvoxwCjyD06cUDiXTZQh4q8xa,
ww: qZepp.wpXCOYQrwnVIwoZ4kR9pIuMGDQpvRevv80,
v: wxkjBSP54cKEfxKE1Zte-2dDll3G9Nd-yDh3CLas
}
}
>>> d = hdict(x=3) >> p.sample(rnd)
>>> d.show(colored=False)
{
x: 3,
z: λ(x 16),
w: λ(x 9)→a,
v: λ(x 9)→b,
_id: 22b-e.CtRGVSoMkektNzHYSVZTouhL2jAHLyPd4Q,
_ids: {
x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr,
z: 64cxw0HmJ0fydH7By6i0HrbuwA759XexTu3Bu0Zd,
w: p1Z5umNo12DHCZtKbh2EClW6TZxv.M447HlALWhv,
v: HbYbR1RjPdU4jixjW7xSxslRpYx9W6Oiay7maK6F
}
}
>>> d1 = hdict(x=52, y=13)
>>> d2 = hdict(x=value(52, hosh="1234567890123456789012345678901234567890"))
>>> d1.show(colored=False)
{
x: 52,
y: 13,
_id: 5pwGP0LxQRbQaDEk9ztQ4V4qz.A-IIhVNTrcyt8U,
_ids: {
x: c.llz05T6ZXw5AlsU4xfmMxcvvHZhLl60LckZis9,
y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s
}
}
>>> d2.show(colored=False)
{
x: 52,
_id: kYzgpPdRgQSYSEpp1qt4EHQLQJXuyb2WDQS-iNPh,
_ids: {
x: 1234567890123456789012345678901234567890
}
}
>>> d3 = d1 >> d2
>>> d3.show(colored=False)
{
x: 52,
y: 13,
_id: -EFuy5NAeK.LIALpBiZKK-fYQmc9AZYQQck-HiRK,
_ids: {
x: 1234567890123456789012345678901234567890,
y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s
}
}
>>> (d3 >> d1.frozen).show(colored=False)
{
x: 52,
y: 13,
_id: 5pwGP0LxQRbQaDEk9ztQ4V4qz.A-IIhVNTrcyt8U,
_ids: {
x: c.llz05T6ZXw5AlsU4xfmMxcvvHZhLl60LckZis9,
y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s
}
}
>>> d = hdict(x=2, y=4)
>>> {"x": 2, "y": 4} == d.frozen
True
>>> {"x": 2, "y": 4} == d
True
>>> d == {"x": 2, "y": 4}
True
>>> dict(d)
{'x': 2, 'y': 4}
>>> hdict() >> {"x": 3} == {"x": 3}
True
>>> {"x": 3, "d": {"x": 7}} == hdict(x=3, d=hdict(x=7))
True
>>> hdict(x=3, d=hdict(x=7)) == {"x": 3, "d": {"x": 7}}
True
>>> {"x": 3, "_id": hdict(x=3).id} == hdict(x=3)
True
>>> hdict(x=3) == {"x": 3, "_id": hdict(x=3).id}
True
>>> hdict(x=3) == hdict(x=3)
True
>>> hdict(x=3).frozen == hdict(x=3)
True
>>> hdict(x=3) != {"x": 4}
True
>>> hdict(x=3) != hdict(x=4)
True
>>> hdict(x=3).frozen != hdict(x=4)
True
>>> hdict(x=3) != {"y": 3}
True
>>> hdict(x=3) != {"x": 3, "_id": (~hdict(x=3).hosh).id}
True
>>> hdict(x=3) != hdict(y=3)
True
>>> del d["x"]
>>> list(d)
['y']
>>> e = d >> apply(lambda y: y*7)("y")
>>> from hdict.content.aux_value import f2hosh
>>> print(f2hosh(lambda y: y*7))
54YCMDJIlsIvMQ.KJtT-vFyjg83Zgfj2xSHOgCj8
>>> print(e)
{y: "λ(4)"}
>>> e.evaluate()
>>> print(e)
{y: 28}
>>> d = d >> apply(lambda y=1: y*7, fhosh="54YCMDJIlsIvMQ.KJtT-vFyjg83Zgfj2xSHOgCj8")("y")
>>> print(d)
{y: "λ(4)"}
>>> d.evaluate()
>>> print(d)
{y: 28}
>>> hash(e.frozen) == hash(d.frozen)
True
>>> d = hdict(a=5) >> hdict(y=28)
>>> d.show(colored=False)
{
a: 5,
y: 28,
_id: C-xKyWCyBL6g32KIuxoANoF9czLaJTh-emPsMqOg,
_ids: {
a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9
}
}
>>> d >>= apply(lambda a: a)("x")
>>> d.show(colored=False)
{
a: 5,
y: 28,
x: λ(a),
_id: qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY,
_ids: {
a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9,
x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp
}
}
>>> {"_id": "qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY"} == d
True
>>> d.show(colored=False)
{
a: 5,
y: 28,
x: λ(a),
_id: qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY,
_ids: {
a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9,
x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp
}
}
>>> def f():
... print("busy")
... return 23
>>> storage = {}
>>> d >>= apply(f).o >> cache(storage, "x", "y")
>>> d.y
28
>>> d.show(colored=False)
{
a: 5,
y: 28,
x: ↑↓ cached at `dict`·,
o: λ(),
_id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv,
_ids: {
a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9,
x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp,
o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo
}
}
>>> d.evaluated.show(colored=False)
busy
{
a: 5,
y: 28,
x: 5,
o: 23,
_id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv,
_ids: {
a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9,
x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp,
o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo
}
}
>>> d.evaluated.show(colored=False)
{
a: 5,
y: 28,
x: 5,
o: 23,
_id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv,
_ids: {
a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9,
x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp,
o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo
}
}
"""
class Empty(Empty_):
"""
>>> from hdict import _
>>> d = _ >> {"x": 5} >> dict(y=7)
>>> type(+_), type(d)
(<class 'hdict.Empty'>, <class 'hdict.hdict'>)
>>> d.show(colored=False)
{
x: 5,
y: 7,
_id: A0G3Y7KNMLihDvpSJ3tB.zxshc6u1CbbiiYjCAAA,
_ids: {
x: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2,
y: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf
}
}
"""
class Self(Self_):
""""""
Ø = empty = Empty()
_ = Self()
Sub-modules
hdict.abs
hdict.content
hdict.data
hdict.dataset
hdict.expression
hdict.persistence
hdict.text
Classes
class apply (appliable: callable | apply | field, *applied_args, fhosh: Hosh = None, **applied_kwargs)
-
Function application
Single output application is defined by attribute: 'apply(f).my_output_field'. Multioutput application is defined by a call: 'apply(f)("output_field1", "output_field2")'.
>>> from hdict import apply, value, frozenhdict, _ >>> f = lambda a, b: a**b >>> v = apply(f, 5, b=7) >>> v λ(5 7) >>> g = lambda x, y: x**y >>> apply(g, y=value(7777), x=v) λ(x=λ(5 7) 7777)
>>> v2 = apply(f, a=v, b=value(7)) >>> v2 λ(a=λ(5 7) 7) >>> v.enclosure({}, "j", None).value 78125 >>> v2.enclosure({}, "j", None) λ(a=λ(5 7) 7) >>> v2.enclosure({}, "j", None).value 17763568394002504646778106689453125
>>> f = lambda a,b, c=1,d=2,e=13: 0 >>> apply(f).requirements {'a': field(a), 'b': field(b), 'c': default(1), 'd': default(2), 'e': default(13)} >>> ap = apply(f,3) >>> ap.requirements {'a': 3, 'b': field(b), 'c': default(1), 'd': default(2), 'e': default(13)} >>> ap λ(3 b c=default(1) d=default(2) e=default(13)) >>> ap.enclosure({"b": value(77)}, "j", None) λ(3 b c=1 d=2 e=13) >>> ap λ(3 b c=default(1) d=default(2) e=default(13)) >>> d = {"f": ap, "b": 5, "d": 1, "e": field("b")} >>> d {'f': λ(3 b c=default(1) d=default(2) e=default(13)), 'b': 5, 'd': 1, 'e': field(b)} >>> from hdict.data.aux_frozendict import handle_items >>> handle_items(d, previous=frozenhdict({"b": 5})) {'b': 5, 'f': λ(3 b c=1 d=2 e=13), 'd': 1, 'e': 5} >>> d {'f': λ(3 b c=default(1) d=default(2) e=default(13)), 'b': 5, 'd': 1, 'e': field(b)} >>> apply(f,3,4).requirements {'a': 3, 'b': 4, 'c': default(1), 'd': default(2), 'e': default(13)} >>> apply(f,3,4,5).requirements {'a': 3, 'b': 4, 'c': 5, 'd': default(2), 'e': default(13)} >>> apply(f,3,4,5,6).requirements {'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': default(13)} >>> apply(f,3,4,5,6,7).requirements {'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 7} >>> apply(f,d=5).requirements {'a': field(a), 'b': field(b), 'c': default(1), 'd': 5, 'e': default(13)} >>> f = lambda a,b, *arg, c=1,d=2,e=13, **kwargs: 0 >>> apply(f,3,4,5,6,7,8).requirements {'a': 3, 'b': 4, arg_2: 5, arg_3: 6, arg_4: 7, arg_5: 8, 'c': default(1), 'd': default(2), 'e': default(13)} >>> apply(f,x=3,e=4,d=5,c=6,b=7,a=8).requirements {'a': 8, 'b': 7, 'c': 6, 'd': 5, 'e': 4, 'x': 3} >>> apply(f,3,c=77,x=5).requirements {'a': 3, 'b': field(b), 'c': 77, 'd': default(2), 'e': default(13), 'x': 5} >>> apply(f,b=77,x=5).requirements {'a': field(a), 'b': 77, 'c': default(1), 'd': default(2), 'e': default(13), 'x': 5} >>> from hdict.content.argument.entry import entry >>> a = apply(lambda x: x.value * 7, x=entry("x")) >>> c = {"x": 3, "y": entry("x")} >> a.r >>> c.show(colored=False) { x: 3, y: ·3, r: λ(·x), _id: bh0bgTZI.2f-WteZFpIrsMxJvZYUBydOfF3wFLV., _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, r: NoAit6.-dyFNiCZnoRAhY5zbJ0hc6u5lkQzYwBCx } } >>> b = a.x.sample() >>> b x=λ(·x) >>> d = {"x": 3} >> b >>> d.x 21 >>> a.sampleable False >>> a.sample() λ(·x) >>> d["h"] = frozenhdict(a=2) >>> d.show(colored=False) { x: 21, h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, _id: V8nyMrJbhGschQAaW3ZXD6uxvVRIluFmIFIkSaZ0, _ids: { x: NoAit6.-dyFNiCZnoRAhY5zbJ0hc6u5lkQzYwBCx, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd } } >>> a = apply(lambda x: x.value * 7).x >>> d >>= a >>> d.show(colored=False) { x: λ(x=21), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, _id: okwLxwrcv9.FCsOTgCrB0ZG0yBArMbEaeqXNIGa7, _ids: { x: H8Tgrs3lS78y7Nqm0Qaaks8JLygevb49SEOpn5QD, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd } } >>> a = apply(lambda x: x.value * 7, entry("x")).x >>> d >>= a >>> d.show(colored=False) { x: λ(λ(x=21)), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, _id: ZAozaV7y5Z1cjwzR9XoiBggegMtt9VC-Leafzaod, _ids: { x: Hqq4pKtqmIAejPzyjEf6BixYtzWYVU2Znp1TdB1K, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd } } >>> d >>= {"b" : 2, "c": entry("b")} >>> d.show(colored=False) { x: λ(λ(x=21)), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, b: 2, c: ·2, _id: 9bTAxQR8bR-XsqVTjc7sLgCvTXoJCWXwRS6pNLHe, _ids: { x: Hqq4pKtqmIAejPzyjEf6BixYtzWYVU2Znp1TdB1K, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, b: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29, c: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } } >>> d >>= {"b" : (2, 3), ("a1", "b1"): [0, 1]} >>> d >>= {("a2", "b2"): _.b} >>> d >>= {("a3", "b3"): entry("b")} >>> d.show(colored=False) # todo: : improve output for subvalues (and backtracking in general for pointer-like entries) { x: λ(λ(x=21)), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, b: [ 2, 3 ], c: ·2, a1: 0, b1: 1, a2: "(2, 3)→0", b2: "(2, 3)→1", a3: ·(2, 3)→0, b3: ·(2, 3)→1, _id: gf.QcPTyypNvMcSEMveLdLVC2T218MgepHPb9Md4, _ids: { x: Hqq4pKtqmIAejPzyjEf6BixYtzWYVU2Znp1TdB1K, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, b: -a.WUGANQp6aVgbRCtUljlgs12HNtJ-dJOAgSZWk, c: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29, a1: M7HyZUgSF.ZSmBEMFcDkiZBQz00wU9pGF3DoRiDu, b1: DYu5bfVvb6FOhBCWNsss4wsEWHZYTbKnsVgoWFvl, a2: GfnITQ6RdDtm4F-F0UuU8fOJX1DZIBZG5RWBM8wm, b2: QznFPbiCaMRZKUoFhdLxMKYQf3ujIe1zDl9G5Rq-, a3: GfnITQ6RdDtm4F-F0UuU8fOJX1DZIBZG5RWBM8wm, b3: QznFPbiCaMRZKUoFhdLxMKYQf3ujIe1zDl9G5Rq- } }
Expand source code
class apply(AbsBaseArgument): """ Function application Single output application is defined by attribute: 'apply(f).my_output_field'. Multioutput application is defined by a call: 'apply(f)("output_field1", "output_field2")'. >>> from hdict import apply, value, frozenhdict, _ >>> f = lambda a, b: a**b >>> v = apply(f, 5, b=7) >>> v λ(5 7) >>> g = lambda x, y: x**y >>> apply(g, y=value(7777), x=v) λ(x=λ(5 7) 7777) >>> v2 = apply(f, a=v, b=value(7)) >>> v2 λ(a=λ(5 7) 7) >>> v.enclosure({}, "j", None).value 78125 >>> v2.enclosure({}, "j", None) λ(a=λ(5 7) 7) >>> v2.enclosure({}, "j", None).value 17763568394002504646778106689453125 >>> f = lambda a,b, c=1,d=2,e=13: 0 >>> apply(f).requirements {'a': field(a), 'b': field(b), 'c': default(1), 'd': default(2), 'e': default(13)} >>> ap = apply(f,3) >>> ap.requirements {'a': 3, 'b': field(b), 'c': default(1), 'd': default(2), 'e': default(13)} >>> ap λ(3 b c=default(1) d=default(2) e=default(13)) >>> ap.enclosure({"b": value(77)}, "j", None) λ(3 b c=1 d=2 e=13) >>> ap λ(3 b c=default(1) d=default(2) e=default(13)) >>> d = {"f": ap, "b": 5, "d": 1, "e": field("b")} >>> d {'f': λ(3 b c=default(1) d=default(2) e=default(13)), 'b': 5, 'd': 1, 'e': field(b)} >>> from hdict.data.aux_frozendict import handle_items >>> handle_items(d, previous=frozenhdict({"b": 5})) {'b': 5, 'f': λ(3 b c=1 d=2 e=13), 'd': 1, 'e': 5} >>> d {'f': λ(3 b c=default(1) d=default(2) e=default(13)), 'b': 5, 'd': 1, 'e': field(b)} >>> apply(f,3,4).requirements {'a': 3, 'b': 4, 'c': default(1), 'd': default(2), 'e': default(13)} >>> apply(f,3,4,5).requirements {'a': 3, 'b': 4, 'c': 5, 'd': default(2), 'e': default(13)} >>> apply(f,3,4,5,6).requirements {'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': default(13)} >>> apply(f,3,4,5,6,7).requirements {'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 7} >>> apply(f,d=5).requirements {'a': field(a), 'b': field(b), 'c': default(1), 'd': 5, 'e': default(13)} >>> f = lambda a,b, *arg, c=1,d=2,e=13, **kwargs: 0 >>> apply(f,3,4,5,6,7,8).requirements {'a': 3, 'b': 4, arg_2: 5, arg_3: 6, arg_4: 7, arg_5: 8, 'c': default(1), 'd': default(2), 'e': default(13)} >>> apply(f,x=3,e=4,d=5,c=6,b=7,a=8).requirements {'a': 8, 'b': 7, 'c': 6, 'd': 5, 'e': 4, 'x': 3} >>> apply(f,3,c=77,x=5).requirements {'a': 3, 'b': field(b), 'c': 77, 'd': default(2), 'e': default(13), 'x': 5} >>> apply(f,b=77,x=5).requirements {'a': field(a), 'b': 77, 'c': default(1), 'd': default(2), 'e': default(13), 'x': 5} >>> from hdict.content.argument.entry import entry >>> a = apply(lambda x: x.value * 7, x=entry("x")) >>> c = {"x": 3, "y": entry("x")} >> a.r >>> c.show(colored=False) { x: 3, y: ·3, r: λ(·x), _id: bh0bgTZI.2f-WteZFpIrsMxJvZYUBydOfF3wFLV., _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, r: NoAit6.-dyFNiCZnoRAhY5zbJ0hc6u5lkQzYwBCx } } >>> b = a.x.sample() >>> b x=λ(·x) >>> d = {"x": 3} >> b >>> d.x 21 >>> a.sampleable False >>> a.sample() λ(·x) >>> d["h"] = frozenhdict(a=2) >>> d.show(colored=False) { x: 21, h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, _id: V8nyMrJbhGschQAaW3ZXD6uxvVRIluFmIFIkSaZ0, _ids: { x: NoAit6.-dyFNiCZnoRAhY5zbJ0hc6u5lkQzYwBCx, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd } } >>> a = apply(lambda x: x.value * 7).x >>> d >>= a >>> d.show(colored=False) { x: λ(x=21), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, _id: okwLxwrcv9.FCsOTgCrB0ZG0yBArMbEaeqXNIGa7, _ids: { x: H8Tgrs3lS78y7Nqm0Qaaks8JLygevb49SEOpn5QD, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd } } >>> a = apply(lambda x: x.value * 7, entry("x")).x >>> d >>= a >>> d.show(colored=False) { x: λ(λ(x=21)), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, _id: ZAozaV7y5Z1cjwzR9XoiBggegMtt9VC-Leafzaod, _ids: { x: Hqq4pKtqmIAejPzyjEf6BixYtzWYVU2Znp1TdB1K, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd } } >>> d >>= {"b" : 2, "c": entry("b")} >>> d.show(colored=False) { x: λ(λ(x=21)), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, b: 2, c: ·2, _id: 9bTAxQR8bR-XsqVTjc7sLgCvTXoJCWXwRS6pNLHe, _ids: { x: Hqq4pKtqmIAejPzyjEf6BixYtzWYVU2Znp1TdB1K, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, b: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29, c: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } } >>> d >>= {"b" : (2, 3), ("a1", "b1"): [0, 1]} >>> d >>= {("a2", "b2"): _.b} >>> d >>= {("a3", "b3"): entry("b")} >>> d.show(colored=False) # todo: : improve output for subvalues (and backtracking in general for pointer-like entries) { x: λ(λ(x=21)), h: { a: 2, _id: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, _ids: { a: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29 } }, b: [ 2, 3 ], c: ·2, a1: 0, b1: 1, a2: "(2, 3)→0", b2: "(2, 3)→1", a3: ·(2, 3)→0, b3: ·(2, 3)→1, _id: gf.QcPTyypNvMcSEMveLdLVC2T218MgepHPb9Md4, _ids: { x: Hqq4pKtqmIAejPzyjEf6BixYtzWYVU2Znp1TdB1K, h: GfMhwM5bo6OzIpngAf8Ruro6.QgOv2kb0nbj0mgd, b: -a.WUGANQp6aVgbRCtUljlgs12HNtJ-dJOAgSZWk, c: k3PWYRxIEc0lEvD1f6rbnk.36RAD5AyfROy1aT29, a1: M7HyZUgSF.ZSmBEMFcDkiZBQz00wU9pGF3DoRiDu, b1: DYu5bfVvb6FOhBCWNsss4wsEWHZYTbKnsVgoWFvl, a2: GfnITQ6RdDtm4F-F0UuU8fOJX1DZIBZG5RWBM8wm, b2: QznFPbiCaMRZKUoFhdLxMKYQf3ujIe1zDl9G5Rq-, a3: GfnITQ6RdDtm4F-F0UuU8fOJX1DZIBZG5RWBM8wm, b3: QznFPbiCaMRZKUoFhdLxMKYQf3ujIe1zDl9G5Rq- } } """ _sampleable, isfield, _requirements = None, False, None def __init__(self, appliable: callable | apply | field, *applied_args, fhosh: Hosh = None, _sampleable=None, **applied_kwargs): from hdict.content.argument.aux_apply import handle_args self.appliable = appliable if isinstance(fhosh, str): # pragma: no cover fhosh = Hosh.fromid(fhosh) if isinstance(appliable, apply): # "clone" mode self.fhosh = fhosh or appliable.fhosh self.fargs, self.fkwargs = appliable.fargs.copy(), appliable.fkwargs.copy() self.isfield = appliable.isfield self._sampleable = appliable.sampleable if _sampleable is None else _sampleable self.appliable = appliable.appliable elif isinstance(appliable, field): # todo: : o que era isso mesmo?:: "function will be provided by hdict"-mode constrains 'applied_args' self.fhosh = fhosh self.fargs, self.fkwargs = handle_args(None, applied_args, applied_kwargs) self.isfield = True self._sampleable = _sampleable elif callable(appliable): if not ( isfunction(appliable) or isbuiltin(appliable) or isclass(appliable) ): # "not function" means "custom callable"; `builtin_function_or_method` is not a function and does not allow signature extraction. if not hasattr(appliable, "__call__"): # pragma: no cover raise Exception(f"Cannot infer method to apply non custom callable type '{type(appliable).__name__}'.") if not hasattr(appliable, "hosh"): # pragma: no cover raise Exception(f"Missing 'hosh' attribute while applying custom callable class '{type(appliable).__name__}'") # noinspection PyUnresolvedReferences sig = signature(appliable.__call__) # noinspection PyUnresolvedReferences self.fhosh = fhosh or appliable.hosh else: self.fhosh = f2hosh(appliable) if fhosh is None else fhosh s = str(appliable) if s.startswith("<built-in function"): if s.endswith("getattr>"): self.appliable = appliable = getattr_ sig = signature(appliable) # Separate positional parameters from named parameters looking at 'f' signature. self.fargs, self.fkwargs = handle_args(sig, applied_args, applied_kwargs) self._sampleable = _sampleable else: # pragma: no cover raise Exception(f"Cannot apply type '{type(appliable).__name__}'.") @property def sampleable(self): if self._sampleable is None: gen = (req.sampleable for req in self.fargs.values()) kwgen = (req.sampleable for req in self.fkwargs.values()) self._sampleable = any(gen) or any(kwgen) return self._sampleable @property def ahosh(self): return self.fhosh.rev # 'f' identified as an appliable function def clone(self, _sampleable=None): return apply(self, _sampleable=_sampleable) def sample(self, rnd: int | Random = None): if not self.sampleable: return self clone = self.clone(_sampleable=False) for k, v in clone.fargs.items(): clone.fargs[k] = v.sample(rnd) for k, v in clone.fkwargs.items(): clone.fkwargs[k] = v.sample(rnd) return clone def enclosure(self, data, key, previous): from hdict.content.entry.closure import Closure return Closure(self, data, [key], previous) def __call__(self, *out, **kwout): from hdict.expression.step.applyout import ApplyOut if not (out or kwout): # pragma: no cover raise Exception(f"At least one output field must be specified to apply.") if out and kwout: # pragma: no cover raise Exception(f"Cannot mix translated (**kwargs) and non translated (*args) outputs.") if len(out) == 1: out = out[0] return ApplyOut(self, out or tuple(kwout.items())) def __getattr__(self, item): # REMINDER: Work around getattribute missing all properties. if item not in ["ahosh", "requirements", "hosh"]: from hdict.expression.step.applyout import ApplyOut return ApplyOut(self, item) return self.__getattribute__(item) # pragma: no cover def __rshift__(self, other): # pragma: no cover raise Exception(f"Cannot pipeline an application before specifying the output field.") def __rrshift__(self, other): # pragma: no cover raise Exception(f"Cannot apply before specifying the output field.") def __mul__(self, other): # pragma: no cover raise Exception(f"Cannot pipeline an application before specifying the output field.") def __rmul__(self, other): # pragma: no cover raise Exception(f"Cannot apply before specifying the output field.") def __repr__(self): from hdict.content.value import value from hdict.content.argument.entry import entry lst = [] for param, content in sorted(chain(self.fargs.items(), self.fkwargs.items())): match content: case field(name=param): lst.append(f"{param}") case entry(name=param): lst.append(repr(content)) case value(): lst.append(truncate(repr(content), width=7)) case AbsArgument(): lst.append(f"{param}={repr(content)}") case _: # pragma: no cover raise Exception(f"Canoot repr `{type(content)}") return f"λ({' '.join(lst)})" @property def requirements(self): if self._requirements is None: self._requirements = {k: v for k, v in sorted(chain(self.fargs.items(), self.fkwargs.items()))} return self._requirements
Ancestors
Class variables
var isfield
Instance variables
var ahosh
-
Expand source code
@property def ahosh(self): return self.fhosh.rev # 'f' identified as an appliable function
var requirements
-
Expand source code
@property def requirements(self): if self._requirements is None: self._requirements = {k: v for k, v in sorted(chain(self.fargs.items(), self.fkwargs.items()))} return self._requirements
var sampleable
-
bool(x) -> bool
Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
Expand source code
@property def sampleable(self): if self._sampleable is None: gen = (req.sampleable for req in self.fargs.values()) kwgen = (req.sampleable for req in self.fkwargs.values()) self._sampleable = any(gen) or any(kwgen) return self._sampleable
Methods
def clone(self)
-
Expand source code
def clone(self, _sampleable=None): return apply(self, _sampleable=_sampleable)
def enclosure(self, data, key, previous)
-
Expand source code
def enclosure(self, data, key, previous): from hdict.content.entry.closure import Closure return Closure(self, data, [key], previous)
def sample(self, rnd: int | Random = None)
-
Expand source code
def sample(self, rnd: int | Random = None): if not self.sampleable: return self clone = self.clone(_sampleable=False) for k, v in clone.fargs.items(): clone.fargs[k] = v.sample(rnd) for k, v in clone.fkwargs.items(): clone.fkwargs[k] = v.sample(rnd) return clone
class cache (storage: dict, *fields)
-
>>> from hdict import _, hdict, cache, apply >>> storage = {} >>> d = hdict(x=3, y=5) >> apply(lambda x, y: x / y).z >>> d.show(colored=False) { x: 3, y: 5, z: λ(x y), _id: IIh20mb2BGUx9XMCDwzTr4y7v-JaGin3eEHvx692, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: GC-BMZNVRagHxgUynUadKUYA1kZ8GzcUj6OKWstQ } } >>> d >>= cache(storage) >>> d.show(colored=False) { x: 3, y: 5, z: ↑↓ cached at <code>dict</code>·, _id: IIh20mb2BGUx9XMCDwzTr4y7v-JaGin3eEHvx692, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: GC-BMZNVRagHxgUynUadKUYA1kZ8GzcUj6OKWstQ } } >>> d.evaluate() >>> d.show(colored=False) { x: 3, y: 5, z: 0.6, _id: IIh20mb2BGUx9XMCDwzTr4y7v-JaGin3eEHvx692, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: GC-BMZNVRagHxgUynUadKUYA1kZ8GzcUj6OKWstQ } }
Expand source code
class cache(AbsStep): """ >>> from hdict import _, hdict, cache, apply >>> storage = {} >>> d = hdict(x=3, y=5) >> apply(lambda x, y: x / y).z >>> d.show(colored=False) { x: 3, y: 5, z: λ(x y), _id: IIh20mb2BGUx9XMCDwzTr4y7v-JaGin3eEHvx692, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: GC-BMZNVRagHxgUynUadKUYA1kZ8GzcUj6OKWstQ } } >>> d >>= cache(storage) >>> d.show(colored=False) { x: 3, y: 5, z: ↑↓ cached at `dict`·, _id: IIh20mb2BGUx9XMCDwzTr4y7v-JaGin3eEHvx692, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: GC-BMZNVRagHxgUynUadKUYA1kZ8GzcUj6OKWstQ } } >>> d.evaluate() >>> d.show(colored=False) { x: 3, y: 5, z: 0.6, _id: IIh20mb2BGUx9XMCDwzTr4y7v-JaGin3eEHvx692, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: GC-BMZNVRagHxgUynUadKUYA1kZ8GzcUj6OKWstQ } } """ def __init__(self, storage: dict, *fields): self.storage = storage self.fields = fields def __repr__(self): return f"↑↓`{type(self.storage).__name__}`"
Ancestors
class field (name: str)
-
Pointer to a field, without knowing the concrete value yet
>>> from hdict import Ø, _, apply >>> d = Ø >>> d.show(colored=False) { _id: 0000000000000000000000000000000000000000, _ids: {} } >>> d = +_ >>> d.show(colored=False) { _id: 0000000000000000000000000000000000000000, _ids: {} } >>> d >>= {"x": 3, "y": 5} >> apply(lambda x, y: x + y).z >>> d.show(colored=False) { x: 3, y: 5, z: λ(x y), _id: ..SSoOQF.FYZDUevP1CGj0DJVc.M8cgimN70yI3C, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 3j029VhuvENAnBK6JLRGl8ePpsQybm57sXKfX2oo } } >>> d >>= {"x": 3, "y": 5} >> apply(lambda x, y: x + y).x >>> d.x 8 >>> d["x"] = apply(lambda x, y: x + y) >>> d.x 13
Expand source code
@dataclass class field(AbsBaseArgument): """ Pointer to a field, without knowing the concrete value yet >>> from hdict import Ø, _, apply >>> d = Ø >>> d.show(colored=False) { _id: 0000000000000000000000000000000000000000, _ids: {} } >>> d = +_ >>> d.show(colored=False) { _id: 0000000000000000000000000000000000000000, _ids: {} } >>> d >>= {"x": 3, "y": 5} >> apply(lambda x, y: x + y).z >>> d.show(colored=False) { x: 3, y: 5, z: λ(x y), _id: ..SSoOQF.FYZDUevP1CGj0DJVc.M8cgimN70yI3C, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 3j029VhuvENAnBK6JLRGl8ePpsQybm57sXKfX2oo } } >>> d >>= {"x": 3, "y": 5} >> apply(lambda x, y: x + y).x >>> d.x 8 >>> d["x"] = apply(lambda x, y: x + y) >>> d.x 13 """ name: str def __repr__(self): return f"field({self.name})"
Ancestors
Class variables
var name : str
class frozenhdict (**kwargs)
-
Immutable hdict.
Any nested 'hdict' value will be frozen to avoid inconsistency between the hdict id (inner id) and the frozenhdict id (outer id).
>>> from hdict import frozenhdict, hdict >>> d = frozenhdict({"x": 3}, y=5) >>> from hosh._internals_appearance import decolorize >>> print(decolorize(repr(d))) # This is equivalent to just 'd', without colors. { x: 3, y: 5, _id: r5A2Mh6vRRO5rxi5nfXv1myeguGSTmqHuHev38qM, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2 } } >>> bool(d), bool(frozenhdict()) (True, False) >>> d.data {'x': 3, 'y': 5} >>> from hdict import _, apply >>> d *= apply(lambda v, x: v - x).z >>> str(d) '⦑{x: 3, y: 5} » z=λ(v x)⦒' >>> d.show(colored=False) ⦑{ x: 3, y: 5, _id: r5A2Mh6vRRO5rxi5nfXv1myeguGSTmqHuHev38qM, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2 } } » z=λ(v x)⦒ >>> d = {"v": 7} * d >>> d.solve().show(colored=False) { v: 7, x: 3, y: 5, z: λ(v x), _id: 0qFPOnULZigyiXU9Jv.1D.XSTIYHZ24UCT00DMHF, _ids: { v: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf, x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 2-wfv1b9RyFHB2kdba3EBCy6Do5L-mMPJjT-nfPa } } >>> d = _ >> d >>> d.show(colored=False) { v: 7, x: 3, y: 5, z: λ(v x), _id: 0qFPOnULZigyiXU9Jv.1D.XSTIYHZ24UCT00DMHF, _ids: { v: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf, x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 2-wfv1b9RyFHB2kdba3EBCy6Do5L-mMPJjT-nfPa } } >>> d = {"a": 5} >> d >>> d.show(colored=False) { a: 5, v: 7, x: 3, y: 5, z: λ(v x), _id: jZrJ2CiVUA9OqW.G7dwb3KoaTWGMUmSUVUXn0CkM, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, v: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf, x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 2-wfv1b9RyFHB2kdba3EBCy6Do5L-mMPJjT-nfPa } } >>> from hdict.content.entry import AbsEntry, Unevaluated >>> from hdict import frozenhdict
Expand source code
class frozenhdict(UserDict, dict[str, VT]): """ Immutable hdict. Any nested 'hdict' value will be frozen to avoid inconsistency between the hdict id (inner id) and the frozenhdict id (outer id). >>> from hdict import frozenhdict, hdict >>> d = frozenhdict({"x": 3}, y=5) >>> from hosh._internals_appearance import decolorize >>> print(decolorize(repr(d))) # This is equivalent to just 'd', without colors. { x: 3, y: 5, _id: r5A2Mh6vRRO5rxi5nfXv1myeguGSTmqHuHev38qM, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2 } } >>> bool(d), bool(frozenhdict()) (True, False) >>> d.data {'x': 3, 'y': 5} >>> from hdict import _, apply >>> d *= apply(lambda v, x: v - x).z >>> str(d) '⦑{x: 3, y: 5} » z=λ(v x)⦒' >>> d.show(colored=False) ⦑{ x: 3, y: 5, _id: r5A2Mh6vRRO5rxi5nfXv1myeguGSTmqHuHev38qM, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2 } } » z=λ(v x)⦒ >>> d = {"v": 7} * d >>> d.solve().show(colored=False) { v: 7, x: 3, y: 5, z: λ(v x), _id: 0qFPOnULZigyiXU9Jv.1D.XSTIYHZ24UCT00DMHF, _ids: { v: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf, x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 2-wfv1b9RyFHB2kdba3EBCy6Do5L-mMPJjT-nfPa } } >>> d = _ >> d >>> d.show(colored=False) { v: 7, x: 3, y: 5, z: λ(v x), _id: 0qFPOnULZigyiXU9Jv.1D.XSTIYHZ24UCT00DMHF, _ids: { v: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf, x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 2-wfv1b9RyFHB2kdba3EBCy6Do5L-mMPJjT-nfPa } } >>> d = {"a": 5} >> d >>> d.show(colored=False) { a: 5, v: 7, x: 3, y: 5, z: λ(v x), _id: jZrJ2CiVUA9OqW.G7dwb3KoaTWGMUmSUVUXn0CkM, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, v: eJCW9jGsdZTD6-AD9opKwjPIOWZ4R.T0CG2kdyzf, x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, z: 2-wfv1b9RyFHB2kdba3EBCy6Do5L-mMPJjT-nfPa } } >>> from hdict.content.entry import AbsEntry, Unevaluated >>> from hdict import frozenhdict """ _evaluated = None _asdict, _asdicts, _asdicts_noid = None, None, None _hoshes = None # noinspection PyMissingConstructor def __init__(self, /, _dictionary=None, _previous=None, **kwargs): from hdict.content.entry import AbsEntry from hdict.data.aux_frozendict import handle_identity from hdict.data.aux_frozendict import handle_items # todo: : check if _dictionary keys is 'str'; regex to check if k is an identifier; data = _dictionary or {} # REMINDER: Inside data, the only 'dict' entries are "_id" and "_ids", the rest are AbsEntry objects. self.data: dict[str, AbsEntry | str | dict[str, str]] self.data = handle_items(data, kwargs, previous=_previous) self.hosh, self.ids = handle_identity(self.data) self.id = self.hosh.id self.raw = self.data @property def hoshes(self): if self._hoshes is None: self._hoshes = {k: v.hosh for k, v in self.data.items()} return self._hoshes def __rmul__(self, left): from hdict import frozenhdict from hdict.expression.step.edict import EDict from hdict.expression.expr import Expr from hdict import hdict if isinstance(left, dict) and not isinstance(left, (hdict, frozenhdict)): return Expr(EDict(left), self) return NotImplemented # pragma: no cover def __mul__(self, other): from hdict import hdict, frozenhdict from hdict.expression.step.edict import EDict from hdict.expression.expr import Expr from hdict.expression.step.step import AbsStep match other: case AbsStep() | hdict() | frozenhdict(): return Expr(self, other) case dict(): return Expr(self, EDict(other)) case _: # pragma: no cover return NotImplemented def __rrshift__(self, left): from hdict import hdict if isinstance(left, dict) and not isinstance(left, (hdict, frozenhdict)): return frozenhdict(left) >> self return NotImplemented # pragma: no cover def __rshift__(self, other): # If merging, keep ids. from hdict import hdict from hdict.expression.step.applyout import ApplyOut from hdict.expression.step.cache import cache from hdict.content.entry.cached import Cached from hdict.content.argument.apply import apply if isinstance(other, apply): # pragma: no cover raise Exception(f"Cannot apply without specifying output(s).\n" f"Hint: d >> apply(f)('output_field1', 'output_field2')") from hdict.content.argument import AbsArgument if isinstance(other, AbsArgument): # pragma: no cover raise Exception(f"Cannot pipe {type(other).__name__} without specifying output.\n" "Hint: d >> {'field name': object}\n" f"Hint: d['field name'] = object") from hdict.expression.expr import Expr match other: case hdict() | frozenhdict(): dct = other.raw case ApplyOut(nested, out): dct = {out: nested} case cache(storage=storage, fields=fields): if not fields: fields = (k for k, v in self.raw.items() if not v.isevaluated) dct = {k: Cached(self.ids[k], storage, self.raw[k]) for k in fields} case dict(): dct = other case Expr(): return Expr(self, other).solve() case _: # pragma: no cover return NotImplemented return frozenhdict(dct, _previous=self) def __getitem__(self, item): # pragma: no cover return self.data[item].value def __getattr__(self, item): # pragma: no cover if item in self.data: return self.data[item].value return self.__getattribute__(item) def __setitem__(self, key: str, value): # pragma: no cover print(value) raise Exception(f"Cannot set an entry ({key}) of a frozen dict.") def __delitem__(self, key): # pragma: no cover raise Exception(f"Cannot delete an entry ({key}) from a frozen dict.") @staticmethod def fromdict(dictionary, ids): """Build a frozenidict from values and pre-defined ids >>> from hdict import hdict, value >>> hdict.fromdict({"x": value(5, hosh="0123456789012345678901234567890123456789")}, {"x": "0123456789012345678901234567890123456789"}).show(colored=False) { x: 5, _id: bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq, _ids: { x: 0123456789012345678901234567890123456789 } } """ from hdict.content.value import value from hdict.content.entry import AbsEntry data = {} for k, v in dictionary.items(): if isinstance(v, AbsEntry): if k in ids and ids[k] != v.id: # pragma: no cover raise Exception(f"Conflicting ids provided for key '{k}': ival.id={v.id}; ids[{k}]={ids[k]}") data[k] = v else: data[k] = value(v, ids[k] if k in ids else None) return frozenhdict(data) @property def evaluated(self): if self._evaluated is None: for k, val in self.data.items(): val.evaluate() self._evaluated = self return self def evaluate(self): # todo: add flag to inhibit evaluation (i.e., fetching) of cached values; or other solution, e.g. Cache(write_onapply) _ = self.evaluated @property def asdict(self): """ Convert to 'dict', including ids. This evaluates all fields. HINT: Use 'dict(d)' to convert a 'hdict' to a 'dict' excluding ids. >>> from hdict import hdict, value >>> d = hdict.fromdict({"x": value(5, hosh="0123456789012345678901234567890123456789")}, {"x": "0123456789012345678901234567890123456789"}) >>> d.asdict {'x': 5, '_id': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq', '_ids': {'x': '0123456789012345678901234567890123456789'}} """ if self._asdict is None: dic = dict(self.items()) dic["_id"] = self.id dic["_ids"] = self.ids.copy() self._asdict = dic return self._asdict @property def asdicts(self): """ Convert to 'dict' recursing into nested frozenhdicts, including ids. This evaluates all fields. REMINDER: hdict is never nested, frozenhdict is used instead HINT: Use 'asdicts_noid' to recursively convert a 'hdict' to a 'dict' excluding ids. >>> from hdict import value, hdict >>> d = hdict(x=value(5, hosh="0123456789012345678901234567890123456789")) >>> e = hdict(d=d) >>> e.asdicts {'d': {'x': 5, '_id': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq', '_ids': {'x': '0123456789012345678901234567890123456789'}}, '_id': 'GGhKhUmGhISaoHevn39hb-pLZEMoAc3KzE6Z0.IH', '_ids': {'d': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq'}} >>> dict(e) == e True """ if self._asdicts is None: from hdict import hdict dic = {} for k, v in self.items(): dic[k] = v.asdicts if isinstance(v, (hdict, frozenhdict)) else v dic["_id"] = self.id dic["_ids"] = self.ids.copy() self._asdicts = dic return self._asdicts @property def asdicts_noid(self): """ Convert to 'dict' recursing into nested frozenhdicts, excluding ids. REMINDER: hdict is never nested, frozenhdict is used instead HINT: Use 'asdicts' to recursively convert a 'hdict' 'd' to 'dict' including ids. >>> from hdict import value, hdict >>> d = hdict(x=value(5, hosh="0123456789012345678901234567890123456789")) >>> e = hdict(d=d) >>> e.asdicts_noid {'d': {'x': 5}} >>> dict(e) == e True """ if self._asdicts_noid is None: from hdict import hdict dic = {} for k, v in self.items(): dic[k] = v.asdicts_noid if isinstance(v, (hdict, frozenhdict)) else v self._asdicts_noid = dic return self._asdicts_noid @property def asdicts_hoshes_noneval(self): from hdict import value from hdict.content.entry import AbsEntry hoshes = set() dic = {} for k, val in self.data.items(): if isinstance(val, AbsEntry): hoshes.add(val.hosh) if isinstance(val, value): v = val.value if isinstance(v, frozenhdict): dic[k], subhoshes = v.asdicts_hoshes_noneval hoshes.update(subhoshes) else: dic[k] = v else: dic[k] = val hoshes.add(self.hosh) dic["_id"] = self.id dic["_ids"] = self.ids.copy() return dic, hoshes def astext(self, colored=True, key_quotes=False): r"""Textual representation of a frozenidict object""" dicts, hoshes = self.asdicts_hoshes_noneval txt = json.dumps(dicts, indent=4, ensure_ascii=False, cls=CustomJSONEncoder) # Put colors after json, to avoid escaping ansi codes. todo: check how HTML behaves here for h in hoshes: txt = txt.replace(f'"{h.id}"', repr(h)) if colored else txt.replace(f'"{h.id}"', h.id) # Remove quotes. txt = re.sub(r'(": )"(λ.+?)"(?=,\n)', '": \\2', txt) # Closure txt = re.sub(r'(": )"(·.+?)"(?=,\n)', '": \\2', txt) # Wrapper txt = re.sub(r'(": )"(↑↓ cached at `.+?·)"(?=,\n)', '": \\2', txt) # cache if not key_quotes: txt = re.sub(r'(?<!: )"([\-a-zA-Z0-9_ ]+?)"(?=: )', "\\1", txt) # keys return txt def show(self, colored=True, key_quotes=False): r"""Print textual representation of a frozenidict object""" print(self.astext(colored, key_quotes)) def copy(self): # pragma: no cover raise Exception("A FrozenIdict doesn't need copies") @property def unfrozen(self): from hdict import hdict return hdict(_frozen=self) # def entries(self, evaluate=True): # """Iterator over all items""" # yield from self.items(evaluate) # # yield from self.metaitems(evaluate) def keys(self): """Generator of keys which don't start with '_'" >>> from hdict import hdict >>> list(hdict(x=3, y=5).keys()) ['x', 'y'] >>> list(hdict(x=3, y=5).values()) [3, 5] """ # return (k for k in self.data if not k.startswith("_")) return self.data.keys() def values(self, evaluate=True): """Generator of field values (keys that don't start with '_')""" return ((v.value if evaluate else v) for k, v in self.data.items()) # return ((v.value if evaluate else v) for k, v in self.data.items() if not k.startswith("_")) def items(self, evaluate=True): """Generator over field-value pairs""" for k, val in self.data.items(): # if not k.startswith("_"): yield k, (val.value if evaluate else val) def save(self, storage: dict): """ Store an entire frozenidict """ from hdict.persistence.stored import Stored data = {self.id: self.ids} for field, fid in self.ids.items(): value = self[field] if field.endswith("_"): raise Exception(f"Not implemented for mirror fields") # todo: confirm existence of the counterpart # data[kindid(fid)] = str(type(value)) elif isinstance(value, frozenhdict): value.save(storage) else: data[fid] = Stored(value) # todo: check if frozenhdict is being stored by mistake # todo: attribute/method as subfield: # apply(f, _.df.x) SubField(name="df", attribute="x") # apply(_.df.drop, "col1") SubField(name="df", attribute="drop") # storage.update(data) @staticmethod def load(id, storage: dict, lazy=True) -> Union["frozenhdict", None]: """ Fetch an entire frozenidict """ if len(id) != 40: # pragma: no cover raise Exception(f"id should have lenght of 40, not {len(id)}") return frozenhdict.fetch(id, storage, lazy, ishdict=True) @staticmethod def fetch(id: str, storage: dict, lazy=True, ishdict=False) -> Union["frozenhdict", None]: """ Fetch a single entry When cache is a list, traverse it from the end (right item to the left item). """ from hdict.content.entry.cached import Cached from hdict.persistence.stored import Stored if id not in storage: return None obj = storage[id] if isinstance(obj, dict): ishdict = True # Set to True, because now we have a nested frozenhdict elif ishdict or not isinstance(obj, Stored): # pragma: no cover raise Exception(f"Wrong content for hdict expected under id {id}: {type(obj)}.") if ishdict: ids = obj data = {} mirrored = set() for field, fid in ids.items(): if field.endswith("_"): # TODO: 2023-06-23 # - raise Exception(f"Not implemented for mirror fields") # mirrored.add(field[:-1]) continue if lazy: data[field] = Cached(fid, storage) else: obj = frozenhdict.fetch(fid, storage, lazy=False, ishdict=False) if obj is None: # pragma: no cover print(storage.keys()) raise Exception(f"Incomplete hdict: id '{id}' not found in the provided cache.") data[field] = obj # for field in mirrored: # obj = data[field] # kind = obj.kind if isinstance(obj, Cached) else getkind(storage, obj.hosh) # data[field + "_"] = handle_mirror(field, data, ids[field], kind) return frozenhdict.fromdict(data, ids) return obj.content @property def asdf(self): """ Represent hdict as a DataFrame if possible """ from pandas import DataFrame data = dict(self) index = data.pop("index") return DataFrame(data, index=index) @staticmethod def fromfile(name, fields=None, format="df", named=None, hide_types=True): r""" Input format is defined by file extension: .arff, .csv """ from hdict.data.aux_frozendict import handle_format df, name = file2df(name, hide_types, True) return handle_format(format, fields, df, named and name) @staticmethod def fromtext(text: str, fields=None, format="df", named=None): r""" Input format is defined by file extension: .arff, .csv """ from hdict import frozenhdict if text.startswith("@"): name = "<Unnamed>" with StringIO() as f: f.write(text) text = f.getvalue() df = loads(text) for line in isplit(text, "\n"): if line[:9].upper() == "@RELATION": name = line[9:].strip() break else: from testfixtures import TempDirectory with TempDirectory() as tmp: tmp.write( "temp.csv", text.encode(), ) return frozenhdict.fromfile(tmp.path + "/temp.csv", fields, format, named) from hdict.data.aux_frozendict import handle_format return handle_format(format, fields, df, named and name) def __eq__(self, other): if isinstance(other, dict): if "_id" in other: return self.id == other["_id"] if list(self.keys()) != list(other.keys()): return False from hdict import hdict if isinstance(other, (frozenhdict, hdict)): return self.id == other.id return dict(self) == other return NotImplemented # pragma: no cover def __ne__(self, other): return not (self == other) def __repr__(self): return self.astext() def __str__(self): return stringfy(self.data) def __iter__(self): for k in self.data: yield k def __hash__(self): return hash(self.hosh) def __bool__(self): return bool(self.data) # def __reduce__(self): # dic = self.data.copy() # del dic["_id"] # del dic["_ids"] # return self.__class__, (dic,)
Ancestors
- collections.UserDict
- collections.abc.MutableMapping
- collections.abc.Mapping
- collections.abc.Collection
- collections.abc.Sized
- collections.abc.Iterable
- collections.abc.Container
- builtins.dict
Subclasses
Static methods
def fetch(id: str, storage: dict, lazy=True, ishdict=False) ‑> Optional[frozenhdict]
-
Fetch a single entry
When cache is a list, traverse it from the end (right item to the left item).
Expand source code
@staticmethod def fetch(id: str, storage: dict, lazy=True, ishdict=False) -> Union["frozenhdict", None]: """ Fetch a single entry When cache is a list, traverse it from the end (right item to the left item). """ from hdict.content.entry.cached import Cached from hdict.persistence.stored import Stored if id not in storage: return None obj = storage[id] if isinstance(obj, dict): ishdict = True # Set to True, because now we have a nested frozenhdict elif ishdict or not isinstance(obj, Stored): # pragma: no cover raise Exception(f"Wrong content for hdict expected under id {id}: {type(obj)}.") if ishdict: ids = obj data = {} mirrored = set() for field, fid in ids.items(): if field.endswith("_"): # TODO: 2023-06-23 # - raise Exception(f"Not implemented for mirror fields") # mirrored.add(field[:-1]) continue if lazy: data[field] = Cached(fid, storage) else: obj = frozenhdict.fetch(fid, storage, lazy=False, ishdict=False) if obj is None: # pragma: no cover print(storage.keys()) raise Exception(f"Incomplete hdict: id '{id}' not found in the provided cache.") data[field] = obj # for field in mirrored: # obj = data[field] # kind = obj.kind if isinstance(obj, Cached) else getkind(storage, obj.hosh) # data[field + "_"] = handle_mirror(field, data, ids[field], kind) return frozenhdict.fromdict(data, ids) return obj.content
def fromdict(dictionary, ids)
-
Build a frozenidict from values and pre-defined ids
>>> from hdict import hdict, value >>> hdict.fromdict({"x": value(5, hosh="0123456789012345678901234567890123456789")}, {"x": "0123456789012345678901234567890123456789"}).show(colored=False) { x: 5, _id: bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq, _ids: { x: 0123456789012345678901234567890123456789 } }
Expand source code
@staticmethod def fromdict(dictionary, ids): """Build a frozenidict from values and pre-defined ids >>> from hdict import hdict, value >>> hdict.fromdict({"x": value(5, hosh="0123456789012345678901234567890123456789")}, {"x": "0123456789012345678901234567890123456789"}).show(colored=False) { x: 5, _id: bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq, _ids: { x: 0123456789012345678901234567890123456789 } } """ from hdict.content.value import value from hdict.content.entry import AbsEntry data = {} for k, v in dictionary.items(): if isinstance(v, AbsEntry): if k in ids and ids[k] != v.id: # pragma: no cover raise Exception(f"Conflicting ids provided for key '{k}': ival.id={v.id}; ids[{k}]={ids[k]}") data[k] = v else: data[k] = value(v, ids[k] if k in ids else None) return frozenhdict(data)
def fromfile(name, fields=None, format='df', named=None, hide_types=True)
-
Input format is defined by file extension: .arff, .csv
Expand source code
@staticmethod def fromfile(name, fields=None, format="df", named=None, hide_types=True): r""" Input format is defined by file extension: .arff, .csv """ from hdict.data.aux_frozendict import handle_format df, name = file2df(name, hide_types, True) return handle_format(format, fields, df, named and name)
def fromtext(text: str, fields=None, format='df', named=None)
-
Input format is defined by file extension: .arff, .csv
Expand source code
@staticmethod def fromtext(text: str, fields=None, format="df", named=None): r""" Input format is defined by file extension: .arff, .csv """ from hdict import frozenhdict if text.startswith("@"): name = "<Unnamed>" with StringIO() as f: f.write(text) text = f.getvalue() df = loads(text) for line in isplit(text, "\n"): if line[:9].upper() == "@RELATION": name = line[9:].strip() break else: from testfixtures import TempDirectory with TempDirectory() as tmp: tmp.write( "temp.csv", text.encode(), ) return frozenhdict.fromfile(tmp.path + "/temp.csv", fields, format, named) from hdict.data.aux_frozendict import handle_format return handle_format(format, fields, df, named and name)
def load(id, storage: dict, lazy=True) ‑> Optional[frozenhdict]
-
Fetch an entire frozenidict
Expand source code
@staticmethod def load(id, storage: dict, lazy=True) -> Union["frozenhdict", None]: """ Fetch an entire frozenidict """ if len(id) != 40: # pragma: no cover raise Exception(f"id should have lenght of 40, not {len(id)}") return frozenhdict.fetch(id, storage, lazy, ishdict=True)
Instance variables
var asdf
-
Represent hdict as a DataFrame if possible
Expand source code
@property def asdf(self): """ Represent hdict as a DataFrame if possible """ from pandas import DataFrame data = dict(self) index = data.pop("index") return DataFrame(data, index=index)
var asdict
-
Convert to 'dict', including ids.
This evaluates all fields. HINT: Use 'dict(d)' to convert a 'hdict' to a 'dict' excluding ids.
>>> from hdict import hdict, value >>> d = hdict.fromdict({"x": value(5, hosh="0123456789012345678901234567890123456789")}, {"x": "0123456789012345678901234567890123456789"}) >>> d.asdict {'x': 5, '_id': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq', '_ids': {'x': '0123456789012345678901234567890123456789'}}
Expand source code
@property def asdict(self): """ Convert to 'dict', including ids. This evaluates all fields. HINT: Use 'dict(d)' to convert a 'hdict' to a 'dict' excluding ids. >>> from hdict import hdict, value >>> d = hdict.fromdict({"x": value(5, hosh="0123456789012345678901234567890123456789")}, {"x": "0123456789012345678901234567890123456789"}) >>> d.asdict {'x': 5, '_id': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq', '_ids': {'x': '0123456789012345678901234567890123456789'}} """ if self._asdict is None: dic = dict(self.items()) dic["_id"] = self.id dic["_ids"] = self.ids.copy() self._asdict = dic return self._asdict
var asdicts
-
Convert to 'dict' recursing into nested frozenhdicts, including ids.
This evaluates all fields. REMINDER: hdict is never nested, frozenhdict is used instead HINT: Use 'asdicts_noid' to recursively convert a 'hdict' to a 'dict' excluding ids.
>>> from hdict import value, hdict >>> d = hdict(x=value(5, hosh="0123456789012345678901234567890123456789")) >>> e = hdict(d=d) >>> e.asdicts {'d': {'x': 5, '_id': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq', '_ids': {'x': '0123456789012345678901234567890123456789'}}, '_id': 'GGhKhUmGhISaoHevn39hb-pLZEMoAc3KzE6Z0.IH', '_ids': {'d': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq'}} >>> dict(e) == e True
Expand source code
@property def asdicts(self): """ Convert to 'dict' recursing into nested frozenhdicts, including ids. This evaluates all fields. REMINDER: hdict is never nested, frozenhdict is used instead HINT: Use 'asdicts_noid' to recursively convert a 'hdict' to a 'dict' excluding ids. >>> from hdict import value, hdict >>> d = hdict(x=value(5, hosh="0123456789012345678901234567890123456789")) >>> e = hdict(d=d) >>> e.asdicts {'d': {'x': 5, '_id': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq', '_ids': {'x': '0123456789012345678901234567890123456789'}}, '_id': 'GGhKhUmGhISaoHevn39hb-pLZEMoAc3KzE6Z0.IH', '_ids': {'d': 'bi5Qdbh-zgA1ZQdxGhxqjaKaQROtxk1VCPRZhMOq'}} >>> dict(e) == e True """ if self._asdicts is None: from hdict import hdict dic = {} for k, v in self.items(): dic[k] = v.asdicts if isinstance(v, (hdict, frozenhdict)) else v dic["_id"] = self.id dic["_ids"] = self.ids.copy() self._asdicts = dic return self._asdicts
var asdicts_hoshes_noneval
-
Expand source code
@property def asdicts_hoshes_noneval(self): from hdict import value from hdict.content.entry import AbsEntry hoshes = set() dic = {} for k, val in self.data.items(): if isinstance(val, AbsEntry): hoshes.add(val.hosh) if isinstance(val, value): v = val.value if isinstance(v, frozenhdict): dic[k], subhoshes = v.asdicts_hoshes_noneval hoshes.update(subhoshes) else: dic[k] = v else: dic[k] = val hoshes.add(self.hosh) dic["_id"] = self.id dic["_ids"] = self.ids.copy() return dic, hoshes
var asdicts_noid
-
Convert to 'dict' recursing into nested frozenhdicts, excluding ids.
REMINDER: hdict is never nested, frozenhdict is used instead HINT: Use 'asdicts' to recursively convert a 'hdict' 'd' to 'dict' including ids.
>>> from hdict import value, hdict >>> d = hdict(x=value(5, hosh="0123456789012345678901234567890123456789")) >>> e = hdict(d=d) >>> e.asdicts_noid {'d': {'x': 5}} >>> dict(e) == e True
Expand source code
@property def asdicts_noid(self): """ Convert to 'dict' recursing into nested frozenhdicts, excluding ids. REMINDER: hdict is never nested, frozenhdict is used instead HINT: Use 'asdicts' to recursively convert a 'hdict' 'd' to 'dict' including ids. >>> from hdict import value, hdict >>> d = hdict(x=value(5, hosh="0123456789012345678901234567890123456789")) >>> e = hdict(d=d) >>> e.asdicts_noid {'d': {'x': 5}} >>> dict(e) == e True """ if self._asdicts_noid is None: from hdict import hdict dic = {} for k, v in self.items(): dic[k] = v.asdicts_noid if isinstance(v, (hdict, frozenhdict)) else v self._asdicts_noid = dic return self._asdicts_noid
var evaluated
-
Expand source code
@property def evaluated(self): if self._evaluated is None: for k, val in self.data.items(): val.evaluate() self._evaluated = self return self
var hoshes
-
Expand source code
@property def hoshes(self): if self._hoshes is None: self._hoshes = {k: v.hosh for k, v in self.data.items()} return self._hoshes
var unfrozen
-
Expand source code
@property def unfrozen(self): from hdict import hdict return hdict(_frozen=self)
Methods
def astext(self, colored=True, key_quotes=False)
-
Textual representation of a frozenidict object
Expand source code
def astext(self, colored=True, key_quotes=False): r"""Textual representation of a frozenidict object""" dicts, hoshes = self.asdicts_hoshes_noneval txt = json.dumps(dicts, indent=4, ensure_ascii=False, cls=CustomJSONEncoder) # Put colors after json, to avoid escaping ansi codes. todo: check how HTML behaves here for h in hoshes: txt = txt.replace(f'"{h.id}"', repr(h)) if colored else txt.replace(f'"{h.id}"', h.id) # Remove quotes. txt = re.sub(r'(": )"(λ.+?)"(?=,\n)', '": \\2', txt) # Closure txt = re.sub(r'(": )"(·.+?)"(?=,\n)', '": \\2', txt) # Wrapper txt = re.sub(r'(": )"(↑↓ cached at `.+?·)"(?=,\n)', '": \\2', txt) # cache if not key_quotes: txt = re.sub(r'(?<!: )"([\-a-zA-Z0-9_ ]+?)"(?=: )', "\\1", txt) # keys return txt
def copy(self)
-
D.copy() -> a shallow copy of D
Expand source code
def copy(self): # pragma: no cover raise Exception("A FrozenIdict doesn't need copies")
def evaluate(self)
-
Expand source code
def evaluate(self): # todo: add flag to inhibit evaluation (i.e., fetching) of cached values; or other solution, e.g. Cache(write_onapply) _ = self.evaluated
def items(self, evaluate=True)
-
Generator over field-value pairs
Expand source code
def items(self, evaluate=True): """Generator over field-value pairs""" for k, val in self.data.items(): # if not k.startswith("_"): yield k, (val.value if evaluate else val)
def keys(self)
-
Generator of keys which don't start with '_'"
>>> from hdict import hdict >>> list(hdict(x=3, y=5).keys()) ['x', 'y'] >>> list(hdict(x=3, y=5).values()) [3, 5]
Expand source code
def keys(self): """Generator of keys which don't start with '_'" >>> from hdict import hdict >>> list(hdict(x=3, y=5).keys()) ['x', 'y'] >>> list(hdict(x=3, y=5).values()) [3, 5] """ # return (k for k in self.data if not k.startswith("_")) return self.data.keys()
def save(self, storage: dict)
-
Store an entire frozenidict
Expand source code
def save(self, storage: dict): """ Store an entire frozenidict """ from hdict.persistence.stored import Stored data = {self.id: self.ids} for field, fid in self.ids.items(): value = self[field] if field.endswith("_"): raise Exception(f"Not implemented for mirror fields") # todo: confirm existence of the counterpart # data[kindid(fid)] = str(type(value)) elif isinstance(value, frozenhdict): value.save(storage) else: data[fid] = Stored(value) # todo: check if frozenhdict is being stored by mistake # todo: attribute/method as subfield: # apply(f, _.df.x) SubField(name="df", attribute="x") # apply(_.df.drop, "col1") SubField(name="df", attribute="drop") # storage.update(data)
def show(self, colored=True, key_quotes=False)
-
Print textual representation of a frozenidict object
Expand source code
def show(self, colored=True, key_quotes=False): r"""Print textual representation of a frozenidict object""" print(self.astext(colored, key_quotes))
def values(self, evaluate=True)
-
Generator of field values (keys that don't start with '_')
Expand source code
def values(self, evaluate=True): """Generator of field values (keys that don't start with '_')""" return ((v.value if evaluate else v) for k, v in self.data.items()) # return ((v.value if evaluate else v) for k, v in self.data.items() if not k.startswith("_"))
class hdict (**kwargs)
-
Function id is reversed before application. This is needed to enable handling a function as a value, under the original id.
>>> from hdict import hdict, apply, field >>> from hdict.content.argument.default import default >>> d = hdict({"x": 3}, y=5) >>> d["alpha"] = 11 >>> d.show(colored=False) { x: 3, y: 5, alpha: 11, _id: e6WGyTj7trk6AUUcdxGAefyG.T9j.SvBdEsHF.r5, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, alpha: A1RyW.GoA3q9-iCbCvWyWClExm1J3wI.ok6UA3Nk } } >>> d >>= {"beta": 12, "gamma": 17} >>> d["p1", "q1"] = apply(lambda x, y=3: [x**y, x/y]) >>> d["pq"] = apply(lambda x, y=3: [x**y, x/y]) >>> d["p2", "q2"] = apply(lambda x=2, y=None: [x**y, x/y]) >>> f = lambda x, y: {"a": x**y, "b": x/y} >>> d["z1", "w1"] = apply(f) >>> d["z2":"a", "w2":"b"] = apply(f) >>> d >>= { ... "r1": apply(lambda x: x**2), ... "r2": apply(lambda x: x**3), ... "r3": apply(lambda x: x**4), ... ("ra1", "rb1"): apply(f), ... (("ra2", "a"), ("rb2", "b")): apply(f), ... } >>> d["z2"] 243 >>> d["zz1", "ww1"] = apply(f, field("r1"), y=field("r2")) >>> d >>= {("zz2", "ww2"): apply(f, y=field("r2"), x=9)} # Define external value. >>> d >>= {"zzzz": apply(f, y=13, x=9)} >>> # Non-pickable custom classes need a custom 'hosh' attribute to be applied and also to be used as a value. >>> from hosh import Hosh >>> # Example of class that could be used as a value or as a function. >>> from dataclasses import dataclass >>> @dataclass ... class CustomClass: ... hosh = Hosh.fromid("Some.arbitrary.identifier.with.length.40") ... def __call__(self, x, y): ... return x + y, x / y >>> custom = CustomClass() >>> d["f"] = custom # Custom callable handled as a value. >>> d["zzz1", "www1"] = apply(custom, 11, y=33) # Custom callable being applied. >>> d["zzz2", "www2"] = apply(field("f"), field("r1"), y=44) # Callable field being applied. >>> d.show(colored=False) { x: 3, y: 5, alpha: 11, beta: 12, gamma: 17, p1: λ(x y)→0, q1: λ(x y)→1, pq: λ(x y), p2: λ(x y)→0, q2: λ(x y)→1, z1: λ(x y)→0, w1: λ(x y)→1, z2: 243, w2: λ(x y)→b, r1: λ(x), r2: λ(x), r3: λ(x), ra1: λ(x y)→0, rb1: λ(x y)→1, ra2: λ(x y)→a, rb2: λ(x y)→b, zz1: λ(x=r1 y=r2)→0, ww1: λ(x=r1 y=r2)→1, zz2: λ(9 y=r2)→0, ww2: λ(9 y=r2)→1, zzzz: λ(9 13), f: "CustomClass()", zzz1: λ(11 33)→0, www1: λ(11 33)→1, zzz2: λ(r1 44)→0, www2: λ(r1 44)→1, _id: i5wtTs5qggivS-y5TNuhnM5jwokjF132M7jF.49a, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, alpha: A1RyW.GoA3q9-iCbCvWyWClExm1J3wI.ok6UA3Nk, beta: WM5TbiaJ1gLqKRSFiY3VkZEu1PwQcaAokBKBPrWg, gamma: yb-HU.jSxd496XfId1J..MkX7xfUPJOL1-07hHdt, p1: Qs0J0I.AhR.brQjpYwUJqDNLk-zKd7FmG0g7gdd1, q1: VOAVwyrrdC7eIsjnVkqdpsqUfhprKzKriATFEOQI, pq: KtTWRcFQRKVgTJabGMgY-HAQWJ1TZGnOYw7NU.1K, p2: qb0H0MqNit0rLwk6CsC4Q2bxpCmBQ581eoGI39sr, q2: Sjsl-.MJJ3SK2.INLAJ-0R5BwlfG.tccIpxPFRtB, z1: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, w1: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, z2: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, w2: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, r1: FO3NXIQIi7TBFw1FqLRJYo13EA.uu4Y-L17Fmx0z, r2: HorxHsNCdpkm270yeTZ-vREjjFXWIYC99ALidDVU, r3: bWc33lXvXHIJXix5Jw2.Nhw0EIsv3TuAa7t8Ix5q, ra1: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, rb1: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, ra2: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, rb2: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, zz1: FB6W9j12qWZ34fUwyrBETzFuAXRB-xn7O1PGhr2j, ww1: IhchjkRfjLXpnsC6zl-TFugIQrnUIdB7Wsgpnely, zz2: LE5ohPby7q4dNu3qhqgucRcCt.pd87O.CyKWloqe, ww2: -RBf-UiccAG3sTH0UFC6C.YFmYcpTRA.0PFP6Oun, zzzz: Irbj-xVP8rEIPoylOTNmiuJ-lGdx0dpzIPgq-169, f: Some.arbitrary.identifier.with.length.40, zzz1: TBw0fUZZo1WlI9uczNuF0w4vC06u6YvzJyNPVEi1, www1: WqqXpIpMwinaXxYNqRjj4qttDcKXN.gcGjARpOSh, zzz2: .mJim0y-LMUYZi01GN8MTPkHj79JtFdREf7g40ug, www2: jwtsaf1IZMG6sWqprXZnc.n-ilyfncwhL3Qr.-Md } } >>> d["p1"] 243 >>> from hdict import value >>> d.evaluate() >>> d = hdict(x=2) >>> g = lambda x, y: [x + y, x / y] >>> d["z"] = apply(f, 2, y=3) >>> d["w", "v"] = apply(f, field("x"), y=33) >>> d["f"] = f >>> d = d >> apply(field("f"), field("x"), y=default(3), nonexistent_parameter=7)("w3", "v3") # todo: : nonexistent parameter should raise an exception >>> d >>= apply(field("f"), field("x"), y=default(3))("w", "v") >>> d["w2", "v2"] = apply(field("f"), field("x"), y=default(3)) >>> d >>= {"z": apply(f, field("x"), y=3), ("w", "v"): apply(g, y=7)} >>> d >>= apply(f, field("x"), y=3)("z9") * apply(g, y=7)("w9", "v9") >>> pp = apply(f, field("x"), y=3)("z") >> apply(g, y=7)("w", "v") >>> d >>= {"x": 3} >> pp >> apply(g, y=7)("w", "v") >>> from hdict import _ >>> a1 = apply(f, y=_(1, 2, 4, ..., 128)) >>> a2 = apply(f, _(0, 3, 6, ..., 9), y=_(0, 3, 6, ..., 9)) >>> ppp = hdict() >> a2.sample()("k", "t") >>> ppp.show(colored=False) { k: λ(9 9)→0, t: λ(9 9)→1, _id: dK-iumb4L5nkFVT9LCkdk3daQtuC.ORk6JwWMhnt, _ids: { k: rHTgwW.w2SsbcvBlSnWWddLH4vgyXlM1Fhxqr48f, t: IldA8m-uSN9lJcE4TBtjTcY-sSiA33mzxQ2k-wpN } } >>> ppp.k 387420489 >>> a1("z") z=λ(x y=~[1 2 .*. 128]) >>> a2(w="a", v="b") (('w', 'a'), ('v', 'b'))=λ(x=~[0 3 .+. 9] y=~[0 3 .+. 9]) >>> p = a1("z") >> a2(w="a", v="b") >>> h = lambda a, b=4: 5 >>> app = apply(h, a=_(0, 3, 6, ..., 9)) >>> app λ(a=~[0 3 .+. 9] b=default(4)) >>> app.c c=λ(a=~[0 3 .+. 9] b=default(4)) >>> sampled = app.sample(0).c >>> sampled c=λ(9 b=default(4)) >>> r = hdict() >> sampled >>> r.show(colored=False) { c: λ(9 b=4), _id: Bbe5mzn0oCuHZ.Y84-jaEnh3jcrgD8av6IZezKEG, _ids: { c: 6EehD7OoZe2REI.1YsVLKxSF4hJoYxfOZJLbF.Aj } } >>> r.evaluated.show(colored=False) { c: 5, _id: Bbe5mzn0oCuHZ.Y84-jaEnh3jcrgD8av6IZezKEG, _ids: { c: 6EehD7OoZe2REI.1YsVLKxSF4hJoYxfOZJLbF.Aj } } >>> from random import Random >>> rnd = Random(0) >>> p1 = p.sample(rnd) >>> d["w"] 10 >>> d >>= p1 >>> d["z"] = apply(f, 2, y=3) >>> d["w", "v"] = apply(f, _.x, y=_.x) >>> d["w", "v"] = apply(_.f, _.x, y=default(3)) >>> d = hdict() >> {"z": apply(f, 7, y=3), ("w", "v"): apply(g, default(6), y=7)} >>> d = hdict(w=6) >> (apply(f, _["w"], y=3)(z="z") >> apply(g, x=_(1,2,3,...,5), y=7)("ww", "v")).sample(0) >>> p = apply(f, y=_(1, 2, 4, ..., 128))("z") >> apply(f, y=_(0, 3, 6, ..., 9))(w="a", v="b") >>> d.show(colored=False) { w: 6, z: λ(x=w 3)→z, ww: λ(4 7)→0, v: λ(4 7)→1, _id: x4TxaVuAymsh97Yr.15Oc1ekllvlpECk091124RM, _ids: { w: CZ7Jm5fQMZ3fZJ3kAVOi0FYK-exFqPqgoYLsGxGl, z: No1nN40OXnJ.zOyAvoxwCjyD06cUDiXTZQh4q8xa, ww: qZepp.wpXCOYQrwnVIwoZ4kR9pIuMGDQpvRevv80, v: wxkjBSP54cKEfxKE1Zte-2dDll3G9Nd-yDh3CLas } } >>> d = hdict(x=3) >> p.sample(rnd) >>> d.show(colored=False) { x: 3, z: λ(x 16), w: λ(x 9)→a, v: λ(x 9)→b, _id: 22b-e.CtRGVSoMkektNzHYSVZTouhL2jAHLyPd4Q, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, z: 64cxw0HmJ0fydH7By6i0HrbuwA759XexTu3Bu0Zd, w: p1Z5umNo12DHCZtKbh2EClW6TZxv.M447HlALWhv, v: HbYbR1RjPdU4jixjW7xSxslRpYx9W6Oiay7maK6F } } >>> d1 = hdict(x=52, y=13) >>> d2 = hdict(x=value(52, hosh="1234567890123456789012345678901234567890")) >>> d1.show(colored=False) { x: 52, y: 13, _id: 5pwGP0LxQRbQaDEk9ztQ4V4qz.A-IIhVNTrcyt8U, _ids: { x: c.llz05T6ZXw5AlsU4xfmMxcvvHZhLl60LckZis9, y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s } } >>> d2.show(colored=False) { x: 52, _id: kYzgpPdRgQSYSEpp1qt4EHQLQJXuyb2WDQS-iNPh, _ids: { x: 1234567890123456789012345678901234567890 } } >>> d3 = d1 >> d2 >>> d3.show(colored=False) { x: 52, y: 13, _id: -EFuy5NAeK.LIALpBiZKK-fYQmc9AZYQQck-HiRK, _ids: { x: 1234567890123456789012345678901234567890, y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s } } >>> (d3 >> d1.frozen).show(colored=False) { x: 52, y: 13, _id: 5pwGP0LxQRbQaDEk9ztQ4V4qz.A-IIhVNTrcyt8U, _ids: { x: c.llz05T6ZXw5AlsU4xfmMxcvvHZhLl60LckZis9, y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s } }
>>> d = hdict(x=2, y=4) >>> {"x": 2, "y": 4} == d.frozen True >>> {"x": 2, "y": 4} == d True >>> d == {"x": 2, "y": 4} True >>> dict(d) {'x': 2, 'y': 4} >>> hdict() >> {"x": 3} == {"x": 3} True >>> {"x": 3, "d": {"x": 7}} == hdict(x=3, d=hdict(x=7)) True >>> hdict(x=3, d=hdict(x=7)) == {"x": 3, "d": {"x": 7}} True >>> {"x": 3, "_id": hdict(x=3).id} == hdict(x=3) True >>> hdict(x=3) == {"x": 3, "_id": hdict(x=3).id} True >>> hdict(x=3) == hdict(x=3) True >>> hdict(x=3).frozen == hdict(x=3) True >>> hdict(x=3) != {"x": 4} True >>> hdict(x=3) != hdict(x=4) True >>> hdict(x=3).frozen != hdict(x=4) True >>> hdict(x=3) != {"y": 3} True >>> hdict(x=3) != {"x": 3, "_id": (~hdict(x=3).hosh).id} True >>> hdict(x=3) != hdict(y=3) True >>> del d["x"] >>> list(d) ['y'] >>> e = d >> apply(lambda y: y*7)("y") >>> from hdict.content.aux_value import f2hosh >>> print(f2hosh(lambda y: y*7)) 54YCMDJIlsIvMQ.KJtT-vFyjg83Zgfj2xSHOgCj8 >>> print(e) {y: "λ(4)"} >>> e.evaluate() >>> print(e) {y: 28} >>> d = d >> apply(lambda y=1: y*7, fhosh="54YCMDJIlsIvMQ.KJtT-vFyjg83Zgfj2xSHOgCj8")("y") >>> print(d) {y: "λ(4)"} >>> d.evaluate() >>> print(d) {y: 28} >>> hash(e.frozen) == hash(d.frozen) True >>> d = hdict(a=5) >> hdict(y=28) >>> d.show(colored=False) { a: 5, y: 28, _id: C-xKyWCyBL6g32KIuxoANoF9czLaJTh-emPsMqOg, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9 } } >>> d >>= apply(lambda a: a)("x") >>> d.show(colored=False) { a: 5, y: 28, x: λ(a), _id: qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp } } >>> {"_id": "qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY"} == d True >>> d.show(colored=False) { a: 5, y: 28, x: λ(a), _id: qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp } } >>> def f(): ... print("busy") ... return 23 >>> storage = {} >>> d >>= apply(f).o >> cache(storage, "x", "y") >>> d.y 28 >>> d.show(colored=False) { a: 5, y: 28, x: ↑↓ cached at <code>dict</code>·, o: λ(), _id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp, o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo } } >>> d.evaluated.show(colored=False) busy { a: 5, y: 28, x: 5, o: 23, _id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp, o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo } } >>> d.evaluated.show(colored=False) { a: 5, y: 28, x: 5, o: 23, _id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp, o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo } }
Expand source code
class hdict(hdict_): """ Function id is reversed before application. This is needed to enable handling a function as a value, under the original id. >>> from hdict import hdict, apply, field >>> from hdict.content.argument.default import default >>> d = hdict({"x": 3}, y=5) >>> d["alpha"] = 11 >>> d.show(colored=False) { x: 3, y: 5, alpha: 11, _id: e6WGyTj7trk6AUUcdxGAefyG.T9j.SvBdEsHF.r5, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, alpha: A1RyW.GoA3q9-iCbCvWyWClExm1J3wI.ok6UA3Nk } } >>> d >>= {"beta": 12, "gamma": 17} >>> d["p1", "q1"] = apply(lambda x, y=3: [x**y, x/y]) >>> d["pq"] = apply(lambda x, y=3: [x**y, x/y]) >>> d["p2", "q2"] = apply(lambda x=2, y=None: [x**y, x/y]) >>> f = lambda x, y: {"a": x**y, "b": x/y} >>> d["z1", "w1"] = apply(f) >>> d["z2":"a", "w2":"b"] = apply(f) >>> d >>= { ... "r1": apply(lambda x: x**2), ... "r2": apply(lambda x: x**3), ... "r3": apply(lambda x: x**4), ... ("ra1", "rb1"): apply(f), ... (("ra2", "a"), ("rb2", "b")): apply(f), ... } >>> d["z2"] 243 >>> d["zz1", "ww1"] = apply(f, field("r1"), y=field("r2")) >>> d >>= {("zz2", "ww2"): apply(f, y=field("r2"), x=9)} # Define external value. >>> d >>= {"zzzz": apply(f, y=13, x=9)} >>> # Non-pickable custom classes need a custom 'hosh' attribute to be applied and also to be used as a value. >>> from hosh import Hosh >>> # Example of class that could be used as a value or as a function. >>> from dataclasses import dataclass >>> @dataclass ... class CustomClass: ... hosh = Hosh.fromid("Some.arbitrary.identifier.with.length.40") ... def __call__(self, x, y): ... return x + y, x / y >>> custom = CustomClass() >>> d["f"] = custom # Custom callable handled as a value. >>> d["zzz1", "www1"] = apply(custom, 11, y=33) # Custom callable being applied. >>> d["zzz2", "www2"] = apply(field("f"), field("r1"), y=44) # Callable field being applied. >>> d.show(colored=False) { x: 3, y: 5, alpha: 11, beta: 12, gamma: 17, p1: λ(x y)→0, q1: λ(x y)→1, pq: λ(x y), p2: λ(x y)→0, q2: λ(x y)→1, z1: λ(x y)→0, w1: λ(x y)→1, z2: 243, w2: λ(x y)→b, r1: λ(x), r2: λ(x), r3: λ(x), ra1: λ(x y)→0, rb1: λ(x y)→1, ra2: λ(x y)→a, rb2: λ(x y)→b, zz1: λ(x=r1 y=r2)→0, ww1: λ(x=r1 y=r2)→1, zz2: λ(9 y=r2)→0, ww2: λ(9 y=r2)→1, zzzz: λ(9 13), f: "CustomClass()", zzz1: λ(11 33)→0, www1: λ(11 33)→1, zzz2: λ(r1 44)→0, www2: λ(r1 44)→1, _id: i5wtTs5qggivS-y5TNuhnM5jwokjF132M7jF.49a, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, y: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, alpha: A1RyW.GoA3q9-iCbCvWyWClExm1J3wI.ok6UA3Nk, beta: WM5TbiaJ1gLqKRSFiY3VkZEu1PwQcaAokBKBPrWg, gamma: yb-HU.jSxd496XfId1J..MkX7xfUPJOL1-07hHdt, p1: Qs0J0I.AhR.brQjpYwUJqDNLk-zKd7FmG0g7gdd1, q1: VOAVwyrrdC7eIsjnVkqdpsqUfhprKzKriATFEOQI, pq: KtTWRcFQRKVgTJabGMgY-HAQWJ1TZGnOYw7NU.1K, p2: qb0H0MqNit0rLwk6CsC4Q2bxpCmBQ581eoGI39sr, q2: Sjsl-.MJJ3SK2.INLAJ-0R5BwlfG.tccIpxPFRtB, z1: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, w1: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, z2: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, w2: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, r1: FO3NXIQIi7TBFw1FqLRJYo13EA.uu4Y-L17Fmx0z, r2: HorxHsNCdpkm270yeTZ-vREjjFXWIYC99ALidDVU, r3: bWc33lXvXHIJXix5Jw2.Nhw0EIsv3TuAa7t8Ix5q, ra1: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, rb1: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, ra2: w8obIVknqdoKk.hDUN8TE2M-KiFh-yCCXtxNdrJ4, rb2: T0hCevYdBG6vWZ3R5Nba.jXacMTFFUW5OjOX4yAO, zz1: FB6W9j12qWZ34fUwyrBETzFuAXRB-xn7O1PGhr2j, ww1: IhchjkRfjLXpnsC6zl-TFugIQrnUIdB7Wsgpnely, zz2: LE5ohPby7q4dNu3qhqgucRcCt.pd87O.CyKWloqe, ww2: -RBf-UiccAG3sTH0UFC6C.YFmYcpTRA.0PFP6Oun, zzzz: Irbj-xVP8rEIPoylOTNmiuJ-lGdx0dpzIPgq-169, f: Some.arbitrary.identifier.with.length.40, zzz1: TBw0fUZZo1WlI9uczNuF0w4vC06u6YvzJyNPVEi1, www1: WqqXpIpMwinaXxYNqRjj4qttDcKXN.gcGjARpOSh, zzz2: .mJim0y-LMUYZi01GN8MTPkHj79JtFdREf7g40ug, www2: jwtsaf1IZMG6sWqprXZnc.n-ilyfncwhL3Qr.-Md } } >>> d["p1"] 243 >>> from hdict import value >>> d.evaluate() >>> d = hdict(x=2) >>> g = lambda x, y: [x + y, x / y] >>> d["z"] = apply(f, 2, y=3) >>> d["w", "v"] = apply(f, field("x"), y=33) >>> d["f"] = f >>> d = d >> apply(field("f"), field("x"), y=default(3), nonexistent_parameter=7)("w3", "v3") # todo: : nonexistent parameter should raise an exception >>> d >>= apply(field("f"), field("x"), y=default(3))("w", "v") >>> d["w2", "v2"] = apply(field("f"), field("x"), y=default(3)) >>> d >>= {"z": apply(f, field("x"), y=3), ("w", "v"): apply(g, y=7)} >>> d >>= apply(f, field("x"), y=3)("z9") * apply(g, y=7)("w9", "v9") >>> pp = apply(f, field("x"), y=3)("z") >> apply(g, y=7)("w", "v") >>> d >>= {"x": 3} >> pp >> apply(g, y=7)("w", "v") >>> from hdict import _ >>> a1 = apply(f, y=_(1, 2, 4, ..., 128)) >>> a2 = apply(f, _(0, 3, 6, ..., 9), y=_(0, 3, 6, ..., 9)) >>> ppp = hdict() >> a2.sample()("k", "t") >>> ppp.show(colored=False) { k: λ(9 9)→0, t: λ(9 9)→1, _id: dK-iumb4L5nkFVT9LCkdk3daQtuC.ORk6JwWMhnt, _ids: { k: rHTgwW.w2SsbcvBlSnWWddLH4vgyXlM1Fhxqr48f, t: IldA8m-uSN9lJcE4TBtjTcY-sSiA33mzxQ2k-wpN } } >>> ppp.k 387420489 >>> a1("z") z=λ(x y=~[1 2 .*. 128]) >>> a2(w="a", v="b") (('w', 'a'), ('v', 'b'))=λ(x=~[0 3 .+. 9] y=~[0 3 .+. 9]) >>> p = a1("z") >> a2(w="a", v="b") >>> h = lambda a, b=4: 5 >>> app = apply(h, a=_(0, 3, 6, ..., 9)) >>> app λ(a=~[0 3 .+. 9] b=default(4)) >>> app.c c=λ(a=~[0 3 .+. 9] b=default(4)) >>> sampled = app.sample(0).c >>> sampled c=λ(9 b=default(4)) >>> r = hdict() >> sampled >>> r.show(colored=False) { c: λ(9 b=4), _id: Bbe5mzn0oCuHZ.Y84-jaEnh3jcrgD8av6IZezKEG, _ids: { c: 6EehD7OoZe2REI.1YsVLKxSF4hJoYxfOZJLbF.Aj } } >>> r.evaluated.show(colored=False) { c: 5, _id: Bbe5mzn0oCuHZ.Y84-jaEnh3jcrgD8av6IZezKEG, _ids: { c: 6EehD7OoZe2REI.1YsVLKxSF4hJoYxfOZJLbF.Aj } } >>> from random import Random >>> rnd = Random(0) >>> p1 = p.sample(rnd) >>> d["w"] 10 >>> d >>= p1 >>> d["z"] = apply(f, 2, y=3) >>> d["w", "v"] = apply(f, _.x, y=_.x) >>> d["w", "v"] = apply(_.f, _.x, y=default(3)) >>> d = hdict() >> {"z": apply(f, 7, y=3), ("w", "v"): apply(g, default(6), y=7)} >>> d = hdict(w=6) >> (apply(f, _["w"], y=3)(z="z") >> apply(g, x=_(1,2,3,...,5), y=7)("ww", "v")).sample(0) >>> p = apply(f, y=_(1, 2, 4, ..., 128))("z") >> apply(f, y=_(0, 3, 6, ..., 9))(w="a", v="b") >>> d.show(colored=False) { w: 6, z: λ(x=w 3)→z, ww: λ(4 7)→0, v: λ(4 7)→1, _id: x4TxaVuAymsh97Yr.15Oc1ekllvlpECk091124RM, _ids: { w: CZ7Jm5fQMZ3fZJ3kAVOi0FYK-exFqPqgoYLsGxGl, z: No1nN40OXnJ.zOyAvoxwCjyD06cUDiXTZQh4q8xa, ww: qZepp.wpXCOYQrwnVIwoZ4kR9pIuMGDQpvRevv80, v: wxkjBSP54cKEfxKE1Zte-2dDll3G9Nd-yDh3CLas } } >>> d = hdict(x=3) >> p.sample(rnd) >>> d.show(colored=False) { x: 3, z: λ(x 16), w: λ(x 9)→a, v: λ(x 9)→b, _id: 22b-e.CtRGVSoMkektNzHYSVZTouhL2jAHLyPd4Q, _ids: { x: KGWjj0iyLAn1RG6RTGtsGE3omZraJM6xO.kvG5pr, z: 64cxw0HmJ0fydH7By6i0HrbuwA759XexTu3Bu0Zd, w: p1Z5umNo12DHCZtKbh2EClW6TZxv.M447HlALWhv, v: HbYbR1RjPdU4jixjW7xSxslRpYx9W6Oiay7maK6F } } >>> d1 = hdict(x=52, y=13) >>> d2 = hdict(x=value(52, hosh="1234567890123456789012345678901234567890")) >>> d1.show(colored=False) { x: 52, y: 13, _id: 5pwGP0LxQRbQaDEk9ztQ4V4qz.A-IIhVNTrcyt8U, _ids: { x: c.llz05T6ZXw5AlsU4xfmMxcvvHZhLl60LckZis9, y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s } } >>> d2.show(colored=False) { x: 52, _id: kYzgpPdRgQSYSEpp1qt4EHQLQJXuyb2WDQS-iNPh, _ids: { x: 1234567890123456789012345678901234567890 } } >>> d3 = d1 >> d2 >>> d3.show(colored=False) { x: 52, y: 13, _id: -EFuy5NAeK.LIALpBiZKK-fYQmc9AZYQQck-HiRK, _ids: { x: 1234567890123456789012345678901234567890, y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s } } >>> (d3 >> d1.frozen).show(colored=False) { x: 52, y: 13, _id: 5pwGP0LxQRbQaDEk9ztQ4V4qz.A-IIhVNTrcyt8U, _ids: { x: c.llz05T6ZXw5AlsU4xfmMxcvvHZhLl60LckZis9, y: zplslThZYha4haD2VmGxZqrFSw5RJcFJd2E-Ku6s } } >>> d = hdict(x=2, y=4) >>> {"x": 2, "y": 4} == d.frozen True >>> {"x": 2, "y": 4} == d True >>> d == {"x": 2, "y": 4} True >>> dict(d) {'x': 2, 'y': 4} >>> hdict() >> {"x": 3} == {"x": 3} True >>> {"x": 3, "d": {"x": 7}} == hdict(x=3, d=hdict(x=7)) True >>> hdict(x=3, d=hdict(x=7)) == {"x": 3, "d": {"x": 7}} True >>> {"x": 3, "_id": hdict(x=3).id} == hdict(x=3) True >>> hdict(x=3) == {"x": 3, "_id": hdict(x=3).id} True >>> hdict(x=3) == hdict(x=3) True >>> hdict(x=3).frozen == hdict(x=3) True >>> hdict(x=3) != {"x": 4} True >>> hdict(x=3) != hdict(x=4) True >>> hdict(x=3).frozen != hdict(x=4) True >>> hdict(x=3) != {"y": 3} True >>> hdict(x=3) != {"x": 3, "_id": (~hdict(x=3).hosh).id} True >>> hdict(x=3) != hdict(y=3) True >>> del d["x"] >>> list(d) ['y'] >>> e = d >> apply(lambda y: y*7)("y") >>> from hdict.content.aux_value import f2hosh >>> print(f2hosh(lambda y: y*7)) 54YCMDJIlsIvMQ.KJtT-vFyjg83Zgfj2xSHOgCj8 >>> print(e) {y: "λ(4)"} >>> e.evaluate() >>> print(e) {y: 28} >>> d = d >> apply(lambda y=1: y*7, fhosh="54YCMDJIlsIvMQ.KJtT-vFyjg83Zgfj2xSHOgCj8")("y") >>> print(d) {y: "λ(4)"} >>> d.evaluate() >>> print(d) {y: 28} >>> hash(e.frozen) == hash(d.frozen) True >>> d = hdict(a=5) >> hdict(y=28) >>> d.show(colored=False) { a: 5, y: 28, _id: C-xKyWCyBL6g32KIuxoANoF9czLaJTh-emPsMqOg, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9 } } >>> d >>= apply(lambda a: a)("x") >>> d.show(colored=False) { a: 5, y: 28, x: λ(a), _id: qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp } } >>> {"_id": "qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY"} == d True >>> d.show(colored=False) { a: 5, y: 28, x: λ(a), _id: qI8rmiUzMTSO1pMkCeQJpHTAOw4xuooFqM41iIiY, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp } } >>> def f(): ... print("busy") ... return 23 >>> storage = {} >>> d >>= apply(f).o >> cache(storage, "x", "y") >>> d.y 28 >>> d.show(colored=False) { a: 5, y: 28, x: ↑↓ cached at `dict`·, o: λ(), _id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp, o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo } } >>> d.evaluated.show(colored=False) busy { a: 5, y: 28, x: 5, o: 23, _id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp, o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo } } >>> d.evaluated.show(colored=False) { a: 5, y: 28, x: 5, o: 23, _id: 4FdTqXVIMKldUnZgrrp315c78KHD9yu7T.Nr5zGv, _ids: { a: ecvgo-CBPi7wRWIxNzuo1HgHQCbdvR058xi6zmr2, y: -2A0hTRBN1wtIKQxLzRcYDBkhv1hu-dMY-24Jye9, x: sxkIk6E9l8oScCyoGDlzrqJ9QgpIpl5PCBvHlERp, o: Re1o0YXNebYNezPrVv2dOrFxtgLQutD-b-SHFRbo } } """
Ancestors
- hdict_
- builtins.dict
Inherited members
class sample (*values: list[int | float], rnd: int | random.Random = 0, maxdigits=28)
-
A lazily evaluated list of values
>>> (s := sample(1, 2, 3, ..., 9).values) [1 2 .+. 9] >>> (s := sample(2, 4, 8, ..., 1024).values) [2 4 .*. 1024] >>> (s := sample(2, -4, 8, ..., 12).values) [2 -4 8]
Expand source code
class sample(AbsMetaArgument): """ A lazily evaluated list of values >>> (s := sample(1, 2, 3, ..., 9).values) [1 2 .+. 9] >>> (s := sample(2, 4, 8, ..., 1024).values) [2 4 .*. 1024] >>> (s := sample(2, -4, 8, ..., 12).values) [2 -4 8] """ sampleable = True def __init__(self, *values: list[int | float], rnd: int | Random = 0, maxdigits=28): self.rnd = rnd # todo: : accept list of non numeric types (categoric)? prog = list2progression(values, maxdigits=maxdigits) if prog.n.is_infinite(): # pragma: no cover raise Exception(f"Cannot sample from an infinite list: {prog}") self.values = prog def sample(self, rnd: int | Random = None): if rnd is None: rnd = self.rnd if isinstance(rnd, int): rnd = Random(rnd) if not isinstance(rnd, Random): # pragma: no cover raise Exception(f"Sampling needs an integer seed or a Random object.") idx = rnd.randint(0, self.values.n - 1) return value(self.values[idx]) def __repr__(self): return f"~{self.values}"
Ancestors
Class variables
var sampleable
Methods
def sample(self, rnd: int | random.Random = None)
-
Expand source code
def sample(self, rnd: int | Random = None): if rnd is None: rnd = self.rnd if isinstance(rnd, int): rnd = Random(rnd) if not isinstance(rnd, Random): # pragma: no cover raise Exception(f"Sampling needs an integer seed or a Random object.") idx = rnd.randint(0, self.values.n - 1) return value(self.values[idx])
class value (val: object, hosh: hosh.hosh_.Hosh | str = None, hdict=None)
-
Wrapper for any Python object except AbsAny instances
>>> x = 5 >>> from hdict.content.value import value >>> v = value(x, "1234567890123456789012345678901234567890") >>> v 5 >>> v.hosh.id '1234567890123456789012345678901234567890'
Args
- val:
- hosh:
hdict
- optional reference to the object if it has a hdict counterpart (e.g.: pandas DF)
Expand source code
class value(AbsBaseArgument, AbsEntry): """ Wrapper for any Python object except AbsAny instances >>> x = 5 >>> from hdict.content.value import value >>> v = value(x, "1234567890123456789012345678901234567890") >>> v 5 >>> v.hosh.id '1234567890123456789012345678901234567890' """ isevaluated = True def __init__(self, val: object, hosh: Hosh | str = None, hdict=None): """ Args: val: hosh: hdict: optional reference to the object if it has a hdict counterpart (e.g.: pandas DF) """ from hdict.abs import AbsAny if isinstance(val, AbsAny): # pragma: no cover raise Exception(f"Cannot handle objects of type '{type(val).__name__}' as raw values for hdict.") self.value = self._value = val if isinstance(hosh, str): hosh = Hosh.fromid(hosh) self.hosh = v2hosh(self.value) if hosh is None else hosh self.hdict = hdict def __repr__(self): return repr(self.value)
Ancestors
Inherited members