Hacker News new | past | comments | ask | show | jobs | submit login
Spark (github.com/holman)
568 points by lrvick on Nov 15, 2011 | hide | past | favorite | 95 comments



Just did a Haskell version of spark. It supports in 9 lines of code (exclude comment + empty line) Double instead of just Int. Negative numbers.

https://github.com/Mgccl/mgccl-haskell/blob/master/random/sp...


Same features. 4 SLoC of Ruby :)

https://gist.github.com/1367091


'floor' on last line should be changed to 'round'.

  ▁▁▁▁▁▁▂▂▂▂▂▂▃▃▃▃▃▃▅▅▅▅▅▅▆▆▆▆▆▆▇ = floor
  ▁▁▁▂▂▂▂▂▂▃▃▃▃▃▃▅▅▅▅▅▅▆▆▆▆▆▆▇▇▇▇ = round


Thanks! Much better.


And here's a PowerShell version. (Use PowerShell ISE as PowerShell normal prompt doesn't support unicode).

http://pastie.org/2867807

[edit: updated, careless variable rename, thanks jcromartie]


$stats should be $minmax


I made my own Sparks in C. They look like Sparks.

https://gist.github.com/1368661


My horrible php version :) https://gist.github.com/1368025


I really like your version. Very neat!


Here's a Haskell version that uses a single loop to do the normalizing, and has a main that doesn't use do syntax. This was mostly a nice little brainteaser:

https://gist.github.com/1367709

mapNormalize takes a function, and produces a function that runs that function with the normalized input. It runs in a single iteration, rather than 2 maps. Credit to `dylex` for much hand holding on a single iteration normalizer :)


Because Haskell is evaluated lazily, two maps doesn't imply two iterations over the data. In this case, I would expect only one pass through the data for both of the maps. Out of curiosity, I did a quick criterion benchmark for both functions. Here's the result on a list of 100 elements:

  benchmarking spark_mggcl
  mean: 49.29483 us, lb 48.77776 us, ub 50.25594 us, ci 0.950
  std dev: 3.495423 us, lb 2.140951 us, ub 6.373469 us, ci 0.950

  benchmarking spark_ocharles
  mean: 60.12347 us, lb 58.95586 us, ub 61.48084 us, ci 0.950
  std dev: 6.434853 us, lb 5.529613 us, ub 7.824865 us, ci 0.950 
The simpler version appears to be faster.

(As an aside, is there something in particular you dislike about do syntax? I find that it often makes things more readable, though slightly more verbose.)


I am aware of that, as I said this was more a mental exercise. normalizeMap is harder to understand, but it was interesting to write - it wasn't meant to be a stab at your code or claim it's better :)

In terms of do syntax, I try and avoid that because I find it detracts from the overall flow of data. With: "putStrLn . spark . map read =<< getArgs" I find it easy to see that main doesn't do much other than transform the users input. maybe a personal preference thing though...


Updated. thx to gwern. Now I know the existence of hlint.

Now, without the type declaration, white space, comments, it's only 6 lines, and looks even better. :)


This is pretty cool. Unfortunately it's coupled with some of the more obnoxious documentation I have seen recently. While the docs aren't very long, I had to read through a third of it to figure out simply what Spark is.

I'm all for being cute, but it shouldn't come at the cost of a basic understanding of what the program actually does and is useful for.



Excellent. Does a great job of clarifying.


Unfortunately, the maintainer didn't like it as much as you.


This is a totally fair complaint. Sometimes it is a mystery to me why HN-ers downvote things.


In all seriousness: some folks on HN (not all) seem to be the guard in the center of the panopticon.

If you could see a list of who downvoted you, I'd bet that something interesting would happen.

I almost expect to come back and see my karma drop as a result of this comment.


I think having downvotes public is an intersting idea. It would certainly force people to justify their downvotes, anyway.


The script is not a proper POSIX bourne shell script, as it uses arrays.

For starters, it won't work in dash (Debian and Ubuntu /bin/sh implementation). So the shebang line should be changed to #!/bin/bash (not sure if it would work in Zsh either).


Maybe this shouldn't be a shell script. A C implementation would be quite portable and also pretty fast.


Fork and fix please!


... and send a pull-request, so everyone can share the happy.


Already done, and someone even did a better fix:

https://github.com/holman/spark/pull/8


NetBSD seriously doesn't put bash in /bin? That's just broken by design.


I can't speak to NetBSD, but FreeBSD doesn't put any user-installed programs in /bin or /usr/bin, they all go into /usr/local. Since bash isn't distributed as part of the base system, it goes into /usr/local/bin/bash


So then how do you write cross-platform scripts? You can't even do "#!/usr/bin/env bash" since I'm assuming what you're saying means 'env' is in /usr/local/ as well, but on Linux systems it'll be in /usr/.

Broken! Can we please just pick one convention and stick with it? Oh, standards... so many to choose from.


This reminds me of another useful utility from the childhood:

alias updick='/usr/bin/uptime | perl -ne "/(\d+) d/;print 8,q(=)x\$1,\"D\n\""'


You cracked my office up. Deploying to production immediately.


The dick grows depending on how long the system has been running?


Exactly. Kinda measure of how strong is sysadmin.


I'm curious: is there a reason U+2584 LOWER HALF BLOCK is missing from the character set, which otherwise contains the progression from U+2581 to U+2587?

Edit: U+2588 seems like an obvious candidate as well.


No idea. Here they are for everyone's use:

ticks = " ▁▂▃▄▅▆▇█"

I've included SPACE as well. That's an obvious missing one.


At least in my OS/X terminal using the "Monaco" font (which I think is the default), the final one (U+2588) doesn't descend as far as the rest of the characters. It really produces some ugly output with that one included.

Including the space character means that you lose a nice baseline if the input is fairly sparse, so it looks less like a bar graph and more like just some random blobs.


Yes, on the mac it seems only menlo renders it correctly, (vs all the other fixed with font families that bork the rendering in various ways)


Ah, as inspired by Edward ttyfte.


That ^ is why HN needs a LOL button :)

http://img819.imageshack.us/img819/264/hnlol.png

(edit) Ah, the downvoting frenzy! 4601 karma points to go. Bring it on, fellow HNers. Don't forget to quote the guidelines and to lecture me too as no bashing is complete without showing some smug superiority with a hint of righteousness.


Would you please not do this?


I was about to upvote compensate you before I read your edit.


Well. When I posted the above comment, its parent was lingering at the very bottom of the page. Then it quickly floated to the top, and after that mine got as quickly downvoted into oblivion. Interesting dynamic in itself.

Right now the karma counter keeps oscillating around 4600... which makes me regret that I didn't say it was 4701 :)


I rewrote it in C, so it's faster and can work more efficiently on different data sets. It also uses a prettier algorithm for determining heights. Have fun:

http://git.zx2c4.com/spark/tree/spark.c

    $ git clone http://git.zx2c4.com/spark
    $ cd spark
    $ make
    $ ./spark 1 4 2 8 14
    ▂▃▂▅█
    $ curl -s http://earthquake.usgs.gov/earthquakes/catalogs/eqs1day-M1.txt | cut -d, -f9 | ./spark
    ▂▃▄▃▃▃▄▃▇▃▄▄▄▅▃▄▄▄▅▅▅▄▄▄▃▃▃▃▃▄▃▄█▅▄▄▄▄▃▇▄▄▄█▄▃▄▄▄▄▃▃▄▅▄▅▃▃▃▃▇▄▅▄▇▃▅▃▄▃▄▃▇▃▃▄▇▃▄▃▄▃▃▃▄▃▃▃▃▃▃▅▃▄▃▃


Nice: found a sparkline generator at http://sandbox.kidstrythisathome.com/louis/ :

⡠⠞⠉⠙⠦⣀⠴⠋⠉⠳⢄⡠⠞⠉⠙⠦⣀⠴⠋⠉⠳⢄


Needs a lot more characters to handle height progressions and angles better, but that's awesome.


Hmm, I get the following:

  [scotty@Scotty-Allens-MacBook-Air ~/bin]$ spark 1,2,3,4,5
  ▇\c
  ▇\c
  ▇\c
  ▇\c
  ▇\c
I suspect this has something to do with my terminal settings, but I'm not sure quite what...

Nifty idea, regardless.


add a '-e' after 'echo' on line 120


Try changing line 120 to

  echo -e $"$(print_tick $number)\c"
And it should work fine.


I found it necessary to escape the backslash

         echo -e $"$(print_tick $number)\\c"



The "\c" escape sequence makes the -n unnecessary (as I discovered while reading "help echo").


https://github.com/holman/spark/pull/4

(in addition to line 120, there are some "\n"s in the help)


I've quickly looked at the link, read the reviews here, and there's actually no description of what spark _is_. I gather is an UTF-8 graph generator.


Sparklines Wikipedia page: http://en.wikipedia.org/wiki/Sparkline

spark, the linked project, is just an implementation of a sparkline generator for the command line.


Thanks! First time I've heard of "sparkline". Of course I've seen these items for as long as I can remember, but I just call them "graphs". :P


A sparkline is a specific type of graph used for certain types of data. The wiki page is pretty clear with the uses and limitations.

Not all graphs are created equal, it's important to use the right tool for the job. This tool isnt just a graph generator, it's a spark bar chart generator that's compact enough to fit in the command line. Overall a cool idea.


I feel like I'm being reprimanded. Forgive me if I'm mistaken.

> A sparkline is a specific type of graph

My point is this should be explained _somewhere_. Anybody else unfamiliar with sparklines will now have the benefit of this thread. Previously, to me anyway, it was a mystery.

> The wiki page is pretty clear with the uses and limitations.

It is. It was only presented upon my initial query, and am grateful to @IgorPartola for providing!

> Not all graphs are created equal, it's important to use the right > tool for the job. This tool isnt just a graph generator, > it's a > spark bar chart generator that's compact enough to fit in > the > command line. Overall a cool idea.

It is, indeed. My initial note wasn't about the coolness of the project, just "what _is_ the project"? Is clear now. Anybody else who is ignorant about sparklines as I was, enjoy this thread!


Cool. I also like that he set up a wiki where people can contribute interesting spark one liners:

https://github.com/holman/spark/wiki/Wicked-Cool-Usage


All involve awk or sed. That cuts out a large portion of the potential userbase...

Perhaps common uses could be wrapped in options to the script? For instance, an option to graph numbers on separate lines, to graph all numbers in the input in order, to graph a specific column of information (like passing through cut first) or to graph commonly graphed sources?


I feel like they're examples of really awesome use cases, so it shouldn't matter if people can't use them. Not to mention, I feel like this tool is targeted for terminal junkies who likely already have awk/sed.


Basically. Are there very many people who would generate sparklines, using a sh program - somewhere that has sh but not awk or sed?



Sparklines are cool. This is just a bar graph and not nearly as useful.


So, because you can't deviate below the x axis this is really that much less useful?


This also doesn't meet the high resolution part of Tufte's definition ("a small intense, simple, word-sized graphic with typographic resolution"[1]).

[1]: http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0...


They're comparatively higher density...


This gives you eight levels (plus blank)[1]. Most of the type I read is at least twice that many pixels high.

[1]:https://github.com/holman/spark/blob/master/spark#L46


Tufte honestly thinks pixelated type is pretty terrible, too. 16 pixel density is embarrassing compared to printed or pressed text.

But in either case, it's obvious that's a silly argument. Trends posterized to 8 levels are far easier to read in "sparkbar" form than as a list of numbers. It's suboptimal, but better than the plain list.


You must admit the horizontal resolution is quite low as well


I hooked this up to my homebrew cohort-analysis script and saw a gratifying terminal hockeystick :D


a bit more efficient, and without the comma requirement

https://gist.github.com/1366926


Because I want my shell prompt to be a giant graph.

▁▁▁▁▅▁▇▁▁▅▁▁▁▁▁▂▂▁▃▃▁▁▃▁▃▁▂▁▁▂▂▅▂▃▂▃▃▁▆▃▃▃▁▇▁▁▂▂▂▇▅▁▂▂▁▇▁▃▁▇▁▂▁▇▁▁▆▂▁▇▁▂▁▁▂▅▁▂▁▆▇▇▂▁▂▁▁▁▂▂▁▅▁▂▁▁▃▁▃▁▁▁▃▂▂▂▁▁▅▂▁▁▁▁▂▂▁▁▁▂▂$

Ship it.


Does HN really not have any protection against comments that are very long single words that screw up the page width?


What would be really interesting is finding out which decent programming fonts can show block elements. I mean, beyond the DejaVu Sans Mono fiasco.



This is what I've been using (after more than a year with DejaVu Sans Mono) and I sometimes still stop to admire my terminal ;)

Using #e8e8e8 instead of pure white for the text color helps too.


Doesn't seem to be able to display the block characters neither on PuTTY, gvim on Windows or my Linux terminals/editors. Am I missing something obvious here?


You'll have difficulty on Windows if you use PuTTY, since it doesn't do font substitution.


Are there any Windows SSH programs that display? I get nothing but garbage or "." characters for any of the symbols.


Just tried on mintty, doesn't work there either.


schumacher clean works (i can cut + paste the title of this post to my shell) - it's a bitmap font that's been in X forever.

and has anyone worked out how to get recent cpu load into their bash prompt yet?


Liberation Mono and Terminus both work.



thanks. here's a couple bugfixes. fixed width calc & handles negative #s

https://gist.github.com/1368454


Here's a port of it to Python already live:

https://github.com/kennethreitz/spark.py



I would rather it took a number, one per line from stdin. Great idea though.


Try this:

    alias spark='tr "\\n" "," | xargs spark'


Everyone want a different delimiter... Hence, I filed https://github.com/holman/spark/issues/23


had basically the same idea a while back - but would have used standard ascii characters and written it in c... still cool though!


this should be utf-8 supported.


cool, but:

$ spark 3,4,9 ▃▇▇

huh?


A fixed bug https://github.com/holman/spark/issues/19 With HEAD:

    $ spark 3 4 9
    ▃▄▇


Holman never fails to impress


Blogs on swearing are so last week. This week is Holman week.

Just an observation.


This is sort of useless. Giving visual meaning to a bunch of numbers means nothing. It's just a bunch of numbers.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: