From 69295e463bc1c92c2d745d0e77b1985515952522 Mon Sep 17 00:00:00 2001 From: Stas Versilov Date: Mon, 7 May 2018 01:44:59 +0400 Subject: [PATCH] Large matrices pretty print. --- lib/matrex/inspect.ex | 53 ++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/lib/matrex/inspect.ex b/lib/matrex/inspect.ex index eb36a19..6344110 100644 --- a/lib/matrex/inspect.ex +++ b/lib/matrex/inspect.ex @@ -10,7 +10,7 @@ defimpl Inspect, for: Matrex do }, %{width: screen_width} = _opts ) - when columns < screen_width / 8 do + when columns < screen_width / 8 and rows <= 50 do rows_as_strings = for( row <- 1..rows, @@ -32,21 +32,21 @@ defimpl Inspect, for: Matrex do def inspect( %Matrex{ - data: - << - rows::unsigned-integer-little-32, - columns::unsigned-integer-little-32, - body::binary - >> = data + data: << + rows::unsigned-integer-little-32, + columns::unsigned-integer-little-32, + body::binary + >> }, %{width: screen_width} = _opts ) - when columns >= screen_width / 8 do + when columns >= screen_width / 8 or rows > 50 do suffix_size = prefix_size = div(screen_width, 16) element_chars_size = 8 rows_as_strings = - for row <- 0..(rows - 1), do: format_row(body, row, rows, columns, suffix_size, prefix_size) + for row <- displayable_rows(rows), + do: format_row(body, row, rows, columns, suffix_size, prefix_size) rows_as_strings = [ binary_part(body, 0, prefix_size * @element_byte_size) @@ -54,22 +54,33 @@ defimpl Inspect, for: Matrex do | rows_as_strings ] - # rows_as_strings = - # for( - # row <- 1..rows, - # do: - # Matrex.row_as_list(data, row - 1) - # |> Enum.map(&(Float.round(&1, 5) |> Float.to_string() |> String.pad_leading(8))) - # |> Enum.join() - # ) - - row_length = element_chars_size * (suffix_size + prefix_size) + 8 + row_length = element_chars_size * (suffix_size + prefix_size) + 5 + half_row_length = div(row_length, 2) top = "#{IO.ANSI.white()}┌#{String.pad_trailing("", row_length)}┐\n│#{IO.ANSI.yellow()}" bottom = " #{IO.ANSI.white()}│\n└#{String.pad_trailing("", row_length)}┘" - contents_str = rows_as_strings |> Enum.join(IO.ANSI.white() <> " ... " <> IO.ANSI.yellow()) - "#Matrix[#{rows}x#{columns}]\n#{top}#{contents_str}#{bottom}" + + contents_str = + rows_as_strings + |> Enum.join(IO.ANSI.white() <> " … " <> IO.ANSI.yellow()) + |> String.replace( + ~r/\n.*⋮.*\n/, + "\n│#{String.pad_leading("", half_row_length, " ⋮ ")}… #{ + String.pad_trailing("", half_row_length - 1, " ⋮ ") + }│\n" + ) + + "#{IO.ANSI.white()}#Matrix#{IO.ANSI.light_white()}[#{IO.ANSI.yellow()}#{rows}#{ + IO.ANSI.light_white() + }×#{IO.ANSI.yellow()}#{columns}#{IO.ANSI.light_white()}]\n#{top}#{contents_str}#{bottom}" end + defp displayable_rows(rows) when rows > 50, + do: Enum.to_list(0..25) ++ [-1] ++ Enum.to_list((rows - 25)..(rows - 1)) + + defp displayable_rows(rows), do: 0..(rows - 1) + + defp format_row(_body, -1, _rows, _columns, _, _), do: "⋮" + defp format_row(body, row, rows, columns, suffix_size, prefix_size) when row == rows - 1 do n = chunk_offset(row, columns, suffix_size)