From 39b4b7282d7b582600dd9df5d5ee11ebf5b7be55 Mon Sep 17 00:00:00 2001 From: RonaldoCMP <rcmpersiano@gmail.com> Date: Fri, 24 Jul 2020 00:04:16 +0100 Subject: [PATCH] Update typeof(), int(), range(), list_of() and segs --- common.scad | 31 ++++++++++++++++++++----------- tests/test_common.scad | 27 ++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/common.scad b/common.scad index 8d0655a..6cc910e 100644 --- a/common.scad +++ b/common.scad @@ -15,7 +15,8 @@ // Usage: // typ = typeof(x); // Description: -// Returns a string representing the type of the value. One of "undef", "boolean", "number", "nan", "string", "list", or "range" +// Returns a string representing the type of the value. One of "undef", "boolean", "number", "nan", "string", "list", "range" or "invalid". +// Some malformed "ranges", like '[0:NAN:INF]' and '[0:"a":INF]', may be classified as "undef" or "invalid". function typeof(x) = is_undef(x)? "undef" : is_bool(x)? "boolean" : @@ -23,8 +24,11 @@ function typeof(x) = is_nan(x)? "nan" : is_string(x)? "string" : is_list(x)? "list" : - "range"; + is_range(x) ? "range" : + "invalid"; +//*** +// included "invalid" // Function: is_type() // Usage: @@ -70,8 +74,8 @@ function is_str(x) = is_string(x); // is_int(n) // Description: // Returns true if the given value is an integer (it is a number and it rounds to itself). -function is_int(n) = is_num(n) && n == round(n); -function is_integer(n) = is_num(n) && n == round(n); +function is_int(n) = is_finite(n) && n == round(n); +function is_integer(n) = is_finite(n) && n == round(n); // Function: is_nan() @@ -93,7 +97,7 @@ function is_finite(v) = is_num(0*v); // Function: is_range() // Description: // Returns true if its argument is a range -function is_range(x) = is_num(x[0]) && !is_list(x); +function is_range(x) = !is_list(x) && is_finite(x[0]+x[1]+x[2]) ; // Function: is_list_of() @@ -106,13 +110,15 @@ function is_range(x) = is_num(x[0]) && !is_list(x); // is_list_of([3,4,5], 0); // Returns true // is_list_of([3,4,undef], 0); // Returns false // is_list_of([[3,4],[4,5]], [1,1]); // Returns true +// is_list_of([[3,"a"],[4,true]], [1,undef]); // Returns true // is_list_of([[3,4], 6, [4,5]], [1,1]); // Returns false -// is_list_of([[1,[3,4]], [4,[5,6]]], [1,[2,3]]); // Returne true -// is_list_of([[1,[3,INF]], [4,[5,6]]], [1,[2,3]]); // Returne false +// is_list_of([[1,[3,4]], [4,[5,6]]], [1,[2,3]]); // Returns true +// is_list_of([[1,[3,INF]], [4,[5,6]]], [1,[2,3]]); // Returns false +// is_list_of([], [1,[2,3]]); // Returns true function is_list_of(list,pattern) = let(pattern = 0*pattern) is_list(list) && - []==[for(entry=list) if (entry*0 != pattern) entry]; + []==[for(entry=0*list) if (entry != pattern) entry]; // Function: is_consistent() @@ -311,10 +317,13 @@ function scalar_vec3(v, dflt=undef) = // Calculate the standard number of sides OpenSCAD would give a circle based on `$fn`, `$fa`, and `$fs`. // Arguments: // r = Radius of circle to get the number of segments for. -function segs(r) = +function segs(r) = $fn>0? ($fn>3? $fn : 3) : - ceil(max(5, min(360/$fa, abs(r)*2*PI/$fs))); + let( r = is_finite(r)? r: 0 ) + ceil(max(5, min(360/$fa, abs(r)*2*PI/$fs))) ; +//*** +// avoids undef // Section: Testing Helpers @@ -322,7 +331,7 @@ function segs(r) = function _valstr(x) = is_list(x)? str("[",str_join([for (xx=x) _valstr(xx)],","),"]") : - is_num(x)? fmt_float(x,12) : x; + is_finite(x)? fmt_float(x,12) : x; // Module: assert_approx() diff --git a/tests/test_common.scad b/tests/test_common.scad index ed97cae..1cad5e3 100644 --- a/tests/test_common.scad +++ b/tests/test_common.scad @@ -1,4 +1,4 @@ -include <BOSL2/std.scad> +include <../std.scad> module test_typeof() { @@ -18,6 +18,10 @@ module test_typeof() { assert(typeof([0:1:5]) == "range"); assert(typeof([-3:2:5]) == "range"); assert(typeof([10:-2:-10]) == "range"); + assert(typeof([0:NAN:INF]) == "invalid"); + assert(typeof([0:"a":INF]) == "undef"); + assert(typeof([0:[]:INF]) == "undef"); + assert(typeof([true:1:INF]) == "undef"); } test_typeof(); @@ -102,6 +106,8 @@ module test_is_int() { assert(!is_int(-99.1)); assert(!is_int(99.1)); assert(!is_int(undef)); + assert(!is_int(INF)); + assert(!is_int(NAN)); assert(!is_int(false)); assert(!is_int(true)); assert(!is_int("foo")); @@ -124,6 +130,8 @@ module test_is_integer() { assert(!is_integer(-99.1)); assert(!is_integer(99.1)); assert(!is_integer(undef)); + assert(!is_integer(INF)); + assert(!is_integer(NAN)); assert(!is_integer(false)); assert(!is_integer(true)); assert(!is_integer("foo")); @@ -166,6 +174,9 @@ module test_is_range() { assert(!is_range("foo")); assert(!is_range([])); assert(!is_range([3,4,5])); + assert(!is_range([INF:4:5])); + assert(!is_range([3:NAN:5])); + assert(!is_range([3:4:"a"])); assert(is_range([3:1:5])); } test_is_nan(); @@ -331,11 +342,25 @@ module test_scalar_vec3() { assert(scalar_vec3([3]) == [3,0,0]); assert(scalar_vec3([3,4]) == [3,4,0]); assert(scalar_vec3([3,4],dflt=1) == [3,4,1]); + assert(scalar_vec3([3,"a"],dflt=1) == [3,"a",1]); + assert(scalar_vec3([3,[2]],dflt=1) == [3,[2],1]); assert(scalar_vec3([3],dflt=1) == [3,1,1]); assert(scalar_vec3([3,4,5]) == [3,4,5]); assert(scalar_vec3([3,4,5,6]) == [3,4,5]); + assert(scalar_vec3([3,4,5,6]) == [3,4,5]); } test_scalar_vec3(); +module test_segs() { + assert_equal(segs(50,$fn=8), 8); + assert_equal(segs(50,$fa=2,$fs=2), 158); + assert(segs(1)==5); + assert(segs(11)==30); + // assert(segs(1/0)==5); + // assert(segs(0/0)==5); + // assert(segs(undef)==5); +} +test_segs(); + // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap