omdl  v0.9.5
OpenSCAD Mechanical Design Library
scalar_test.scad
Go to the documentation of this file.
1 //! Scalar data type tests.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2015-2023
6 
7  \copyright
8 
9  This file is part of [omdl] (https://github.com/royasutton/omdl),
10  an OpenSCAD mechanical design library.
11 
12  The \em omdl is free software; you can redistribute it and/or modify
13  it under the terms of the [GNU Lesser General Public License]
14  (http://www.gnu.org/licenses/lgpl.html) as published by the Free
15  Software Foundation; either version 2.1 of the License, or (at
16  your option) any later version.
17 
18  The \em omdl is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with the \em omdl; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26  02110-1301, USA; or see <http://www.gnu.org/licenses/>.
27 
28  \details
29 
30  \amu_define group_name (Scalar Tests)
31  \amu_define group_brief (Tests to differentiate scalar data types.)
32 
33  \amu_include (include/amu/pgid_path_pstem_pg.amu)
34 *******************************************************************************/
35 
36 //----------------------------------------------------------------------------//
37 // validation.
38 //----------------------------------------------------------------------------//
39 
40 /***************************************************************************//**
41  \amu_include (include/amu/validate_log_th.amu)
42  \amu_include (include/amu/validate_log_td.amu)
43  \amu_include (include/amu/validate_results.amu)
44 *******************************************************************************/
45 
46 //----------------------------------------------------------------------------//
47 // group.
48 //----------------------------------------------------------------------------//
49 
50 /***************************************************************************//**
51  \amu_include (include/amu/group_in_parent_start.amu)
52  \amu_include (include/amu/includes_required.amu)
53 
54  \details
55 
56  \amu_define group_references
57  (
58  [ottf]: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Type_Test_Functions "OpenSCAD Type Test Functions"
59  )
60 
61  \amu_include (include/amu/validate_summary.amu)
62 *******************************************************************************/
63 
64 //----------------------------------------------------------------------------//
65 
66 //! Test if a value is a single non-iterable value.
67 /***************************************************************************//**
68  \param v <value> A value.
69 
70  \returns <boolean> \b true when the value is a single non-iterable
71  value and \b false otherwise.
72 
73  \details
74 
75  input value | function return
76  :-----------:|:-----------------:
77  \em number | \b true
78  \em boolean | \b true
79  \em string | \b false
80  \em list | \b false
81  \em range | \b true
82  \b undef | \b true
83  \b inf | \b true
84  \b nan | \b true
85 
86  \note The empty list and empty string return \b true.
87 *******************************************************************************/
88 function is_scalar
89 (
90  v
91 ) = !is_string(v) && !is_list(v);
92 
93 //! Test if a value is defined.
94 /***************************************************************************//**
95  \param v <value> A value.
96 
97  \returns <boolean> \b true when the value is defined
98  and \b false otherwise.
99 
100  \details
101 
102  \note Starting with version 2019.05, this function is now
103  provided directly by OpenSCAD via a built-in [type test
104  function][ottf] \c is_undef().
105 
106  \amu_eval (${group_references})
107 *******************************************************************************/
108 function is_defined
109 (
110  v
111 ) = is_undef(v) ? false : true;
112 
113 //! Test if a numerical value is 'nan' (not a number).
114 /***************************************************************************//**
115  \param v <value> A numerical value.
116 
117  \returns <boolean> \b true when the value is determined to be
118  \b nan (Not A Number) and \b false otherwise.
119 *******************************************************************************/
120 function is_nan
121 (
122  v
123 ) = (v != v);
124 
125 //! Test if a numerical value is infinite.
126 /***************************************************************************//**
127  \param v <value> A numerical value.
128 
129  \returns <boolean> \b true when the value is determined to be
130  \b inf (greater than the largest OpenSCAD representable
131  number) and \b false otherwise.
132 *******************************************************************************/
133 function is_inf
134 (
135  v
136 ) = ( v == (number_max * number_max) );
137 
138 //! Test if a value is a number.
139 /***************************************************************************//**
140  \param v <value> A value.
141 
142  \returns <boolean> \b true when the value is a number
143  and \b false otherwise.
144 
145  \details
146 
147  \note Starting with version 2019.05, this function is now
148  provided directly by OpenSCAD via a built-in [type test
149  function][ottf] \c is_num().
150 
151  \amu_eval (${group_references})
152 *******************************************************************************/
153 function is_number
154 (
155  v
156 ) = is_num(v);
157 
158 //! Test if a value is an integer.
159 /***************************************************************************//**
160  \param v <value> A value.
161 
162  \returns <boolean> \b true when the value is an integer and \b false
163  otherwise.
164 *******************************************************************************/
165 function is_integer
166 (
167  v
168 ) = !is_num(v) ? false
169  : ((v % 1) == 0);
170 
171 //! Test if a value is a decimal.
172 /***************************************************************************//**
173  \param v <value> A value.
174 
175  \returns <boolean> \b true when the value is a decimal and \b false
176  otherwise.
177 *******************************************************************************/
178 function is_decimal
179 (
180  v
181 ) = !is_num(v) ? false
182  : ((v % 1) > 0);
183 
184 //! Test if a value is a range definition.
185 /***************************************************************************//**
186  \param v <value> A value.
187 
188  \returns <boolean> \b true when the value is a range definition
189  and \b false otherwise.
190 
191  \details
192 
193  \note A range is determined to be a value which does not fit in
194  any other category. Specifically, It is a value that is not
195  {\b undef, \b nan or \b inf}, and is neither of {\em list,
196  \em number, \em bool, or \em string}.
197 
198  \internal
199  This exclusion test should be replaced by a suitable inclusion test
200  when possible.
201  \endinternal
202 *******************************************************************************/
203 function is_range
204 (
205  v
206 ) = !is_undef(v) &&
207  !is_nan(v) &&
208  !is_inf(v) &&
209  !is_list(v) &&
210  !is_num(v) &&
211  !is_bool(v) &&
212  !is_string(v);
213 
214 //! Test if a numerical value is even.
215 /***************************************************************************//**
216  \param v <value> A numerical value.
217 
218  \returns <boolean> \b true when the value is determined to be an \em even
219  integer and \b false otherwise (The value may be positive or
220  negative).
221 *******************************************************************************/
222 function is_even
223 (
224  v
225 ) = !is_integer(v) ? false
226  : ((v % 2) == 0);
227 
228 //! Test if a numerical value is odd.
229 /***************************************************************************//**
230  \param v <value> A numerical value.
231 
232  \returns <boolean> \b true when the value is determined to be an \em odd
233  integer and \b false otherwise (The value may be positive or
234  negative).
235 *******************************************************************************/
236 function is_odd
237 (
238  v
239 ) = !is_integer(v) ? false
240  : ((v % 2) != 0);
241 
242 //! Test if a numerical value is between an upper and lower bounds.
243 /***************************************************************************//**
244  \param v <number> A numerical value.
245  \param l <number> The minimum value.
246  \param u <number> The maximum value.
247 
248  \returns <boolean> \b true when the value is equal to or between the
249  upper and lower bounds and \b false otherwise. Returns \b false
250  when either of \p v, \p l, or \p u is not a number.
251 *******************************************************************************/
252 function is_between
253 (
254  v,
255  l,
256  u
257 ) = !(is_num(v) && is_num(l) && is_num(u)) ? false
258  : ((v >= l) && (v <=u));
259 
260 //! @}
261 //! @}
262 
263 //----------------------------------------------------------------------------//
264 // openscad-amu auxiliary scripts
265 //----------------------------------------------------------------------------//
266 
267 /*
268 BEGIN_SCOPE validate;
269  BEGIN_OPENSCAD;
270  include <omdl-base.scad>;
271  include <common/validation.scad>;
272 
273  function fmt( id, td, v1, v2, v3 ) = table_validate_fmt(id, td, v1, v2, v3);
274  function v1(db, id) = table_validate_get_v1(db, id);
275  t = true; f = false; u = undef; s = validation_skip;
276 
277  tbl_test_values =
278  [
279  fmt("t01", "The undefined value", undef),
280  fmt("t02", "An odd integer", 1),
281  fmt("t03", "An small even integer", 10),
282  fmt("t04", "A large integer", 100000000),
283  fmt("t05", "A small decimal (epsilon)", eps),
284  fmt("t06", "The max number", number_max),
285  fmt("t07", "The min number", number_min),
286  fmt("t08", "The max number^2", number_max * number_max),
287  fmt("t09", "The invalid number nan", 0 / 0),
288  fmt("t10", "The boolean true", true),
289  fmt("t11", "The boolean false", false),
290  fmt("t12", "A character string", "a"),
291  fmt("t13", "A string", "This is a longer string"),
292  fmt("t14", "The empty string", empty_str),
293  fmt("t15", "The empty list", empty_lst),
294  fmt("t16", "A 1-tuple list of undef", [undef]),
295  fmt("t17", "A 1-tuple list", [10]),
296  fmt("t18", "A 3-tuple list", [1, 2, 3]),
297  fmt("t19", "A list of lists", [[1,2,3], [4,5,6], [7,8,9]]),
298  fmt("t20", "A shorthand range", [0:9]),
299  fmt("t21", "A range", [0:0.5:9])
300  ];
301 
302  tbl_test_answers =
303  [ // function 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21
304  ["is_scalar", t, t, t, t, t, t, t, t, t, t, t, f, f, f, f, f, f, f, f, t, t],
305  ["is_defined", f, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t],
306  ["is_nan", f, f, f, f, f, f, f, f, t, f, f, f, f, f, f, f, f, f, f, f, f],
307  ["is_inf", f, f, f, f, f, f, f, t, f, f, f, f, f, f, f, f, f, f, f, f, f],
308  ["is_number", f, t, t, t, t, t, t, t, f, f, f, f, f, f, f, f, f, f, f, f, f],
309  ["is_integer", f, t, t, t, f, t, t, f, f, f, f, f, f, f, f, f, f, f, f, f, f],
310  ["is_decimal", f, f, f, f, t, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f],
311  ["is_range", f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, t, t],
312  ["is_even", f, f, t, t, f, t, t, f, f, f, f, f, f, f, f, f, f, f, f, f, f],
313  ["is_odd", f, t, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f],
314  ["is_between_MM", f, t, t, t, t, t, t, f, f, f, f, f, f, f, f, f, f, f, f, f, f],
315 
316  ["is_undef", t, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f],
317  ["is_bool", f, f, f, f, f, f, f, f, f, t, t, f, f, f, f, f, f, f, f, f, f],
318  ["is_string", f, f, f, f, f, f, f, f, f, f, f, t, t, t, f, f, f, f, f, f, f],
319  ["is_list", f, f, f, f, f, f, f, f, f, f, f, f, f, f, t, t, t, t, t, f, f]
320  ];
321 
322  db = table_validate_init( tbl_test_values, tbl_test_answers );
323 
324  table_validate_start( db );
325  test_ids = table_validate_get_ids( db );
326 
327  for (id=test_ids) table_validate( db, id, "is_scalar", 1, is_scalar( v1(db,id)) );
328  for (id=test_ids) table_validate( db, id, "is_defined", 1, is_defined( v1(db,id)) );
329  for (id=test_ids) table_validate( db, id, "is_nan", 1, is_nan( v1(db,id)) );
330  for (id=test_ids) table_validate( db, id, "is_inf", 1, is_inf( v1(db,id)) );
331  for (id=test_ids) table_validate( db, id, "is_number", 1, is_number( v1(db,id)) );
332  for (id=test_ids) table_validate( db, id, "is_integer", 1, is_integer( v1(db,id)) );
333  for (id=test_ids) table_validate( db, id, "is_decimal", 1, is_decimal( v1(db,id)) );
334  for (id=test_ids) table_validate( db, id, "is_range", 1, is_range( v1(db,id)) );
335  for (id=test_ids) table_validate( db, id, "is_even", 1, is_even( v1(db,id)) );
336  for (id=test_ids) table_validate( db, id, "is_odd", 1, is_odd( v1(db,id)) );
337  for (id=test_ids) table_validate( db, id, "is_between_MM", 1, is_between( v1(db,id), number_min, number_max ) );
338 
339  // OpenSCAD built-in functions: is_undef() and is_num() are tested above
340  for (id=test_ids) table_validate( db, id, "is_undef", 1, is_undef( v1(db,id)) );
341  for (id=test_ids) table_validate( db, id, "is_bool", 1, is_bool( v1(db,id)) );
342  for (id=test_ids) table_validate( db, id, "is_string", 1, is_string( v1(db,id)) );
343  for (id=test_ids) table_validate( db, id, "is_list", 1, is_list( v1(db,id)) );
344 
345  // end_include
346  END_OPENSCAD;
347 
348  BEGIN_MFSCRIPT;
349  include --path "${INCLUDE_PATH}" {var_init,var_gen_term}.mfs;
350  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
351  END_MFSCRIPT;
352 END_SCOPE;
353 */
354 
355 //----------------------------------------------------------------------------//
356 // end of file
357 //----------------------------------------------------------------------------//
number_max
<decimal> The largest representable number in OpenSCAD scripts.
Definition: constants.scad:289
function is_nan(v)
Test if a numerical value is 'nan' (not a number).
function is_scalar(v)
Test if a value is a single non-iterable value.
function is_between(v, l, u)
Test if a numerical value is between an upper and lower bounds.
function is_inf(v)
Test if a numerical value is infinite.
function is_defined(v)
Test if a value is defined.
function is_integer(v)
Test if a value is an integer.
function is_number(v)
Test if a value is a number.
function is_even(v)
Test if a numerical value is even.
function is_decimal(v)
Test if a value is a decimal.
function is_odd(v)
Test if a numerical value is odd.
function is_range(v)
Test if a value is a range definition.