Every user query is a puzzle

The user didn’t really mean to give you a level 5 puzzle to solve. But that’s what it is. Every time the user asks you to help him solve a software related problem, he’s giving you a puzzle.

Sometimes, it’s a level 1 puzzle, where you don’t even need to fire up your code editor to glance through the code to answer, or give more than a few seconds to think through. Sometimes, you have to really push for lots of hints, like clarifying the user’s query, ask for screenshots (even if sometimes they aren’t enough…), and dig through code archives.

I got a level 1.5-ish puzzle lately… The user said he couldn’t use the delete button. I fired up the application, selected a record, and indeed the delete button was disabled. On a whim, I double-clicked. The details of the selected record came up, and the delete button was enabled.

I have never seen or used that particular section of the application before. The user on the other hand, was supposed to be familiar with the application. Perhaps I’m more willing to try out typing randomly or aimlessly clicking the mouse on an application screen. I certainly typed enough asdf’s…

So, have you encountered any high level puzzles? Share in the comments.

Polymercation aka Polymath Programmer Publication

I’m feeling restless. There’s a bunch of stuff I want to share and somehow they don’t make it here to the blog. There’s so much I want to learn, and I have the usual excuses of too little time, little motivation, little interest…

I find myself talking and writing and thinking more about software than actually coding. Much of the software work I do nowadays are quite simple… after I’ve done the heavyweight thinking that is. I think and scribble on paper a lot.

Truth be told, I feel like I’m stagnating. Which isn’t too bad if it’s restricted to only coding. I kind of miss the feeling of learning something because I’m interested and excited about it, and just because I’m learning something new.

I want to do something about it.

Newspaper printing machine
[image by Gabriela Schaufelberger]

I’m starting a newsletter. I know, I know, the last time I started a newsletter, it didn’t quite work out. The topics seem to overlap very much with the blog topics, and I felt the blog format worked better. I can easily include images and videos on the blog.

This time round, I’m treating it more like an informal lesson plan to myself. Hopefully, it’s also useful to you too.

The schedule will be about once a month. Maybe twice a month, if there’s a lot of material to cover. But 3 times a month is the maximum. I didn’t keep to the once-a-fortnight schedule the last time, so there’s no reason to believe I have the fortitude to come up with 3 newsletters in a month…

I still want to include stuff from both the arts and the sciences. Actually I’ll be covering a lot of ground. I plan to also touch on marketing, sales, and other business-related stuff (I got interested because I wanted to know more about how my employer operates). I may not write about those topics, but I can certainly provide links to people who wrote great articles on them. Psychology-related articles too, since I’m fascinated by human behaviour.

My blog seems to be stretching to cover a lot of topics, even if they circle around mathematics and programming. Am I setting myself up for failure by creating a newsletter that’s even broader in scope? I don’t know.

Right now, I have 2 main goals. Be curious, and to make the world a better place. With the rise of technology, and its usefulness to our lives, I believe a programmer can do much more to help.

I don’t know how as a programmer I can contribute to making the world a better place. Making better user interfaces? Creating better software so there’s less toxic emissions?

But I do know that curiosity plays a part. It’s not about “I can learn to do X when I need to do X, not before”. It’s about cultivating the habit of being curious. The moment I stop being curious, then I stop learning, and I stop trying to make a difference.

I quote:

Creative work only seems like a magic trick to people who don’t understand that it’s ultimately still work. – Merlin Mann

If you haven’t figured it out, programming is creative work. So I’m working harder on getting better at it. I’m just approaching it from all kinds of angles.

Medicine? Those machines and reports and medical records? Someone has to write software for them. Space shuttles, trajectory calculations and fuel usage? Someone has to write software for them. Traffic simulations, city modelling and urban planning. Someone has to write software for them.

I’d rather that someone be you. Sure, I may not know much about you, but if you’re reading my blog, then you probably care about your education (not necessarily in an academic setting) and the world at large. Ok, back to the newsletter thing.

The original newsletter was named P3, as a shortening of Polymath Programmer Publication. For some reason, I really want to actually publish something. A blog doesn’t quite fill that urge. A newsletter sounds very fun. Anyway, “Polymath Programmer Publication” is too long, and P3 doesn’t quite have a characteristic distinction.

Following my portmanteau of Polymath Programmer into Polymer, you now have Polymercation, a newsletter for Polymers. The newsletter will contain content that’s separate from the blog content, a mishmash of tidbits and thought-provokers. And I want to do this together with you, because it’s as much an informal lesson for you as it is for me. The sign up form is on my blog (so if you’re reading this in a feed reader, please visit my blog).

You know the making the world a better place part? I have a problem. I can’t do it alone. I need your help. If you know anything that can help expand my education, let me know. In return, I’ll source for material to help you in your life, on your education, on your goals. Fair?

This will be an exciting journey.

Dissecting Trigonometric Particles part 2 – Axis functions

This is a continuation of the explanation behind Trigonometric Particles. Read up on part 1 if you haven’t done so.

Actually, there isn’t a clever coding construct I used to implement the axis functions. I just created a function that does a combination of polynomials and trigonometry functions. It looks something like this:

float function AxisFunction(float t, float p0, float p1, float p2, float p3, float p4, float p5, float p6)
{
	float result = 0.0;
	result += p0 + p1*t + p2*t*t + p3*t*t*t;
	result += p4*sin(t) + p5*cos(t) + p6*tan(t);

	return result;
}

The variable t is the time elapsed. The first part of the function is basically a cubic polynomial. The second part is a sum of the 3 standard trigonometric functions. Basically, I’m just passing in parameters which are the coefficients of the respective terms.

To simulate a sphere, since I can’t quite summon the mental energy to switch between my preferred Y-axis-pointing-skywards and the more widely known Z-axis-pointing-skywards coordinate system, I’ll just use the more famous version to illustrate. So the axes are:
x = r * sin(theta) * cos(phi)
y = r * sin(theta) * sin(phi)
z = r * cos(theta)

To calculate the X, Y, Z coordinates, I just use different combinations of AxisFunction(). So
x = AxisFunction(t, 0,0,0,0, r,0,0) * AxisFunction(t/2, 0,0,0,0, 0,1,0)
y = AxisFunction(t, 0,0,0,0, r,0,0) * AxisFunction(t/2, 0,0,0,0, 1,0,0)
z = AxisFunction(t, 0,0,0,0, 0,r,0)

I’m passing t/2 for a different-valued phi. I can’t remember the exact multiple of t I used… so I’m just using t/2 as an example. For the sphere simulation, I was playing around with t to get the particles to swirl and end roughly near the top of the sphere. Took me a while to figure out the right magic number…

To simulate a cylinder, just set polar coordinates on X and Y, then use Z as the height.
x = AxisFunction(t, 0,0,0,0, 0,r,0)
y = AxisFunction(t, 0,0,0,0, r,0,0)
z = AxisFunction(t, 0,H,0,0, 0,0,0)
where H corresponds to the speed value you want the particles to “climb” the cylinder. Again, much time taken to figure out the right magic number…

As for the tornado simulation, notice that it’s similar to that of a cylinder, and the particles circle with a wider radius as they climb the cylinder. So the radius is now a function of the height.

Actually, we just need the radius to increase as t increases, not necessarily as a function of height. So we apply a linear function to r.
x = AF(t, 0,0,0,0, 0, r * AF(t, 0,L,0,0, 0,0,0), 0)
y = AF(t, 0,0,0,0, r * AF(t, 0,L,0,0, 0,0,0), 0,0)
z = AF(t, 0,H,0,0, 0,0,0)
where L is some magic number such that the radius increases in a reasonable manner proportionate to the time elapsed (and effectively proportionate to the height).

I have a confession to make. When I first introduced Trigonometric Particles, I said I used a W axis as well as composite functions. Well I truly remembered having a W axis, and I think I used it as such:
x = W * AF(…)
or maybe
x = AF( … W, …)

But I’m not using W in my explanations above. Hmm… somehow while writing the explanations, the W axis wasn’t required.

As for composite functions, a short description. H is a composite function when
H(x) = F(G(x))
meaning you calculate G(x) first, then calculate function F using G(x). That’s what we’re doing when we passed in one form of AxisFunction() to another AxisFunction() as a parameter.

Well, my memory being foggy, I seem to recall having both W axis and the use of composite functions. It appears one can simulate the results with one or the other. Oh well, no one’s perfect…

And the last simulation pattern, the sun’s surface? I think I used a pure polynomial. Quadratic, I think…

Jerk jumping assignments are bad

Do you deal with incrementing values of a cyclic nature? For example, angular values used in sine functions? Then be careful when you reach the cycle’s end.

Back when I was doing an OpenGL class project in university, there was this Ferris wheel simulation. The Ferris wheel was going to keep turning, and there’s a variable keeping track of the angle of rotation.

Even though a float or double can take in large values, there’s still the possibility that it would overflow if unchecked. So most of us (the students) just keep the variable to within the [0, 2*PI) range.

The thing was, some students jerk jump the assignment as follows:

if (rot > 2*PI)
{
	rot = 0.0;
}

Well, there’s nothing wrong with getting it back to square zero, isn’t it?

Ahh, but PI is an irrational number, and couple that with the sometimes inexact representation of floating point variables, it means the variable rot is probably never exactly 2*PI. This means (rot – 2*PI) is greater than zero. And the students just smashed that difference to pieces.

It also meant their Ferris wheels would appear jerky. The Ferris wheels would rotate until 2*PI was exceeded, and then snap back to when they’re at zero rotation. Depending on how much their increments were (which affected the speed of rotation), the jerky movements could be more pronounced.

The smoother solution is to subtract a full cycle value:

if (rot > 2*PI)
{
	rot -= 2*PI;
}

There’s a caveat. It assumes the incremental value is less than 2*PI. That’s a safe assumption. It’s not like you’d do something like this, right?

rot += (2*PI + 0.5);
if (rot > 2*PI)
{
	rot -= 2*PI;
}

Right?!?!

This reminds me of sinks and diverging values in chaos theory… f(x)=x^2 tends to zero if x<1, but goes to infinity if x>1.

Anyway, be careful of assignments when you reach boundaries. Because jerk jumping assignments are bad.

How to prorate in discrete blocks

Recently, I had the occasion to contemplate prorating logic. Alright, fine, I was tasked with implementing some business logic which required prorating, but in discrete blocks. Let me explain.

Suppose you’re providing a service, and you charge in minutes. Say as a promotion, you give away 600 minutes for free per month, on condition that the customer stay with you for a certain number of months. The customer backs out on that condition on the 17th of his first month, so the customer has to pay for the rest of the free minutes of that month (there are 31 days for that month). BUT, and here’s the kicker, the price must be calculated based on blocks of 6 minutes.

So you have to prorate the remaining minutes, and it has to be in multiples of 6.

Ok, that wasn’t much of a challenge. I thought I’d just write down how to do it anyway. Here’s the C# code.

int num = (31 - 17), den = 31, block = 6, total = 600;
int prorated = 0;
prorated = (int)(Math.Round(((double)num / den) / block * total, 0)) * block;
Console.WriteLine(prorated);

The only things to note are the casts to int and double. And that the example was quite contrived.