Stream: helpdesk (published)

Topic: first and last of range


view this post on Zulip Júlio Hoffimann (Feb 26 2021 at 18:20):

Given a range r = 0.5:10.0 how do we recover the first and last as typed?

first(r) # ok this is 0.5
last(r) # not ok this is 9.5

view this post on Zulip Expanding Man (Feb 26 2021 at 18:21):

You can't, it computes this when it first constructs the type. What you happened to type in is lost.

view this post on Zulip Mason Protter (Feb 26 2021 at 18:30):

It's like asking "suppose I type x = round(1.5), how do I get back 1.5?"

view this post on Zulip Júlio Hoffimann (Feb 26 2021 at 18:37):

I get it, just wanted to double check. I am trying to write a function slice(obj, ranges...) that is implemented in terms of a bounding box view(obj, Box(first.(ranges), last.(ranges)) and because the last is not the same as the one typed by the user the behavior is unexpected :confused:

view this post on Zulip Mason Protter (Feb 26 2021 at 18:38):

yeah, it's certainly a reasonable question!

view this post on Zulip Júlio Hoffimann (Feb 26 2021 at 18:39):

There is no workaround for this?

view this post on Zulip Júlio Hoffimann (Feb 26 2021 at 18:39):

How could I enforce the same range given a range object?

view this post on Zulip Júlio Hoffimann (Feb 26 2021 at 18:40):

I think I will just add a warning to the doc string in this case. It is easier. Users can remediate the situation with a buffer.

view this post on Zulip Expanding Man (Feb 26 2021 at 18:41):

Not with this type, you'd need to create a new type for it. I'm not really following what you're trying to do, but I suspect if I were you I would not want to echo what the user typed in, but instead the actual underlying state of the thing. If you show them what they typed in, you will not actually be showing them the bound of the range.

view this post on Zulip Mason Protter (Feb 26 2021 at 18:42):

you could do:

julia> function (:)(x, y)
           col = Base.:(:)(x, y)
           if col[begin] != x || col[end] != y
               throw("don't do that")
           end
           col
       end
: (generic function with 1 method)

julia> 0.5:10
ERROR: "don't do that"
Stacktrace:
 [1] :(x::Float64, y::Int64)
   @ Main ./REPL[2]:4
 [2] top-level scope
   @ REPL[3]:1

view this post on Zulip Mason Protter (Feb 26 2021 at 18:42):

Or something similar

view this post on Zulip Mason Protter (Feb 26 2021 at 18:43):

A note about rounding in the docstring would be a good idea.

view this post on Zulip Expanding Man (Feb 26 2021 at 18:43):

oh yeah, that's a much better option; I was confused about whether you just wanted a different display behavior or whether you want to throw an error for rangers with a bound the doesn't correspond to the end. Throwing an error seems far more reasonable

view this post on Zulip Mark Kittisopikul (Feb 27 2021 at 00:03):

If you want to guarantee the endpoints of the range, I suggest using length rather than step.

julia> range(0.5, 10; length = 11)
0.5:0.95:10.0

In Julia 1.7, you will be able to specify length as the third positional argument.

julia> range(0.5, 10, 11)
0.5:0.95:10.0

view this post on Zulip Mark Kittisopikul (Feb 27 2021 at 00:07):

If what you want is to just memoize the two numbers, may I suggest Pair?

julia> p = 0.5 => 10
0.5 => 10

julia> first(p)
0.5

julia> last(p)
10

I created something of a rogue package to experiment with different range concepts if you are interested. One of those forms accepts a Pair:
https://github.com/mkitti/Ranges.jl

view this post on Zulip Júlio Hoffimann (Feb 27 2021 at 00:47):

In this use case users will not use ranges like this, they will probably write slice(obj, 0.5:10.0, 0.5:10.0). I just added a warning to the docstring.


Last updated: Oct 02 2023 at 04:34 UTC