Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

random_namedtuple #34

Open
cscherrer opened this issue Dec 21, 2020 · 1 comment
Open

random_namedtuple #34

cscherrer opened this issue Dec 21, 2020 · 1 comment

Comments

@cscherrer
Copy link
Contributor

Hi @JeffreySarnoff , I'd like to contribute some of the things I've been working on lately. First up:

"""
    random_namedtuple(width, depth; names='a':'z')

Generate a random nested named tuple. This is useful for tests.

Example:

    julia> randnt(3,3)
    (e = (o = (l = :l, e = :e, s = :s), d = (x = :x, e = :e, a = :a), a = (i = :i, u = :u, d = :d)), 
    f = (b = (y = :y, k = :k, o = :o), a = (b = :b, f = :f, k = :k), z = (j = :j, b = :b, u = :u)), 
    t = (b = (q = :q, k = :k, s = :s), c = (d = :d, u = :u, a = :a), h = (u = :u, c = :c, m = :m)))
"""
function random_namedtuple(width, depth; names='a':'z')
    k = unique(Symbol.(rand(names, width)))
    if depth  1
        return namedtuple(k)(k)
    else
        nts = Tuple((randnt(width, depth-1; names=names) for _ in 1:length(k)))
        return namedtuple(k)(nts)
    end
end 

Any thoughts on this? If you like it, where should it go?

@JeffreySarnoff
Copy link
Owner

JeffreySarnoff commented Jan 10, 2021

Thank you. Some thoughts:

We should strive to comport with the interface to Random.rand.

To generate symbols that serve as names, we can do something like

const LCASE = collect('a':'z');

function symbol(nchars::Int=1, offset::Int=0)
  nchars = max(1, min(26, nchars))
  ofs  = max(0, min(offset, 26-nchars))
  return Symbol(join(LCASE[1+ofs:nchars+ofs]))
end

symbols(n ,width; randwidth::Bool=false) = 
  randwidth ? [symbol(rand(1:width), i) for i=0:n-1] : [symbol(width, i) for i=0:n-1]

if the values are the same as the names (for simplicity)

function rand(::Type{NamedTuple}, n::Int)
  nchars = (div(n, 26) + 1)
  syms = Tuple(symbols(n, nchars))
  return NamedTuple{syms}(syms)
end

however also using Ints for values should be supported, at minimum

rand(NamedTuple, n; nesting::Int=0, randnest::Bool=false)
should be built on above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants