Improved Factorial and Concat_list Alternative
I did some RIDICULOUS coding tonight in order to get around some OBSCURE NodeBox limitations - all to make a MINOR improvement to a single, seldom-used node.
WARNING - the following commentary is nerdy even for me. STOP READING NOW unless you are hardcore.
My factorial node can compute exact values up to 170! (a 7 with 306 digits after it) and has an option to add separators (commas or periods depending on your locale) every three digits for easier reading. The problem is that, if you calculate factorials for N=22 or greater, the comma option will start to round the value after about the 20th digit.
The reason for this involves some obscure limitations to the math package built into any modern 64-bit computer.
In Nodebox, you can't represent any floating point number above 2^1023 (about 10^308) or any integer above 2^63 - 1 (about 9 quintillion). If you calculate 2^1024 the result will be "infinity". If you then try to round infinity, or feed infinity into an integer node, you will get 9,223,372,036,854,775,807 (2^63 -1), which is far less than infinity. And you will get that same value for the integer part of any number higher than 2^63. And even for values less than 2^63 but greater than 10 million, Nodebox will automatically switch to scientific notation, making the exact value of large integers hard to see.
All of this can cause problems when you want to put separators into those long numbers to make them more readable.
Adding separators should be easy. Nodebox provides a format node which can format numbers using Java Format String Syntax. Unfortunately, Nodebox only implemented the floating point part of that syntax, so even when you use it to format integers, values are treated as floating point numbers. You can easily add separators using the syntax "%,.0f". And that's what I did to implement the commas option in my Factorial node. But once the Factorial value gets above N=21, the format node quietly converts the integers to floating points and begins to round to the nearest power of 10 (only if the "Add commas" option is checked).
So, to fix this VERY obscure but annoying little bug, I need to dump the format node and add the separators myself. But here we run into ANOTHER Nodebox limitation.
NodeBox provides an easy way of turning a long string into a list of smaller strings: the make_strings node. But it provides NO way to reverse that process. That is, you can't take a list of small strings and concatenate them all together back into a single long string. It does provide a concatenate node, but that only lets you concatenate up to SEVEN specific strings.
Concatenating a list of strings into a single string is not something you need to do very often, but when you need to do it, you REALLY miss not having a general purpose concatenator. Once of those times is NOW, when I need to chop a long string into 3-digit chunks, add commas (or periods), and concatenate them all together.
I long ago came up with one solution to this problem: my concat_list node. And I could certainly use that here. But there's a catch: this node requires an external code module, concat_list.py. And I REALLY don't want to force my users to add that module to their code library just to calculate a simple factorial.
For YEARS I have been wracking my brain trying to find a way to concatenate a list without using Python. I could think of only one way, but was not desperate enough to use it - until tonight.
The workaround is to use the sad little concatenate node to concatenate an arbitrarily long list 7 items at a time, and do this recursively until the list is completely concatenated. But, sadly - and bizarrely for a Lisp-like functional language - NodeBox doesn't do recursion. UNLESS you hardwire the recursion by feeding a subnetwork into a copy of itself, and that one into another copy, and that one into another copy, and so on.
As a one-time professional coder it almost makes me cry to even think of such a silly thing to do. But over the years, Nodebox has broken me.
So behold: the merge_string node. Merge_string takes an arbitrarily long list of strings and returns a single string with everything concatenated together. You can see it in the demo (attached). I take the first sentence of the Gettysburg Address, sort all 30 words into alphabetical order, than concatenate them all back into a single string so that I can use textpath to format it into a paragraph.
If you select the merge_string node and control click it to Edit Children you will see something strange. The subnetwork consists of nothing more than a solid block of ONE HUNDRED reduce subnetworks all joined into a single long chain. Each reduce subnetwork concatenates another six items in the list; once everything is reduced to a single string it just passes that along. Most of the time you will only need a few of these reduce nodes, but I make you go through a hundred of them anyway. This allows me to handle any list UP TO 601 items long. (If you need more than that, you can just copy paste more reduce nodes and add them to the chain.)
No external code required.
I am so ashamed of this monstrosity that I'm not going to release it as a separate node in my library. Instead, I will hide it inside the demo of the concat_list node. If you ever need it (and I doubt anyone but me ever will), just open that demo (starting with the next release of my library) and copy it from there.
What does all this have to do with my original problem?
Go to the demo and look inside my new, improved factorial node. Inside that you will find ANOTHER new node: separators. Separators adds commas or periods (depending on locale) to a number without relying on the flawed format node. If you look inside that, you will find an add_commas node. And if you look inside THAT you will find our new friend, merge_string.
As you can see in the attached screenshot I demonstrate both nodes by first displaying 170 factorial in all its glory (using factorial v3.4) and then the sorted Gettysburg (using merge_string).
And that, gentle reader, is what I did with my precious time tonight.
John
P.S. If ANYONE actually reads this thing all the way through, and is brave enough to admit it, I would really appreciate it if you would reply and simply say, well, anything. If nobody replies I will just assume I am talking to myself (as usual).
Keyboard shortcuts
Generic
? | Show this help |
---|---|
ESC | Blurs the current field |
Comment Form
r | Focus the comment reply box |
---|---|
^ + ↩ | Submit the comment |
You can use Command ⌘
instead of Control ^
on Mac
1 Posted by lastvector on 27 May, 2024 07:03 PM
Hi John
Unfortunately, my mathematical understanding is quite underdeveloped.
I also taught myself English with a little help from Google Translator
Which isn't always super helpful for understanding posts.
But I wanted you to know that there are people who will read your thoughts
and ideas about Nodebox with interest, regardless of how much they initially
understand about it.
I don't know why, but I like reading all sorts of nerdy things.
You never know what it's good for. :)
gottfried
2 Posted by lastvector on 27 May, 2024 07:05 PM
I understand the frustration regarding the low response. But on the one hand,
you have already helped so many people. The problem is that no one posts
who doesn't have problems :)
Maybe there are ways and means to bring Nodebox more widely to the people again.
Node based scripting might look a bit nerdy at first glance. But once you realize the
possibilities it offers, you won't want to miss it anymore. I like it.
There are also many other programs that make people more aware of the possibilities
of nodes. Blender with its node editor is certainly a factor. Then there is Rhino 3D with
Grasshopper, Moi 3D has a Node Editor, Black Ink a paint Program use a Layers like Nodes.
gottfried
Support Staff 3 Posted by john on 27 May, 2024 11:19 PM
Gottfried,
THANK YOU for breaking the silence. I really appreciate it.
Last night's ramblings are mostly about me pushing Nodebox to its edges. That has always been part of the attraction for me: how far can I push Nodebox? That's why I prefer to do things without resorting to external code modules.
And you're right about Blender, Grasshopper, etc. Nodebox explores a paradigm with endless possibilities. It's a diamond in the rough that few, so far, have discovered. But perhaps, if those few of us keep playing with it, and more people start to notice how much fun we are having, it will gradually gain the audience it deserves.
4 Posted by lastvector on 28 May, 2024 10:13 AM
John
you are very welcome
For example, I read through many of your old posts to better
understand Nodebox, which may not have received much
attention before.
I was also always very grateful for the included sample files
and always found them helpful for a better understanding.
That's why I really appreciate your work and especially a few others.
I'll definitely do a thing or two and highlight some of Nodebox's features
in the communities I visit regularly.
I also think about starting a YouTube channel from time to time,
but that's still a long way off, if I even do that.
gottfried
5 Posted by florisdejonge on 28 May, 2024 06:08 PM
I am reading every new discussion, John. I appreciate you sharing your considerations for a new node here, although I don't really understand it :)
Floris
Support Staff 6 Posted by john on 29 May, 2024 05:15 AM
Thanks, Floris. I consider you one of my primary partners in crime.