Sunday, 5 February 2017

Bait And Switch (Part 2/2)

There will be times when a project you're working on is put under periodic review. Attending the meeting, invariably, will be one or two senior personnel whose sole purpose is to make suggestions which sound productive, but, more often than not, are a frivolous waste of time. Don't get me wrong - honest, constructive feedback is always welcome and if this results in extra hours or even weeks of re-work, so be it. But while the feedback is often honest enough, it tends to be hardly constructive.

These people tend to talk for the sake of talking. Because they're in a senior position and therefore feel they have to somehow justify their presence at the meeting. Thus, they say the first thing that comes to mind, and this sometimes has appalling consequences as implementing their suggested changes may involve excruciating hours of software surgery they think should be easy for you. They're not doing it on purpose, mind you - that would require technical know-how. They're just trying to hit their KPI, which often just amounts to making themselves look like part of the creative process, however nominally.

One countermeasure for times like this, is The Chaff.

Guided missiles at the ready.

The Chaff

During my time in the Republic of Singapore Navy, we were trained in missile countermeasures. This involved something known as the chaff. In layman's terms, this involves confusing the lock-on of an incoming guided missile by dispersing false targets, useless bits of matter known as "chaff", to cause the missile to detonate early and (hopefully) away from its intended target.

It's classic misdirection - distract the enemy with something totally unrelated to what he's aiming at, and prevent him from doing real damage.

So if, for example, you're performing a presentation for an audience which you know includes the people mentioned at the top, the same principle applies. Their motive is to find something to criticize. So give them something to criticize. Something they can point out for you to change. Preferably something obvious enough that will look like a sizeable contribution to the project.And, most importantly, something that is totally unconnected to the delicate parts of your project.

You could make the title headers of your pages a few sizes too big - not enough for it to feel deliberate, but enough for people to say "we need to make those headers smaller". A CSS change, and you're done.

Or you could choose colors that don't exactly clash, but are either too faint or too striking, enough to lead these people into saying "the color scheme needs to change". Again, the resultant change makes the project look almost completely different.

Or cram your pages with loads and loads of information, to the point where they say "can we do away with this, or just hide it?" Comment out some code, and you're golden.

They meet their objective - they get to look like they're involved and important to the process. You meet your objective - you draw their attention away from frivolous changes to delicate parts of the project, and in the process you preserve your sanity. Win-win!

For a more classic example of this, follow this link: https://en.wikipedia.org/wiki/Law_of_triviality\

Isn't this unethical?

That depends on what you use it for. If you do it to mask some very real issues with your system design, then yes it is horribly unethical and you need to stop. But if you're just intending to stop people from suggesting drastic change for the sake of change, then no, you've actually just done everyone a big favor. The changes proposed would have been a lot of work for no discernible benefit. The company is paying for your time and it is imperative that your time is used wisely.

Donald Trump does this too!

It's the Year of the Trump, and our boy has been up to some attention-grabbing shenanigans lately. From the Twitter wars over Melanie Griffith's infamous acceptance speech to the hoo-ha over crowd sizes at his inauguration, Donald Trump has been the topic of many memes and Social Media wars for his apparent pettiness. Seriously, does any of this look familiar to you? They appear to be the hallmarks of a raving madman who has messed up his priorities, but to me they look like clear attempts at misdirection.

I can just imagine him saying "Hey, these guys want to feel like their voices matter, right? Let's give them something to talk about. Make them feel all involved and shit."

And, unfortunately, it seems to be working. Many have taken the bait - hook, line and sinker. They stay awake at 3am waiting for the predictable inflammatory tweet so they can rage over it. They lose no time refuting and obsessing over everything his team says and does, even if it looks trivial. In their zeal, they compare themselves to activists and freedom fighters.

No, Donald old boy. I see what you're doing there. I've pulled this stunt too often in the last ten years to be taken in. I understand that what you allow people to see is often less alarming than what you don't. The Titanic wasn't sunk by the visible tip of the iceberg. She was sunk by the part of the iceberg beneath the water.

I'm watching you, dude. Like a hawk.

Conclusion

Neither of these tactics are particularly admirable. It may end with your superiors feeling foolish when they realize they've been had, and you know how sensitive these people get. Sudden unemployment may not be the worst of it. Some of the management people I've spoken to on this, get incredibly defensive when these tactics are revealed. Not that I blame them - as mentioned earlier, people hate being manipulated, especially by those occupying the lower rungs of the hierarchy.

Hey, look, a UFO!
T___T

Thursday, 2 February 2017

Bait And Switch (Part 1/2)

Today we're going to talk about bait-and-switch tactics. The term is well-defined here, but basically the principle is to show something, reel the suckers in, and manipulate them into doing more or less what you intended, all the while letting them think it was their idea.

Devious, eh? Think sleight of hand is only for illusionists and conmen? Think again. Developers employ a fair bit of psychological warfare in the course of their work, not that many would ever admit it.

At least, well, not in the presence of their employers.

These tactics are mainly used against laypeople. Why laypeople?

First off, I just want to say that laypeople, for the most part, are wonderful people just like you and me. Unfortunately, due to their lack of technical knowledge, they can be a right pain in the arse to work for. Or with. As a vendor, I've had to deal with clients who are laypeople. As an in-house developer, I've had to develop systems for management who are laypeople. And they have a knack - a gift, even - for making the most frustrating decisions. Decisions that go against almost everything you know about developing working software. Decisions that undo hours and weeks of work on a whim.

Sometimes their decisions are sound - based on marketing principles, domain knowledge and very practical objectives.

And sometimes, their decisions are based on feelings. Jesus Christ.

I'm not saying you should employ these tactics. But if you do, please employ them with a modicum of subtlety. No one likes being manipulated, least of all those in managerial position who are delegating these tasks to you, the minion.

Here are a couple of examples...


Multiple choices.

The False Choice

Web developers would have gotten this one a lot. The client, or the marketing manager, want a design for the web. And they feel that they should have an array of designs to choose from. So instead of devoting your attention to one design, you have to devote your attention to several designs before you can even start working in earnest.

Sounds like fun already?

Well, let's just say you already have an idea for what the product ought to look like. But you know, from experience, that they're not going to be convinced unless you offer alternatives.

So give them alternatives. Work on the one design you think is the best choice, then spend a few minutes churning out alternative choices that are utter crap obviously sub-par. Anyone with any sense would take the design you slaved over for hours, right?

This tactic is based off this joke. It's a bit racist, but the point is in the punchline.
Dear Mother and Dad:

It has been three months since I left for college. I have been remiss in writing and I am very sorry for my thoughtlessness in not having written before. I will bring you up to date now, but before you read on, please sit down. You are not to read any further unless you are sitting down, okay.

Well then, I am getting along pretty well now. The skull fracture and the concussion I got when I jumped out of the window of my dormitory when it caught fire shortly after my arrival are pretty well healed by now. I only spent two weeks in the hospital and now I can see almost normally and only get those headaches once a day.

Fortunately, the fire in the dormitory and my jump was witnessed by an attendant at the gas station near the dorm, and he was the one who called the Fire Dept. and the ambulance. He also visited me at the hospital and since I had nowhere to live because of the burnt out dormitory, he was kind enough to invite me to share his apartment with him. It's really a basement room, but it's kind of cute. He is a very fine boy and we have fallen deeply in love and are planning to get married. We haven't set the exact date yet, but it will be before my pregnancy begins to show.

Yes, mother and dad, I am pregnant. I know how very much you are looking forward to being grandparents and I know you will welcome the baby and give it the same love and devotion and tender care you gave me when I was a child. The reason for the delay in our marriage is that my boyfriend has some minor infection which prevents us from passing our premarital blood tests and I carelessly caught it from him. This will soon clear up with the penicillin injections I am now taking daily.

I know you will welcome him into the family with open arms. He is kind and although not well educated, he is ambitious. Although he is of a different race and religion than ours, I know that your oft-expressed tolerance will not permit you to be bothered by the fact that his skin color is somewhat darker than ours. I am sure you will love him as I do. His family background is good too, for I am told his father is an important gunbearer in the village in Africa from which he comes.

Now that I have brought you up to date, I want to tell you there was no dormitory fire; I did not have a concussion or a skull fracture; I was not in the hospital; I am not pregnant; I am not engaged. I do not have syphillis, and there is no Negro in my life. However, I am getting a D in sociology and an F in science; and I wanted you to see these marks in proper perspective.

Your loving daughter,


The problem with this, is that there is no accounting for taste. The decision makers may take one look at some piece of junk you cobbled together in minutes and fall madly in love with it while the piece you poured your heart and soul into, goes languishing. It happens, trust me on this. The best advice I could give you is - just do your best. This tactic sucks, and half the time you'll end up bitterly disappointed.

Next

Let's examine another tactic, The Chaff

Monday, 30 January 2017

Some leverage, please.

Time for another war story. It's a short one.

It was about three years ago when I joined a company as an in-house web developer. I was reporting to a younger guy, who was my manager. The CEO invited us out for lunch, and we all engaged in some small talk. The CEO asked if we were married, with kids. My manager was. I wasn't, and informed him as such.

Perhaps I was being oversensitive, but I detected a certain change in the CEO's expression, and sensed that he was displeased with what he heard. This brought to mind some dialogue I had heard once, in the movie Hercules, starring the electrifying one, Dwayne Johnson.

Hercules: I wanted nothing!
King Eurystheus: Precisely! Your sin, Hercules, was that you had no ambition! I can deal with an ambitious man! He can be bought! But a man who wants nothing has no price!

In here, King Eurystheus explains to a chained Hercules why he murdered his family and set him up for those murders.  

A man who wants nothing has no price.

I had no wife, no kids. Accountable to no one but myself. The fact that I was willing to take orders from someone younger and less experienced, showed that I had no ambition to speak of. None that lay in his company, anyway. I could not be bought, not with the currency he had. And since I could not be bought, I could not be controlled. This made me a far more risky prospect than my manager.


Can't be strung along.

My CEO's mental gears were probably busy turning, calculating just how far I could be counted on. Later on, the relationship between the CEO and I deteriorated somewhat. There were other factors involved, but this was probably the first crack.

Many bosses want a certain amount of leverage over their employees. For some, it's friendship. For others, it's money. Or the promise of a promotion. This makes employees easier to motivate, or more cynically, to manipulate. I call this the Chinese Towkay Syndrome. They pay you, and therefore they want to own you.

There was nothing this particular boss could do to make me stay on if I decided I was tired of his crap, nothing he could do to squeeze that last ounce of productivity from my old bones. To some extent, people become bosses because they like being in control. I was that wild card. That one random variable.

The Wild Card.


I understood this principle. And my concession to this was, from then on, whenever questions of this nature were asked, I would take great pains to mention that I am currently in debt servicing a huge thirty-year loan for my apartment's mortgage. That should be leverage enough for the average boss. It changes nothing - if I want to leave, I'm confident enough in my ability to land another job. But perception is everything, and if this gives my employers the impression that I can be controlled, I'm more than willing to play along.

It's been three years. But better late than lever. (hur hur)
T___T

Saturday, 21 January 2017

Web Tutorial: Year of the Rooster Song and Dance

A blessed and fortune-filled Chinese New Year to all! It's the Year of the Rooster and to mark the occasion, I'd like to walk you through a little fun assignment - a QBasic animation and song.

Sound in QBasic is pretty much a function of supplying different tones at different frequencies. For me, it was a whole mess of trial and error, but once you hit the right first few notes, the rest just sort of fall into place.

In fact, we're going to start off with this...
DIM basetune$
basetune$ = "C-6 C+6 D6 E6 G3 F+4 F+6 B6 B6 F+6 F+3 F-4 F-6 G6 G-6 E6 E3 D4 D6 C+6 C-6 <B-6 >C-3 C-4 E4 G-8 D4 G-8 D-6 G-8 C-6 G-8 E4 G-8 D4 G-8 D-6 G-8 C-6"

PLAY basetune$


When you compile and run, your computer should emit that lovely Chinese New Year song.

Now make the following changes, creating bgtune as a new string variable. This plays the previous tune, then replays it in a higher pitch courtesy of the ">" symbol.

DIM basetune$
basetune$ = "C-6 C+6 D6 E6 G3 F+4 F+6 B6 B6 F+6 F+3 F-4 F-6 G6 G-6 E6 E3 D4 D6 C+6 C-6 <B-6 >C-3 C-4 E4 G-8 D4 G-8 D-6 G-8 C-6 G-8 E4 G-8 D4 G-8 D-6 G-8 C-6"

DIM bgtune$
bgtune$ = basetune$ + " > " + basetune$

PLAY bgtune$


And again!

DIM basetune$
basetune$ = "C-6 C+6 D6 E6 G3 F+4 F+6 B6 B6 F+6 F+3 F-4 F-6 G6 G-6 E6 E3 D4 D6 C+6 C-6 <B-6 >C-3 C-4 E4 G-8 D4 G-8 D-6 G-8 C-6 G-8 E4 G-8 D4 G-8 D-6 G-8 C-6"

DIM bgtune$
bgtune$ = basetune$ + " > " + basetune$ + " >> " + basetune$

PLAY bgtune$


It may all be a little too high pitched, so just add this to the beginning...
bgtune$ = "<<<" + basetune$ + " > " + basetune$ + " >> " + basetune$

PLAY bgtune$


But what's music without a little dance, right? Let's make a rooster dance right here, on screen. To do that, we'll need to draw a rooster on screen. We'll draw different parts of the rooster and animate those parts separately. And, to make our life easier, we'll rely on some good old-fashioned abstraction.

First, we'll need a delay subroutine. Let's create one, and call it, very imaginatively, delay(). A variable Value is passed in, and that is the number of milliseconds you want the function to delay by.

bgtune$ = "<<<" + basetune$ + " > " + basetune$ + " >> " + basetune$

PLAY bgtune$

SUB delay (Value!)

END SUB


The variable T is set to the number of milliseconds since midnight.
SUB delay (Value!)
    T! = TIMER
END SUB


And after that, we use a DO: LOOP UNTIL loop that does nothing until the T subtracted from the current number of milliseconds since midnight, equals or exceeds the value of parameter Value.
SUB delay (Value!)
    T! = TIMER
    DO: LOOP UNTIL (TIMER - T!) >= Value!
END SUB


Then we'll need another subroutine, drawstr(). Here, we pass in the parameters row, col, fg, bg and text. text is the string you want to print, while the rest are integers.
SUB delay (Value!)
    T! = TIMER
    DO: LOOP UNTIL (TIMER - T!) >= Value!
END SUB

SUB drawstr (row, col, fg, bg, text$)
    PRINT text$
END SUB


row and col define where your cursor is going to start drawing.
SUB drawstr (row, col, fg, bg, text$)
    LOCATE row, col
    PRINT text$
END SUB


fg is the foreground color of your string, and bg is the background color.
SUB drawstr (row, col, fg, bg, text$)
    COLOR fg, bg
    LOCATE row, col
    PRINT text$
END SUB


Now we begin drawing the head of the rooster. It's the subroutine draw_head1(), and here you pass in a variable bg which will be used as the background color. Then it's a simple matter of using the drawstr()  subroutine to draw each line of the rooster's head.
SUB drawstr (row, col, fg, bg, text$)
    COLOR fg, bg
    LOCATE row, col
    PRINT text$
END SUB

SUB draw_head1 (bg)
    CALL drawstr(2, 29, 0, bg, " ")
    CALL drawstr(2, 30, 0, 4, "    ")
    CALL drawstr(2, 34, 0, bg, " ")
    CALL drawstr(3, 29, 0, bg, " ")
    CALL drawstr(3, 30, 0, 15, " o  ")
    CALL drawstr(3, 34, 0, 4, " ")
    CALL drawstr(3, 35, 0, bg, " ")
    CALL drawstr(4, 28, 0, bg, " ")
    CALL drawstr(4, 29, 14, bg, "<")
    CALL drawstr(4, 30, 0, 15, "    ")
    CALL drawstr(4, 34, 0, 4, " ")
    CALL drawstr(4, 35, 0, bg, " ")
    CALL drawstr(5, 29, 0, bg, " ")
    CALL drawstr(5, 30, 0, 4, " ")
    CALL drawstr(5, 31, 0, 15, "   ")
    CALL drawstr(5, 34, 0, bg, " ")
END SUB


Let's test this subroutine out. declare a variable, bg, in the main body. We'll set bg to 6, which is a lovely orange. Then we cover the entire screen in this color using the CLS function.
PLAY bgtune$

DIM bg
bg = 6

COLOR 0, bg
CLS


Then call the draw_head1() subroutine passing in the 2 as a test argument, which is green.
PLAY bgtune$

DIM bg
bg = 6

COLOR 0, bg
CLS

CALL draw_head1(2)


This is what you have! Don't worry about the jarring green background. This is a test, remember?



But you'll notice that the song has to finish playing before your code will run. Add this to your bgtune variable. Now your tune runs in the background!
bgtune$ = "mb <<<" + basetune$ + " > " + basetune$ + " >> " + basetune$


Write the draw_head2() subroutine. It's almost a mirror of the draw_head1() subroutine, with a few differences.
SUB draw_head1 (bg)
    CALL drawstr(2, 29, 0, bg, " ")
    CALL drawstr(2, 30, 0, 4, "    ")
    CALL drawstr(2, 34, 0, bg, " ")
    CALL drawstr(3, 29, 0, bg, " ")
    CALL drawstr(3, 30, 0, 15, " o  ")
    CALL drawstr(3, 34, 0, 4, " ")
    CALL drawstr(3, 35, 0, bg, " ")
    CALL drawstr(4, 28, 0, bg, " ")
    CALL drawstr(4, 29, 14, bg, "<")
    CALL drawstr(4, 30, 0, 15, "    ")
    CALL drawstr(4, 34, 0, 4, " ")
    CALL drawstr(4, 35, 0, bg, " ")
    CALL drawstr(5, 29, 0, bg, " ")
    CALL drawstr(5, 30, 0, 4, " ")
    CALL drawstr(5, 31, 0, 15, "   ")
    CALL drawstr(5, 34, 0, bg, " ")
END SUB

SUB draw_head2 (bg)
    CALL drawstr(2, 28, 0, bg, " ")
    CALL drawstr(2, 29, 0, 4, "    ")
    CALL drawstr(2, 33, 0, bg, " ")
    CALL drawstr(3, 28, 0, bg, " ")
    CALL drawstr(3, 29, 0, 15, " u  ")
    CALL drawstr(3, 33, 0, 4, " ")
    CALL drawstr(3, 34, 0, bg, " ")
    CALL drawstr(4, 27, 0, bg, " ")
    CALL drawstr(4, 28, 14, bg, "<")
    CALL drawstr(4, 29, 0, 15, "    ")
    CALL drawstr(4, 33, 0, 4, " ")
    CALL drawstr(4, 34, 0, bg, " ")
    CALL drawstr(5, 28, 0, bg, " ")
    CALL drawstr(5, 29, 0, 4, " ")
    CALL drawstr(5, 30, 0, 15, "   ")
    CALL drawstr(5, 33, 0, bg, " ")
END SUB


Now test using a FOR loop and the delay() subroutine. Does the head move?
COLOR 0, bg
CLS

FOR i = 0 TO 10 STEP 1
    CALL draw_head1(2)
    CALL delay(0.5)
    CALL draw_head2(2)
    CALL delay(0.5)
NEXT i


Change the code by passing in the actual background color, bg. Compile and run again. Is the animation right?
FOR i = 0 TO 10 STEP 1
    CALL draw_head1(bg)
    CALL delay(0.5)
    CALL draw_head2(bg)
    CALL delay(0.5)
NEXT i


In the same vein, write the subroutines draw_legs1(), draw_legs2(), draw_body1(), draw_body2(), draw_tail1() and draw_tail2(). You may notice that the draw_body1() and draw_body2() subroutines do not require parameters. That's because the animation does not change the shape of the body at all.
SUB draw_head2 (bg)
    CALL drawstr(2, 28, 0, bg, " ")
    CALL drawstr(2, 29, 0, 4, "    ")
    CALL drawstr(2, 33, 0, bg, " ")
    CALL drawstr(3, 28, 0, bg, " ")
    CALL drawstr(3, 29, 0, 15, " u  ")
    CALL drawstr(3, 33, 0, 4, " ")
    CALL drawstr(3, 34, 0, bg, " ")
    CALL drawstr(4, 27, 0, bg, " ")
    CALL drawstr(4, 28, 14, bg, "<")
    CALL drawstr(4, 29, 0, 15, "    ")
    CALL drawstr(4, 33, 0, 4, " ")
    CALL drawstr(4, 34, 0, bg, " ")
    CALL drawstr(5, 28, 0, bg, " ")
    CALL drawstr(5, 29, 0, 4, " ")
    CALL drawstr(5, 30, 0, 15, "   ")
    CALL drawstr(5, 33, 0, bg, " ")
END SUB

SUB draw_tail1 (bg)
    CALL drawstr(5, 45, 0, bg, " ")
    CALL drawstr(5, 46, 0, 4, "      ")
    CALL drawstr(5, 52, 0, bg, "  ")
    CALL drawstr(6, 44, 0, bg, " ")
    CALL drawstr(6, 45, 0, 4, "     ")
    CALL drawstr(6, 50, 0, bg, "    ")
    CALL drawstr(7, 44, 0, bg, " ")
    CALL drawstr(7, 45, 0, 4, "  ")
    CALL drawstr(7, 47, 0, bg, "       ")
    CALL drawstr(8, 44, 0, bg, " ")
    CALL drawstr(8, 45, 0, 4, " ")
    CALL drawstr(8, 46, 0, bg, "        ")
    CALL drawstr(9, 44, 0, bg, " ")
    CALL drawstr(9, 45, 0, 4, " ")
    CALL drawstr(9, 46, 0, bg, "        ")
END SUB

SUB draw_tail2 (bg)
    CALL drawstr(5, 46, 0, bg, " ")
    CALL drawstr(5, 47, 0, 4, "     ")
    CALL drawstr(5, 52, 0, bg, "  ")
    CALL drawstr(6, 45, 0, bg, " ")
    CALL drawstr(6, 46, 0, 4, "     ")
    CALL drawstr(6, 51, 0, bg, "    ")
    CALL drawstr(7, 44, 0, bg, " ")
    CALL drawstr(7, 45, 0, 4, "  ")
    CALL drawstr(7, 47, 0, bg, "       ")
    CALL drawstr(8, 44, 0, bg, " ")
    CALL drawstr(8, 45, 0, 4, "  ")
    CALL drawstr(8, 47, 0, bg, "        ")
    CALL drawstr(9, 44, 0, bg, " ")
    CALL drawstr(9, 45, 0, 4, " ")
    CALL drawstr(9, 46, 0, bg, "        ")
END SUB

SUB draw_body1 ()
    CALL drawstr(6, 30, 0, 15, "    ")
    CALL drawstr(7, 29, 0, 15, "     ")
    CALL drawstr(8, 28, 0, 15, "      ")
    CALL drawstr(9, 27, 0, 15, "       ")
    CALL drawstr(10, 27, 4, 15, "                   ")
    CALL drawstr(11, 28, 4, 15, "   .    .  )      ")
    CALL drawstr(12, 29, 4, 15, "  .    . )      ")
    CALL drawstr(13, 30, 4, 15, "   ..   )    ")
    CALL drawstr(14, 31, 4, 15, "           ")
END SUB

SUB draw_body2 ()
    CALL drawstr(6, 30, 0, 15, "    ")
    CALL drawstr(7, 29, 0, 15, "     ")
    CALL drawstr(8, 28, 0, 15, "      ")
    CALL drawstr(9, 27, 0, 15, "       ")
    CALL drawstr(10, 27, 4, 15, "                   ")
    CALL drawstr(11, 28, 4, 15, "         .    )   ")
    CALL drawstr(12, 29, 4, 15, "    .  ..    )  ")
    CALL drawstr(13, 30, 4, 15, "   .   .   ) ")
    CALL drawstr(14, 31, 4, 15, "           ")
END SUB

SUB draw_legs1 (bg)
    CALL drawstr(15, 1, 14, bg, "                                  |   |")
    CALL drawstr(16, 1, 14, bg, "                                  |   |")
    CALL drawstr(17, 1, 14, bg, "                                  |   |")
    CALL drawstr(18, 1, 14, bg, "                                  |   |")
    CALL drawstr(19, 1, 14, bg, "                                  ^   ^")
END SUB

SUB draw_legs2 (bg)
    CALL drawstr(15, 1, 14, bg, "                                  |   |")
    CALL drawstr(16, 1, 14, bg, "                             >----|   |")
    CALL drawstr(17, 1, 14, bg, "                                      |")
    CALL drawstr(18, 1, 14, bg, "                                      |")
    CALL drawstr(19, 1, 14, bg, "                                      ^")
END SUB


Now, we'll use the first FOR loop we wrote as a test, and expand by adding calls to the subroutines for the rest of the rooster. Also, you may want to initialize the drawing of the rooster first.
DIM bg
bg = 6

COLOR 0, bg
CLS

CALL draw_head1(bg)
CALL draw_body1
CALL draw_legs1(bg)
CALL draw_tail1(bg)

FOR i = 0 TO 10 STEP 1
    CALL draw_head1(bg)
    CALL draw_body1
    CALL delay(0.5)
    CALL draw_head2(bg)
    CALL draw_body2
    CALL delay(0.5)
NEXT i


We have a dancing rooster!



Vary it up. Make different parts move using different FOR loops.
FOR i = 0 TO 10 STEP 1
    CALL draw_head1(bg)
    CALL draw_body1
    CALL delay(0.5)
    CALL draw_head2(bg)
    CALL draw_body2
    CALL delay(0.5)
NEXT i

FOR i = 0 TO 10 STEP 1
    CALL draw_legs1(bg)
    CALL draw_body1
    CALL delay(0.5)
    CALL draw_legs2(bg)
    CALL draw_body2
    CALL delay(0.5)
NEXT i

FOR i = 0 TO 10 STEP 1
    CALL draw_tail1(bg)
    CALL draw_body1
    CALL delay(0.5)
    CALL draw_tail2(bg)
    CALL draw_body2
    CALL delay(0.5)
NEXT i

FOR i = 0 TO 10 STEP 1
    CALL draw_head1(bg)
    CALL draw_legs1(bg)
    CALL draw_tail1(bg)
    CALL draw_body1
    CALL delay(0.5)
    CALL draw_head2(bg)
    CALL draw_legs2(bg)
    CALL draw_tail2(bg)
    CALL draw_body2
    CALL delay(0.5)
NEXT i

And there you go...

Dancing rooster. Clunky graphics, very retro. But still awesome McCool.

Once again, Gong Ji Fa Cai!
T___T

Monday, 16 January 2017

Fiction Review: The Millennium Series (Part 4/4)

And now we come to the final (so far) book in the series. This struck me as an unnecessary continuation of what was already a series with a satisfying conclusion, but given that Larsson actually had more novels planned out, this may not be a bad thing.



I didn't like this newest addition very much, but this is my opinion and I may be biased here. There are plenty of things to like about it, though for me, the cons far outweigh the pros.

The Premise

Lisbeth Salander, Ronald Neidermann and Alexander Zalachenko are not the only badasses in the family - there's also Lisbeth's twin Camilla Salander and she turns out to be every bit the villain their father was. She sets up The Spider Society which has illegal dealings with the NSA, and only the team of Lisbeth and Mikael are able to stop them.

The entire novel begins with Frans Balder reclaiming his autistic child August from his estranged wife. Chapters later, Frans is murdered and Mikael, who is at the scene of the crime, begins to do what he does best - investigate and report.

Along the way, he discovers that Lisbeth has had dealings with certain associates of Frans.

Meanwhile, August has seen the murderer's face, and the Spider Society is determined to stop the boy before he can give the murderer away to the police. Lisbeth steps in to save the day, and it's a desperate race to keep August alive and unharmed until he can finally put a face to the hitman.

The Characters

These characters play a major role.

August Balder. A strangely gifted child. The story revolves around him and his gifts. Lisbeth sees in him a kindred spirit, mostly because for most of the first three novels she was pretty awkward herself due to her abilities.

Camilla Salander. Lisbeth's twin, and possibly the most evil foe she's had to face to date. While their father Zalachenko was also an evil bastard, he was mostly ruthless and pragmatic. Camilla seems to inflict torture for the sheer pleasure of it, psychologically tormenting her victims through seduction and emotional manipulation.

Edwin Needham, or "Ed the Ned". Started life as a young thug but became a computer genius later on in life and took on the role as NSA's chief cyber-security tech. Aggressive, loud and a bully, but undeniably good at what he does, and admirably dedicated to his craft.

Frans Balder. A socially awkward computer nerd who also happens to be the genius who invents some artificial intelligence that someone wants to steal. He's also portrayed as an anxious father who's somewhat clumsy with his affections.

Jan Holtser. The hitman. Ex-military. Deeply conflicted. While he's a stone-cold killer, he struggles with his conscience when ordered to kill August Baldur.

Lisbeth Salander. She is somehow more action figure than super-hacker in this tale, though plenty is mentioned about her computer wizardry and cyber coups. Just as awesome as ever.

Mikael Blomkvist. Our ever-intrepid journalist who finds himself in the thick of things once more. At the start of the novel, he's in the midst of a professional crisis, having run out of compelling material and finding himself up against the challenges of emerging technology. What he needs is some motivation... and unexpectedly he's handed a huge chunk of it after witnessing Frans Balder's murder.

List of supporting characters...

Andrei Zander. A young, handsome aspiring journalist with the soul of a poet. Earnest and geeky, which endears him to the staff at The Millennium despite his lack of journalistic experience. Meets a tragic end at the hands of the Spider Society.

Gabriella Grane. Analyst at the Security Police. Pretty and wholesome. Faces some misogyny at work but lets her performance speak for itself.

Hanna Westman. Actress and Frans Balder's ex-wife, mother of August. An abused woman who has long lost the courage to break away from her abuser. Tries to cover it up with glamor, but one gets the distinct impression that her life is both hollow and miserable.

Lasse Westman. An bullying abusive drunk, rather dim and prone to fits of impulse. An actor who portrays, rather fittingly, dangerous and violent characters on-screen. Gets his ass pounded by Lisbeth in a carthatic moment near the end.

Ove Levin. A corporate stooge who used to be an aspiring journalist just like Mikael - except Mikael made it while Ove sold out. Now Ove desperately tries to convince himself that he's happy and wouldn't give up what he has for whatever Mikael's got, but the truth is that he's terrible jealous and insecure. When he fails to gain Mikael's approval, he resorts to trying to destroy him by making moves on The Millennium.

Supporting characters who play  a less prominent role.

Arvis Wrange. One of Frans Baldur's proteges. He betrays Frans Baldur for money, and this leads to Balder's death. His guilty conscience catches up to him in the form of Lisbeth Salander, who first gives his ego a severe beating by trashing him soundly at chess.  A deeply insecure man who masks it through misogyny and excessive pride.

Farah Sharif. She serves to provide some insight as to what Baldur had been working on. And also serves as a love interest for Bublanski, which was cute. Described as an elderly but very attractive woman, which made me afraid that she'd end up having sex with Mikael.

Jan Bublanski. One of my favorite characters in the series makes it to this novel! Here, he's good ol' crusading Officer Bubble, and he does a good bit of poking around. Near the end of the novel, there's even an endearing bit about a blossoming relationship between him and Farah Sharif. "It's just a date". Hah!

Jurij Bogdanov. Street punk and drug addict turned computer genius. A hard luck turnaround story except that he still works for the bad guys and loves it, the little sociopath.

Linus Brandell. He is Blomkvist's initial contact and provides the first inkling that Lisbeth is involved. Comes off as nerdy and awkward, which really hits home after he describes his initial meeting with Lisbeth.

Sonja Modig. Little part in the story, except to argue with Mikael on matters of police procedure. And be the good cop to Officer Bubble's bad cop. Sort of.

Here are the characters who play a very minor role or likely did not even need to be in this novel.

Alona Casales. A middle-aged temptress with a seductive voice and an attraction towards Gabriella Grane. Great buddies with Needham because she sees him as a kindred spirit.

Professor Charles Edelman. A Hungarian authority on the subject of  neurology.

Dan Flinck. Police Officer sent to watch over Frans and August. A divorcee experiencing the good bachelor life again. Does not come off as particularly competent.

Einar Forsberg. At Oden's, taking care of August. Infatuated with Hanna Westman.

Erik Zetterlund. Leader of the investigating team on duty from the Violent Crimes Division on the night of Frans Balder's murder. Not particularly self-assured and seems rather harried at the situation.

Erika Berger. Has little more than a bit part to play. She passes the odd message and runs The Millennium. That's about it.

Helena Kraft. Gabriella's boss. Well-starched, not a hair out of place. Gabriella first suspects her of being a mole, but this turns out to be a red herring. Not much of a personality, all in all.

Holger Palmgren. Has little to do in this story but act as exposition for more of Lisbeth Salander's backround. He and Mikael seemed to have formed some kind of bond in this novel, possibly through the harrowing experiences of The Millennium series. Much as I love this character, his presence was really superfluous.

Plague. More tales of how he and Lisbeth break into computer systems and hack their way to awesomeness.

Jacob Charro. A football player for Syrian FC. He is the driver of the car that Lisbeth hijacks to get August to safety, and later gives an accounting of the tale to the authorities. His description of Jan Holtser is particularly interesting.

Margereta Dalhgren. A woman who has endured a tragic past thanks to Camille. Her story is heartbreaking and really underlines how psychotically evil Camille is.

Obinze. Boxing gym owner. Flirts with Lisbeth shamelessly and is even a little in awe of her single-minded focus and determination.

Peter Blom. Police Officer sent to watch over Frans and August. Almost identical to Flinck, except that he's portrayed with very human fear.

Richard Ekström. As self-centered and pragmatic as ever. Dreads having to deal with Blomkvist again after the events of the previous two novels,

Roger Winter. Another small-time actor who physically abuses August with Lasse Westman's encouragement. Also gets his ass kicked by Lisbeth.

Torkel Linden. At Oden's. Short and prissy. Pugnacious when dealing with Jan Bublanski. And very uncooperative until Sonia Modig does the negotiating.

The Mood

Mostly surreal and disquieting. Even the moments where blood gets spilled just seem to happen in slow motion. At the end of it, one gets the sense that very little has significantly changed - Baldur's murderer is brought to justice, but Lisbeth's evil twin and The Spider Society escape, presumably to wreak more havoc another day.

The mood rarely changes. The pace of the story remains somewhat constant throughout.

What I liked

Tech elements. They're simply more pronounced in this novel, with a few computer nerds among the characters that don't come from Hacker Republic. Lagencratz actually does a far better job in this department than Larsson.

Mikael's studliness. I know this is something I complained about in the previous novels, and I'm glad it's been toned down.

We finally meet Lisbeth's evil twin. Right on! She tries to seduce Mikael but fails. That's pretty awesome in itself.

I liked seeing August's abusive stepfather get his arse kicked by Lisbeth. Very satisfying.

The plot's pretty lean - some might say too lean, but I see this as a good thing. Less pointless subplots, more focus.

What I didn't

Mikael's studliness. Not only was it toned down, it was removed from the story. David Lagencratz himself confessed that it never made sense to him to have beautiful women falling for Mikael out of nowhere (for the record, I agree), and so he just never wrote it into the story. Now, this is where I disagree. For better or worse, this is part of the character of Mikael Blomkvist now and has been established over the course of three novels. I could accept it if the new, non-womanizing Mikael was a result of character growth, but no - that aspect of the character was simply retconned. If Lagencratz found that he was unable to bring himself to write the character the way the original character wrote him, why the hell did he even agree to do this novel? Was the money that good?

Established facts in the previous novels just got written off with no explanation whatsoever. Whatever happened to Monica Figuerola? Wasn't she and Mikael in a serious relationship? What about Sonja Modig? Since when was Modig a single parent? This is just sloppy and disrespectful.

Character overload. There was a somewhat plausible excuse for this in The Girl Who Kicked The Hornet's Nest, as characters accumulated from the first two novels and many were vital to the events conclusion, though, in my opinion, it was still overdone. Here, it's a fresh new storyline and very little baggage from previous novels. However, David Lagercrantz seems determined to match the character count from The Girl Who Kicked the Hornet's Nest, for no discernible reason. Characters are introduced seemingly on a whim and have effects on the plot that could easily be carried out by an existing character. Take Einar Forsberg and Torkel Linden, for example. Was it necessary to introduce two characters at Oden's just to provide obstacles to Officle Bubble and Sonja Modig? Or Dan Flinck and Peter Blom. It was over-indulgent. What is this, some kind of pissing contest to see who can come up with more characters?

Some parts, from the NSA's spying on civilians to the loud bullying Needham, seem distinctively borrowed from Dan Brown's Digital Fortress. Ran out of ideas, Lagercrantz?

Conclusion

I'm sure David Lagercrantz is a fine author in his own right, perhaps an even better novelist than Steig Larsson. I'm just not sure he was the correct choice to carry on Larsson's legacy. The contrast in style was jarring in places. The Millennium Series was far from perfect, but despite its eccentricities, or more probably because of them, they had their distinct charm. This charm is missing from The Girl in the Spider's Web.

Part of the problem could be the fact that Larsson's characters were not created by Lagercrantz, and it shows. Apart from Lisbeth and arguably Jan Bublanski (who was a supporting character anyway), he can't seem to grasp the essence of most of the existing characters, but does considerably better when describing new characters.

Oh well, this was always going to be a thankless task.

My Rating

6 / 10

What a story. What a girl-minator.
T___T