Skip to content

Instantly share code, notes, and snippets.

@mndrake
Created April 30, 2014 15:19
Show Gist options
  • Save mndrake/ae7dc2a0b5ecbbf397cf to your computer and use it in GitHub Desktop.
Save mndrake/ae7dc2a0b5ecbbf397cf to your computer and use it in GitHub Desktop.
Draft of Formatted Deedle objects in IFSharp notebook
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"language": "fsharp",
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"#N \"Deedle/1.0.0-alpha2/pre\"\n",
"#N \"FSharp.Formatting\"\n",
"\n",
"open Deedle\n",
"\n",
"// based on https://github.com/tpetricek/Deedle/blob/mainline/docs/tools/formatters.fsx\n",
"\n",
"module DeedleFormatter =\n",
"\n",
" open System.IO\n",
" open Deedle.Internal\n",
" open FSharp.Literate\n",
" open FSharp.Markdown\n",
" \n",
" // --------------------------------------------------------------------------------------\n",
" // Implements Markdown formatters for common FsLab things - including Deedle series\n",
" // and frames, F# Charting charts and System.Image values\n",
" // --------------------------------------------------------------------------------------\n",
" // How many columns and rows from frame should be rendered\n",
" let startColumnCount = 3\n",
" let endColumnCount = 3\n",
" let startRowCount = 8\n",
" let endRowCount = 4\n",
" // How many items from a series should be rendered\n",
" let startItemCount = 5\n",
" let endItemCount = 3\n",
" \n",
" // --------------------------------------------------------------------------------------\n",
" // Helper functions etc.\n",
" // --------------------------------------------------------------------------------------\n",
" /// Extract values from any series using reflection\n",
" let (|SeriesValues|_|) (value : obj) = \n",
" let iser = value.GetType().GetInterface(\"ISeries`1\")\n",
" if iser <> null then \n",
" let keys = \n",
" value.GetType().GetProperty(\"Keys\").GetValue(value) :?> System.Collections.IEnumerable\n",
" let vector = value.GetType().GetProperty(\"Vector\").GetValue(value) :?> IVector\n",
" Some(Seq.zip (Seq.cast<obj> keys) vector.ObjectSequence)\n",
" else None\n",
" \n",
" /// Format value as a single-literal paragraph\n",
" let formatValue def = \n",
" function \n",
" | Some v -> [ Paragraph [ Literal(v.ToString()) ] ]\n",
" | _ -> [ Paragraph [ Literal def ] ]\n",
" \n",
" /// Format body of a single table cell\n",
" let td v = [ Paragraph [ Literal v ] ]\n",
" \n",
" /// Use 'f' to transform all values, then call 'g' with Some for \n",
" /// values to show and None for \"...\" in the middle\n",
" let mapSteps (startCount, endCount) f g input = \n",
" input\n",
" |> Seq.map f\n",
" |> Seq.startAndEnd startCount endCount\n",
" |> Seq.map (function \n",
" | Choice1Of3 v | Choice3Of3 v -> g (Some v)\n",
" | _ -> g None)\n",
" |> List.ofSeq\n",
" \n",
" // Tuples with the counts, for easy use later on\n",
" let fcols = startColumnCount, endColumnCount\n",
" let frows = startRowCount, endRowCount\n",
" let sitms = startItemCount, endItemCount\n",
" \n",
" let getHtml (value : obj) = \n",
" match value with\n",
" | SeriesValues s -> \n",
" // Pretty print series!\n",
" let heads = \n",
" s |> mapSteps sitms fst (function \n",
" | Some k -> td (k.ToString())\n",
" | _ -> td \" ... \")\n",
" \n",
" let row = \n",
" s |> mapSteps sitms snd (function \n",
" | Some v -> formatValue \"N/A\" (OptionalValue.asOption v)\n",
" | _ -> td \" ... \")\n",
" \n",
" let aligns = s |> mapSteps sitms id (fun _ -> AlignDefault)\n",
" [ InlineBlock \"<div class=\\\"deedleseries\\\">\"\n",
" TableBlock(Some((td \"Keys\") :: heads), AlignDefault :: aligns, [ (td \"Values\") :: row ])\n",
" InlineBlock \"</div>\" ]\n",
" |> Some\n",
" | :? IFrame as f -> \n",
" { // Pretty print frame!\n",
" new IFrameOperation<_> with\n",
" member x.Invoke(f) = \n",
" let heads = \n",
" f.ColumnKeys |> mapSteps fcols id (function \n",
" | Some k -> td (k.ToString())\n",
" | _ -> td \" ... \")\n",
" \n",
" let aligns = f.ColumnKeys |> mapSteps fcols id (fun _ -> AlignDefault)\n",
" \n",
" let rows = \n",
" f.Rows\n",
" |> Series.observationsAll\n",
" |> mapSteps frows id (fun item -> \n",
" let def, k, data = \n",
" match item with\n",
" | Some(k, Some d) -> \n",
" \"N/A\", k.ToString(), Series.observationsAll d |> Seq.map snd\n",
" | Some(k, _) -> \n",
" \"N/A\", k.ToString(), f.ColumnKeys |> Seq.map (fun _ -> None)\n",
" | None -> \" ... \", \" ... \", f.ColumnKeys |> Seq.map (fun _ -> None)\n",
" \n",
" let row = \n",
" data |> mapSteps fcols id (function \n",
" | Some v -> formatValue def v\n",
" | _ -> td \" ... \")\n",
" \n",
" (td k) :: row)\n",
" Some [ InlineBlock \"<div class=\\\"deedleframe\\\">\"\n",
" TableBlock(Some([] :: heads), AlignDefault :: aligns, rows)\n",
" InlineBlock \"</div>\" ] }\n",
" |> f.Apply\n",
" | _ -> None\n",
" \n",
" |> function\n",
" | Some pars -> \n",
" let doc = MarkdownDocument(pars, null)\n",
" Markdown.WriteHtml(doc)\n",
" | None -> value.ToString()\n",
" \n",
"App.AddFsiPrinter(fun (x:Deedle.Internal.IFsiFormattable) ->\n",
" App.Kernel.Value.SendDisplayData(\"text/html\", DeedleFormatter.getHtml(box x))\n",
" DeedleFormatter.getHtml(box x))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"NuGet package: Deedle"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"Referenced: C:\\Github\\ProjectEuler\\notebooks\\packages\\Deedle.1.0.0-alpha2\\lib\\net40\\Deedle.dll"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"NuGet package: FSharp.Formatting"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"Referenced: C:\\Github\\ProjectEuler\\notebooks\\packages\\FSharp.Formatting.2.4.8\\lib\\net40\\CSharpFormat.dll"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"Referenced: C:\\Github\\ProjectEuler\\notebooks\\packages\\FSharp.Formatting.2.4.8\\lib\\net40\\FSharp.CodeFormat.dll"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"Referenced: C:\\Github\\ProjectEuler\\notebooks\\packages\\FSharp.Formatting.2.4.8\\lib\\net40\\FSharp.Literate.dll"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"Referenced: C:\\Github\\ProjectEuler\\notebooks\\packages\\FSharp.Formatting.2.4.8\\lib\\net40\\FSharp.Markdown.dll"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"Referenced: C:\\Github\\ProjectEuler\\notebooks\\packages\\FSharp.Formatting.2.4.8\\lib\\net40\\FSharp.MetadataFormat.dll"
]
}
],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"frame [ \"Map\" => series [ 1 => 2; 2 => 3 ]]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div class=\"deedleframe\">\r\n",
"\r\n",
"<table>\r\n",
"<thead>\r\n",
"<tr class=\"header\">\r\n",
"<th></th>\r\n",
"<th><p>Map</p></th>\r\n",
"</tr>\r\n",
"</thead>\r\n",
"<tbody>\r\n",
"<tr class=\"odd\">\r\n",
"<td><p>1</p></td>\r\n",
"<td><p>2</p></td>\r\n",
"</tr>\r\n",
"<tr class=\"even\">\r\n",
"<td><p>2</p></td>\r\n",
"<td><p>3</p></td>\r\n",
"</tr>\r\n",
"</tbody>\r\n",
"</table>\r\n",
"\r\n",
"\r\n",
"</div>\r\n"
],
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"series [ 1 => 2; 2 => 3 ]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div class=\"deedleseries\">\r\n",
"\r\n",
"<table>\r\n",
"<thead>\r\n",
"<tr class=\"header\">\r\n",
"<th><p>Keys</p></th>\r\n",
"<th><p>1</p></th>\r\n",
"<th><p>2</p></th>\r\n",
"</tr>\r\n",
"</thead>\r\n",
"<tbody>\r\n",
"<tr class=\"odd\">\r\n",
"<td><p>Values</p></td>\r\n",
"<td><p>2</p></td>\r\n",
"<td><p>3</p></td>\r\n",
"</tr>\r\n",
"</tbody>\r\n",
"</table>\r\n",
"\r\n",
"\r\n",
"</div>\r\n"
],
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 14
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"// this should output 5, but outputs a table and a series instead\n",
"let a = frame [ \"Map\" => series [ 1 => 2; 2 => 3 ]]\n",
"let b = a?Map\n",
"b.Values |> Seq.sum"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div class=\"deedleframe\">\r\n",
"\r\n",
"<table>\r\n",
"<thead>\r\n",
"<tr class=\"header\">\r\n",
"<th></th>\r\n",
"<th><p>Map</p></th>\r\n",
"</tr>\r\n",
"</thead>\r\n",
"<tbody>\r\n",
"<tr class=\"odd\">\r\n",
"<td><p>1</p></td>\r\n",
"<td><p>2</p></td>\r\n",
"</tr>\r\n",
"<tr class=\"even\">\r\n",
"<td><p>2</p></td>\r\n",
"<td><p>3</p></td>\r\n",
"</tr>\r\n",
"</tbody>\r\n",
"</table>\r\n",
"\r\n",
"\r\n",
"</div>\r\n"
],
"metadata": {},
"output_type": "display_data"
},
{
"html": [
"<div class=\"deedleseries\">\r\n",
"\r\n",
"<table>\r\n",
"<thead>\r\n",
"<tr class=\"header\">\r\n",
"<th><p>Keys</p></th>\r\n",
"<th><p>1</p></th>\r\n",
"<th><p>2</p></th>\r\n",
"</tr>\r\n",
"</thead>\r\n",
"<tbody>\r\n",
"<tr class=\"odd\">\r\n",
"<td><p>Values</p></td>\r\n",
"<td><p>2</p></td>\r\n",
"<td><p>3</p></td>\r\n",
"</tr>\r\n",
"</tbody>\r\n",
"</table>\r\n",
"\r\n",
"\r\n",
"</div>\r\n"
],
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 34
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment