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

Set Printing #7153

Closed
samuelcolvin opened this issue Jun 6, 2014 · 20 comments
Closed

Set Printing #7153

samuelcolvin opened this issue Jun 6, 2014 · 20 comments
Labels
domain:display and printing Aesthetics and correctness of printed representations of objects. good first issue Indicates a good issue for first-time contributors to Julia

Comments

@samuelcolvin
Copy link
Contributor

Currently if you display a Set the entire thing is slammed to STDOUT, if it's very long it can take ages/fill up the shell.

Shouldn't Sets have a pretty show function that chops out some elements same as arrays?

@stevengj
Copy link
Member

stevengj commented Jun 6, 2014

Yes. Although it shouldn't be show: the pretty/truncated output should be for writemime(io, ::MIME"text/plain", x::Set)

@stevengj
Copy link
Member

stevengj commented Jun 6, 2014

I'm tempted to write something very similar to the matrix output:

import Base: writemime, with_output_limit, print_matrix

function writemime(io::IO, ::MIME"text/plain", S::Set)
    print(io, summary(S))
    if !isempty(S)
        println(io, ":")
        with_output_limit(()->print_matrix(io, sort!([x for x in S])))
    end
end

This produces nice-looking, sorted, truncated output. It is Θ(length(S) * log(length(S))) complexity, but since the current show method is Θ(length(S)) it isn't much of a regression.

@stevengj
Copy link
Member

stevengj commented Jun 6, 2014

If we are worried about the overhead of making a copy of S etc. for really huge sets (gigabytes), there could be a threshold size over which it just makes an array of the first 1000 elements of S and prints those, unsorted. For example, modify the above to:

import Base: writemime, with_output_limit, print_matrix

function writemime{T}(io::IO, ::MIME"text/plain", S::Set{T})
    print(io, summary(S))
    if !isempty(S)
        println(io, ":")
        if length(S) > 10^7
            A = copy!(Array(T, 1000), 1, S, 1, 1000)
        else
            A = sort!(T[x for x in S])
        end
        with_output_limit(()->print_matrix(io, A))
    end
end

@stevengj
Copy link
Member

stevengj commented Jun 7, 2014

Though I guess you would only want to sort! if method_exists(isless, (T, T)).

@samuelcolvin
Copy link
Contributor Author

Surely it's not canonical to sort the set prior to printing it?

It might confuse people thinking the set is actually sorted. Best and easiest just to pump it out as it comes.

@stevengj
Copy link
Member

stevengj commented Jun 8, 2014

The set elements are unordered, so it is equally valid to print them in any order we want. So why not print it in an order where it is much easier to see what is in the set.

Quiz: with which ordering is it easier to tell what is in the following set:

 30  32  2  16  26  10  8  22  6  24  4  28  20  14  12  18

or

 2  4  6  8  10  12  14  16  18  20  22  24  26  28  30  32

?

Especially if we are going to print only a subset of the set, it is much more useful to print the largest and smallest elements (as in my code above) than it is to print some random selection of elements.

@samuelcolvin
Copy link
Contributor Author

Fail point it would be easier, but you will get people thinking the set is naturally sorted. I suppose that's just the way it is.

I suppose it just needs to be clear in the docs what a set is and isn't.

@samuelcolvin
Copy link
Contributor Author

How do we make this happen? Shall I submit a pull request?

@stevengj
Copy link
Member

Sure.

samuelcolvin added a commit to samuelcolvin/julia that referenced this issue Jun 10, 2014
@ihnorton ihnorton added the good first issue Indicates a good issue for first-time contributors to Julia label May 8, 2015
@pkofod
Copy link
Contributor

pkofod commented Feb 25, 2016

This seems fixed? Or am I misunderstanding what the issue is?

Set(map(x->x^2,1:4:356))
Set([8649,31329,47089,1369,2401,108241,289,27225,43681,625    50625,66049,11881,83521,119025,48841,11025,93025,841,34225])

@samuelcolvin
Copy link
Contributor Author

The output still doesn't appear to be ordered correctly.

@pkofod
Copy link
Contributor

pkofod commented Feb 25, 2016

I figured they weren't supposed to be ordered, as you argued for yourself. In that case, more work is needed. Is there an easy way to see which writemime is called?

@samuelcolvin
Copy link
Contributor Author

you're right I argued order doesn't matter but as @stevengj said order makes checking for the presence of a value visually much much easier.

@pkofod
Copy link
Contributor

pkofod commented Feb 25, 2016

Okay. The question remains, how will you sort

 Set(Any[linspace(1,4,240), 3, rand(20,30), rand(3), "a", 'a'])

? :)

(which by the way looks a lot better than Any[linspace(1,4,240), 3, rand(20,30), rand(3), "a", 'a'] on my computer)

@stevengj
Copy link
Member

@pkofod, since there is no isless method for Any, you wouldn't sort in that case.

@pkofod
Copy link
Contributor

pkofod commented Feb 25, 2016

Okay, so

if method_exists(isless, (T, T))
show a sorted version
else
show unsorted version
end

That makes sense. What is the easiest way to find the writemime method for a given type @stevengj ? I'm finding it a bit hard to see what takes care of Set{T}. Is there a tool like @which for functions, but which shows the writemime being used?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Mar 25, 2016

cross-link with #14052

@JeffBezanson JeffBezanson added the domain:display and printing Aesthetics and correctness of printed representations of objects. label Jan 3, 2017
@zslie
Copy link

zslie commented Dec 27, 2018

Didn't mean to spam this issue - I jacked up the commit message and did not know it would link before creating the pull request.

@JeffBezanson
Copy link
Sponsor Member

I think the problem with sorting is that a set has to iterate its elements in some order, so when we print it we should show what that order is.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Jun 26, 2019

Shouldn't Sets have a pretty show function that chops out some elements same as arrays?

As noted above by #7153 (comment), this is fixed:

julia> Set(1:1000)
Set([306, 29, 74, 905, 176, 892, 285, 318, 873, 975    632, 618, 341, 186, 321, 420, 6, 856, 322, 218])

Also, consensus (by bureaucratic delay) seems to be against adding ordering to the printing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:display and printing Aesthetics and correctness of printed representations of objects. good first issue Indicates a good issue for first-time contributors to Julia
Projects
None yet
Development

No branches or pull requests

8 participants