Added echo_matrix, matrix_strings, str_pad and str_replace_char.

This commit is contained in:
Adrian Mariano 2021-01-01 01:30:13 -05:00
parent e0ac4d0c1b
commit ec915a7eaa
3 changed files with 129 additions and 0 deletions

View file

@ -501,4 +501,29 @@ function mod_trace(levs=2, indent=" ", modsep="->") =
);
// Function&Module: echo_matrix()
// Usage:
// echo_matrix(M, [description], [sig], [eps]);
// dummy = echo_matrix(M, [description], [sig], [eps]),
// Description:
// Display a numerical matrix in a readable columnar format with `sig` significant
// digits. Values smaller than eps display as zero. If you give a description
// it is displayed at the top.
function echo_matrix(M,description,sig=4,eps=1e-9) =
let(
horiz_line = chr(8213),
matstr = matrix_strings(M,sig=sig,eps=eps),
separator = str_join(repeat(horiz_line,10)),
dummy1=echo(str(separator," ",is_def(description) ? description : "")),
dummy2=[for(row=matstr) echo(row)]
)
echo(separator);
module echo_matrix(M,description,sig=4,eps=1e-9)
{
dummy = echo_matrix(M,description,sig,eps);
}
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -704,4 +704,90 @@ module echofmt(fmt, vals) {
echo(str_format(fmt,vals));
}
// Function: str_pad()
// Usage:
// padded = str_pad(str, length, char, [left]);
// Description:
// Pad the given string `str` with to length `length` with the specified character,
// which must be a length 1 string. If left is true then pad on the left, otherwise
// pad on the right. If the string is longer than the specified length the full string
// is returned unchanged.
// Arguments:
// str = string to pad
// length = length to pad to
// char = character to pad with. Default: " " (space)
// left = if true, pad on the left side. Default: false
function str_pad(str,length,char=" ",left=false) =
assert(is_str(str))
assert(is_str(char) && len(char)==1, "char must be a single character string")
assert(is_bool(left))
let(
padding = str_join(repeat(char,length-len(str)))
)
left ? str(padding,str) : str(str,padding);
// Function str_replace_char()
// Usage:
// newstr = str_replace_char(str, char, replace)
// Description:
// Replace every occurence of `char` in the input string with the string `replace` which
// can be any string.
function str_replace_char(str,char,replace) =
assert(is_str(str))
assert(is_str(char) && len(char)==1, "Search pattern 'char' must be a a single character string")
assert(is_str(replace))
str_join([for(c=str) c==char ? replace : c]);
// Function: matrix_strings()
// Usage:
// matrix_strings(M, [sig], [eps])
// Description:
// Convert a numerical matrix into a matrix of strings where every column
// is the same width so it will display in neat columns when printed.
// Values below eps will display as zero. The matrix can include nans, infs
// or undefs and the rows can be different lengths.
// Arguments:
// M = numerical matrix to convert
// sig = significant digits to display. Default: 4
// eps = values smaller than this are shown as zero. Default: 1e-9
function matrix_strings(M, sig=4, eps=1e-9) =
let(
columngap = 1,
figure_dash = chr(8210),
space_punc = chr(8200),
space_figure = chr(8199),
strarr=
[for(row=M)
[for(entry=row)
let(
text = is_undef(entry) ? "und"
: abs(entry) < 0 ? "0" // Replace hyphens with figure dashes
: str_replace_char(fmt_float(entry, sig),"-",figure_dash),
have_dot = is_def(str_find(text, "."))
)
// If the text lacks a dot we add a space the same width as a dot to
// maintain alignment
str(have_dot ? "" : space_punc, text)
]
],
maxwidth = max([for(row=M) len(row)]),
// Find maximum length for each column. Some entries in a column may be missing.
maxlen = [for(i=[0:1:maxwidth-1])
max(
[for(j=idx(M)) i>=len(M[j]) ? 0 : len(strarr[j][i])])
],
padded =
[for(row=strarr)
str_join([for(i=idx(row))
let(
extra = ends_with(row[i],"inf") ? 1 : 0
)
str_pad(row[i],maxlen[i]+extra+(i==0?0:columngap),space_figure,left=true)])]
)
padded;
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap

View file

@ -368,5 +368,23 @@ test_echofmt();
*/
module test_str_pad() {
assert_equal(str_pad("abc",5,"x"), "abcxx");
assert_equal(str_pad("abc",5), "abc ");
assert_equal(str_pad("abc",5,"x",left=true), "xxabc");
assert_equal(str_pad("", 5, "x"), "xxxxx");
assert_equal(str_pad("", 5, "x", left=true), "xxxxx");
}
test_str_pad();
module test_str_replace_char() {
assert_equal(str_replace_char("abcabc", "b", "xyz"), "axyzcaxyzc");
assert_equal(str_replace_char("abcabc", "b", ""), "acac");
assert_equal(str_replace_char("", "b", "xyz"), "");
assert_equal(str_replace_char("acdacd", "b", "xyz"), "acdacd");
}
test_str_replace_char();
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap