Showing posts with label engineering. Show all posts
Showing posts with label engineering. Show all posts

Monday, 29 August 2022

Home Engine - Bank Holiday Camera Controls & More Models

After the silence earlier in the year I'm so happy to be blogging more often, and I hope you are all enjoying it too; I can see some regulars popping by and a few new faces in the stats list; but still far too many of you are totally anonymous, drop me a comment!

Anyway, what I have I been up to?

Well, under the hood I've totally revamped how the uniform buffer objects are passed to the rendering operation in the vertex shader.  I've also moved the view and projection matrix calculations into a nice camera system class, so they're contained and sensible to use.

As a result I've then added some key bindings to move forward, strafe and rise/drop the camera on the plane of x-z.  Likewise I've added a free mouse mode to let me move the mouse and fly over the terrain.

Speaking of terrain I've added a checker board to show me the X-Z plane at about -0.5 Y.


I also noticed a winding order in my Blender exporter tool, I've not fixed that in the python, just patched it in my loader and created a few more models to start building out a play space.

Technology wise I need to make the camera more usable - a full third person camera basically.  Then I would like an orbit cam, which moving in the strafe would move it around the locked object.

Then I'm going to think about texturing and lighting.

The solid coloured aesthetic is intentional though, so anything more fancy is a low priority for me.

I am feeling much more comfortable in Vulkan though; and of course enjoyed moving all the glm implementation from the first (and second passes) over this project.

That's perhaps something I've not mentioned to you before, this project as a home engine... Well I've started and restarted it a few times.  The original was in DirectX9 way back; I wrote a page about it in 2004.

Then I re-wrote that in fixed function pipeline OpenGL; that didn't go very far, indeed I received a letter to cease and desist from an IP owner for that particular project's name was known in the wider world.  That IP has moved onto yet another owner now, so best of luck to them.

I however was knocked for six and it wasn't until 2018 that I started to look at a game engine at home again, spurred on by my change of job; and I really enjoyed that first pass, but it didn't focus on the graphics side of things, it was far more about the technology such as threading, memory management, and something you may have heard of, an Entity Component System.

All those pieces remain.

But this new project is very much just about my putting features together into a renderer, indeed the application level item is called "renderDemoApplication" and that is all this is.

What might the game be?  I'm still thinking about that, but I have three strong contenders and when I've picked one, you folks will be the first to hear about it.

Friday, 5 August 2022

I hate FizzBuzz and Will Analyse anyone who uses it

One FizzBuzz Interview so far.... News flash... The moment I am asked to write FizzBuzz during a technical test I intentionally stop and ask the questions from there on out.  I've done this a couple of times.  And you know what I learned... I learned a whole lot more about the interviewer and their processed than they found out about me.

Let me take you back to a technical interview I had about five years ago.

I drive up to the building, it is way out in the sticks; just about still in my home county, but so obscure it's in a part I have never ever been in.

I pull up and the building is like a box of black glass, no character, no soul, just a box.  The non-native tree species planted around it to discourage birds actually using the tree's and the austere grass puts me off.

Things don't get any better, for I walk through the door and there's no secretary, no desk, nothing... The lights aren't even on; this doesn't bode well.  I look around for a buzzer, a phone even a limp notice of what to do.  When a door opens and a man approaches offering me a hand to shake.  He leads me to a similarly deserted corridor with a chair in it and I'm left to my devices once again.

I read some inane notice about some award some member of the staff had received (this is important later in the interview) and I read the fire evacuation notice.  It's quiet, quiet and silent.  There's one door nearby with a few people within and another which is a closed office piled with stacks of desks..... Empty corridors - which would be dev spaces, massive rooms with a few people in them, no secretary and piles of desks?  What have I walked into?

About ten minutes later I'm ushered into this room, I've brought my CV a few piece of detail about me and some references to my technical projects at home; as well as references to some of the discussions I have on these very pages and my github.  You know actual technical things, which you can see me achieving.

I can't talk about my current work with them... Heck I can't talk to you guys about my work now.  But I do it, and I pay a mortgage; that's all the proof I can proffer.

Anyway, I seat myself and a lady explains their technical lead will come and perform the technical test, he enters a moment later with a massively overpowered gaming laptop.  I hate gaming laptops.

I much prefer a simple sleak laptop, a decent screen, nice keyboard and plenty of battery life; and I do my work on a remote machine via SSH or whatever machinations you wish.  I do not generally work on my laptop, it's a portal onto other more powerful machines which are tethered, and this way I can go take my laptop with me anywhere and get amazing performance from it, as I'm only interested in a bit of internet, RAM and then remoting into other services.

Anyway, he plonks this behemoth down and proceeds to tell me about test driven development... TDD.

I HATE TDD.

Now, I know test have a place, heck I really like doctest, including tests into code you've written, to ensure it is within specification is perfect, and validates your progress.

My hatred comes from writing tests up front, I find this backwards logic, and I don't think you could ever persuade me otherwise.  Define the scope of your input, validate it in your code (I often assert up front when data is unexpected or malformed, or at the very least bail early) and then you run your code, and then TEST the result.  I do not believe you should write a test and then further write the code to fulfill that test.

You will miss something, you will be thinking about the test as the solution, rather than the solution itself.

If anything writing the test and then producing the code to meet that test may very well be called TDD today, but when I was a lad it was called Prototyping.  And though I'm sure we can all agree prototyping is best done in a language different to your final product, it is not really prototyping when you are not producing the product, you're producing a test.

I find it wasteful of time, and often ignores enough scope, for instance I've seen a fair few hundred thousand up front tests written and then the code to meet them in my time, never have I seen a validation of the input data, the input has generally been hard set into the test.  That's not as wise a test-scope of ensuring the result after the fact.

(This does not mean test suits after the fact are the best, I just think they're the best for my style; not least as they are opt-in, for those times you are in a swing, and easy to add later).

So, TDD... Why is he telling me about TDD?

He does, he explains they have a method and that method is structured, he does not offer me any test framework specifically, instead he opens notepad and asked me to write FizzBuzz.

And the interview stops there; I don't think the guy realised it, but I stopped being interviewed at that point, I was not going to accept their job even if offered, but I wanted to see where this lad (and he was young) was going with his thinking.

This half empty hulking building and they're trying to hire engineers, and he is going on about TDD but FizzBuzz?

So I play total dumb, I simply start to write "int main"... And he surprises me.

"No No, start with the test".

Ohkakkkakay....

I have NO idea what test suites he has installed, I don't use G-Test or Boost-Test, I use doctest.  So I write a SCENARIO; he blinks and just takes the laptop off of me and starts to open some other window... I didn't know he would allow me to open some other window, this isn't my machine, I don't know what he has installed.

This sort of sums up TDD to me, the tools aren't easily defined.

Anyway, twenty minutes later and I just about have it Buzzing on 5's and I'm not very interested, I've come to a conclusion.

He isn't impressed; rightly so, but he has no idea he's just been investigated by an older and more cynical mind than his.

He leaves and no less than three people come into continue the conversation, and boy do they, they talk to me for a solid 120 minutes; I timed it... I was so bored.  But I engaged a little when they talked about their award winning technology.

I recall the poster for the lady who had won this award and mention her, by name.

"What, how do you, who has been talking to you?"

This is very strange, "no" I assure them "no-one, I saw the poster on the notice board".  One of the two girls flanking the chap in the middle here makes a note.

They talk to me about the company a bit more, they talk about their re-shuffling engineering and wanting to press their position forward to a virtual machine the customer hosts on hardware; previously they had been providing a dedicated box.

I'm terminally not interested in this boring black blocky building which now perfectly reflects the boring blocky people inside.

And I give up, I lean forward, elbows on the table, and I gather the copies of my CV from the hands of the three people and I say:

"Look, I've spoken with your technical lead, and I'm scared to my core of your processes, I don't like what I've heard, it seems you're struggling to recruit and there are reasons for this you will have to identify yourselves; I don't think I can help you"

They are scowling a little here, I'm sure they're far more used to candidates who want the job.

"Indeed, I think somewhere you have a beige room with ranks of screens and engineers in stuff suits not talking with a great board or wiki with all the failing builds traffic lit from your little test driven development board...."

At this point the lady on the left looks at the guy in the middle, who has a little switch to his eye.

"And such a stifling, control freak, desperate development environment is not one I wish to be part of"

They thank me, and I thank them sincerely.  And I leave.

As I come out of the building the sun has come around, the black glass face of the building is now not so black, instead I can see inside, there are three long benches of PC's all facing a pair of chaps at the front sporting bluetooth ear phones in one ear.  Above their heads is a large TV screen with a list of running continuous integration tasks and each has a traffic light.  As I watch one goes red, one of the two larger men touches the headset at his ear and an engineer on one of the benches glances up and starts to scrabble about on their machine.

It is a sweat shop.  I was not only right, but so happy I'm driving off.

I felt like going and knocking on the glass and cooing at them "Come, follow me, be free, be free".

But instead I just drove home.




Prior me: Just coming into edit this before it goes live on Friday, guess what I'm watching... 


And I disagree with the approach of analysing FizzBuzz; analyse the interviewer.

Friday, 12 February 2021

Debugging Techniques

 As a programmer there are many approaches to a take in solving a problem, I remember in my A-Level they talked about trace tables... A lot... I've used them now and then, but almost immediately machines were running so quickly as to make humanly computing any meaningful number of permutations near impossible... and we're talking only a 25Mhz machine.

Far more useful therefore was a decent watch value in a debugger, improved immeasurably by conditional break statements.

Even so there are always times when you need that holistic overview, my favourite approach for this is a huge wide whiteboard.  Many an hour have I spent around a whiteboard laying out the schemes of madmen and managers; the greatest compliment is then when finding that said folks have taken a cheeky photo and your whiteboard machinations appear in the manual.

But one of the best problem solving solutions is to share it, a problem shared can often become a problem halved; unfortunately not always for a programmer.  You see people are a creature of opinion and social status, this means you can often run into folks who believes their opinion is more valid than yours, which maybe so, but if their opinion means starting the whole problem over again it can often be more detrimental than asking for their help.  For help becoming opinion leads only to their being demons in the cupboard.

So what then?  Talk to one self?

And you know I think really rather that is one of the key approaches, talk to yourself.  Quite useful in the current pandemic too.

We have a term for this in Computer Circles, and we detract from the self by making our conversation focus on another object, such as a rubber duck... https://en.wikipedia.org/wiki/Rubber_duck_debugging

Or of course you can find your own devices....



Sunday, 10 November 2019

My First Piece of Software

What was the first piece of commercial software you wrote and what did it do?

This was a good question I was asked by a student interviewing me about my entry into being a software engineer, so I thought I'd share the answer.

It was a PC auditing software application, written in Turbo Pascal for DOS, it scanned your files identified a bunch of known executable and produced a finger print of your machine (linked to either the network Mac address or the BIOS serial number) it showed a number on the screen and I had a silver (label) punch to put that number into a hard metal sticker and put that onto the PC case.

This was used by Claremont Garments* (by me actually) to audit most all the machines they had, it was related to a commercial product we'd bought to do a similar task, but after a bit of tinkering I found my own solution did the task better, and I could export the data to a spreadsheet to produce reports more easily and cheaply than paying for the custom import tools.

I used this software throughout the UK, I sent it to a bunch of folks working with me from the London office and then North East office and finally it went with me for my sojourn in Morocco to audit everything.

I was actually waxing lyrical just today about in order execution of the 486, that first piece of software of mine was definitely operating "in order".

To this day I have fond memories of programming in Pascal for DOS.  And though this was not the first major piece of software I'd written, it was the first used for a commercial purpose and by someone other than me.




* Interesting link to the past, the Claremont site at which I worked was the Selston Factory, which is the town in which I now live... I have fond memories of that job, and I think a fair few people around here remember that factory.  It lives on under "Lilley Close" which is built on the site, but there is a commemoration of the factory in its original "Wood Bastow" incarnation.... That maybe another post I put together, to share with you all.

Wednesday, 13 June 2018

Technology CV's and Me

I've a small gripe with technology recruiters, if any of you out there are reading this (which since I just cast my CV around, you should be).

And this is their penchant for skills lists... I have a very minimalist CV, one page of A4, it covers the primary software languages I like (C++, C, C#) makes mention of my favourite working styles (Agile/Scrum) and it has my history and pertinent academic background.

That's all... Minimal, just me, my page one shot done.

Anymore and it never, ever, gets me anywhere.  It apparently comes across as "hey look at me" attempts to garner and keep attention with the right buzz words, which I myself despise.  Or it comes over as not having a lot to talk about in the interview, as everything you want to know might very well be in this tome of a CV, and I myself reading them find that I want to ask every question I can in the interview stage, so having it all there you disengage, hurting both your interest in the candidate and their chance to explain themselves to you.

So a long CV, in someways, is counter intuitive.

But then the skills list raises it's head, no my CV does not have a specific skills list, at the top is says Software Engineer.  That tells you everything you need know.

You don't got for brain surgery and stop the surgeon to ask whether they've the right skills to use a bone saw, did they spend two years in orthopedics first, did they complete their GCSE's.  No they're a brain surgeon.

So why when I present I'm a software engineer do you get these niggly folks asking "Do you know Java?"... "Hows your skills in C#"... or "You don't have enough experience on XboxOne"....

I literally laugh, I'm a software engineer, a good one, I live for tech, I can, have and will pick up any new language, machine or skill-set desired and very quickly.  I set out in the mid 90's to train for this, I was sitting up all night long tinkering on my computers and programming long before that official water-shed moment.

Therefore I have to ask,why do you need to put down these skill sets?  Why do you need to use the right buzz words?  Well, I think there's a two fold reply to that very question, first of all you may not be speaking to the most tech savvy of individual, they might just have a check-list of the right words, or the right fit to get you over the threshold and passing that initial interview.  Phone interviews are a bit of a blessing in this way, as you get to lay down your own proof of worth quickly.

The second reply being that the folks doing the hiring don't actually know what they are hiring, either because they remain the non-tech-savvy, or more commonly (more sadly) they've never met or worked with an engineer who has a genuine passion for their topic.  Yeah sure you can program, but are you interested in it?  Quite often the answer is no.

Many programmers I meet today are below that level of going in their own time to hack around with things, they're too busy life having grown out of what they see as the adolescent pass-time of tinkering.

I however value my tinkerers, they're the soul of the literally machine, driving innovation, improvement and even just evangelizing about new-ways and approaches to enhance their colleagues.

Such individuals are rare, I consider myself to be one, and hate when I'm asked to pour my soul into soulless lines on a page, get to know me, you never know... You might learn as much from me, as I might learn from you.

Thursday, 24 August 2017

Hard Drive Heat Problem

Most of us are well aware of how much heat electronic equipment puts out, what can be less intuitive and harder to balance is the problem of heat from hard drives.

Good organised machine operation, with clearly defined device usages, easy control of units across machines, sites or different customers is the key, therefore enter stage left a nice fat label to hold all the details of the unit.

Except, this label acts as a heat blocker, reducing the surface area of the metallic or foil labelled drive as delivered, reducing the area across which the heat from the unit can dissipate, and even causing uneven heating, or heat wearing over time.

The net result... For my project, a high mechanical drive mortality rate, which I simply could not explain, nor model or explain in the man lab.

Only a trip to see how these machines were being employed sufficed to show the problem, label after label applied and reapplied, a drive on within a machine was untouchable it got so hot.  My solution, put a number on the drive in marker pen and link that number to a database entry with all the drive information.

This solved the heat death problem.

But it also opened up the scope of the information being transmitted, with access to any smart phone the customer could then look up the information, so could their designated engineer, they need never bother me - which is again key to efficient business practice.

Like-wise those not wanting the quite useful information on the harddrive to be public, simply have their information about the drive secured away behind a password on the site, or even more simply not on the site.

Options and solutions, that's how I see this problem benefiting projects going forward... If only we'd not been putting label after label on for year after year.

Wednesday, 2 August 2017

Development: Design, Prototype then Code

When I were a lad, I were taught to use flow chart stencils....


I was shown how to write data dictionaries, to thought-cloud through the possible data members for these dictionaries, to define the mutable and non-mutable points and abstract away the common elements between these definitions in order to design the code to be written.

All pretty much on paper, before you sat before the computer.

The reason being?  Paper was cheaper than electricity, and it took a long time to compile and recompile, and then even longer to debug, a program.  Bugs got hidden and only appeared when testing took place.

And if a bug ended up in test, which could obviously have been caught on paper, long before it reached the coding phase, then you got egg on your face.  In a nice way, you all knew you had to do more than cut code.

Unfortunately Moores law exists, a blessing, and a curse.  As I feel it's made the quality of software design fall, as people can afford to code and compile and try before thinking.

No-one I work with, certainly no-one immediately around me, designs anything on paper, or performs thought exercises on the task before diving at the keyboard.  Event when they have dived at a keyboard they're not prototyping, they're immediately producing code for release use, and it's starting to show.

As such, I've instigated a new rule, "if you have to prototype, it must be in a different language to the release code", the language I've stipulated is a python for system scripts or data processing tasks, and C# to replace any windows C++ being produced.  For C# I'm still thinking, but Java might be the best option...

This realisation came to be from the back of my mind, and it came from experience, however it seems other authors have had thoughts along these lines:

"One trick to ensuring your prototype code isn't obliged to become real code is to write it in a language different from the one your game uses.  That way, you have to rewrite it before it can end up in your actual game" - Robert Nystrom.


Friday, 23 June 2017

Development : My Top Three Testing Tips

I've said before, and I'll say again, I'm not a fan of Test Driven Development, tests and test frameworks have their place, but they should not; in my opinion; be the driving force behind a projects development stream - even if it does give managers above the dev team a warm fuzzy sense of security, or if it allows blame to be appropriated later, you're a team, work as a team and use tests on a per-developer basis as a tool not as a business rule.

*cough* I do go off topic at the start of posts don't I... *heerrhum*, right... Top Three Automated Testing Tips... From my years of experience...


1. Do not test items which are tested by masses of other developers... I'm talking about when you're using a frame work of library, ensure you are using it correctly certainly, do this at training or with your coding standard, but then do not labour the point by re-testing... Lets take a good example of this, the C++ Standard Library.

The Standard Library contains many collection classes, these classes have iterators within, lets look at a vector:

#include <vector>

std::vector<int> g_SomeNumbers { 1, 3, 5, 7, 9 };

We could iterate over the collection and output it thus:

int g_Sum(0);
for (int i (0); i < g_SomeNumbers.size(); ++i)
{
    g_Sum += g_SomeNumbers[i];
}

However, this is not leveraging the STL properly, you are introducing the need to test the start poing "int i(0);" the end condition "i < g_SomeNumbers.size();" and the iterator "++i", three tests, slowing your system down and complicating your code base.

int g_Sum(0);
-- TEST SUM START
-- TEST i COUNT START
-- TEST RANGE CONDITION LIMIT
for (int i (0); i < g_SomeNumbers.size(); ++i)
{
    -- TEST ITERATION
    g_Sum += g_SomeNumbers[i];
    -- TEST SUM CALCULATION - THE ACTUAL WORK DONE
}
-- REPORT TESTS

Using the iterator, we leverage all the testing of the STL, we remove the need to range test the count variable, we remove the need to test the condition and leave only the step as a test to carry out...

int g_Sum(0);
for (auto i(g_SomeNumbers.cbegin()); i != g_SomeNumbers.cend(); ++i)
{
    g_Sum += (*i);
}

Our code looks a little more alien to oldé timé programmers however, it's far more robust and requires less tests simply because we can trust the STL implementation, if we could not thousands, hundreds of thousand of developers with billions of other lines of code would have noticed the issue, our trivial tests show nothing of gain, so long as we've written the code to a standard which uses the interface correctly...

int g_Sum(0);
-- TEST SUM START
for (auto i(g_SomeNumbers.cbegin()); i != g_SomeNumbers.cend(); ++i)
{
   -- TEST ITERATION
    g_Sum += (*i);
   -- TEST SUM CALCULATION - THE ACTUAL WORK DONE
}
-- REPORT TESTS


2. Do now allow values which have been tested to change unexpectedly... I'm of course talking about "const", which I have covered before on these pages, but constness in programming is key.  The C family of languages allow constness at the variable level, you may notice in the previous point I used a const iterator (with cbegin and cend) as I do not want the loop to change the values within the vector... Constness removes, utterly, the need to perform any tests upon the integrity of your data.

If it's constant, if the access to it is constant, you do not need to test for mutations of the values.

Your coding standard, automated scripts upon source control submissions, and peer review are your key allies in maintaining this discipline, however it's roots stretch back into the system design and anlysis stages of the project, to before code was cut, when you were discussing and layout out the development pathway, you should identify your data consider it constant, lock it down, and only write code allowing access to mutable references of it as and when necessary.

Removing the need to retest mutable calls, removing the need to log when a mutable value is called because you trust the code is key.

In languages, such as python, which do not directly offer constness, you have to build it in, one convention is to declare members of classes with underscores to intimate they are members, I still prefer my "m_" for members and "c_" for constants, therefore my post-repository submit hooks run scripts which check for assigning to, or manipulation of "c_" variables.  Very useful, but identified by the coding standard, enforced by peep review, and therefore removed from the burden of the test phase.


3. Remove foreign code from your base... I'm referring to code in another language, any scripting, any SQL for instance, anything which is not the pure language you are working within should be removed from the inline code.

This may mean a stored procedure to store the physical SQL, rather than inline queries throughout your code, it maybe the shifting of javascript functions to a separate file and their being imported within the header of an HTML page.

But it also includes the words we ourselves use, be that error messages, internationalisation, everything except code comments which is in whatever language you use (English, French etc etc) should be abstracted away and out of your code.

Your ways of working, coding standards, analysis and design have to take this into account, constness plays it's part as well, as does mutability, where ever you move this language to, and whatever form it takes test it a head of time, and then redact that test from your system level tests, trust you did it right based on the abstraction you've performed.  Then avoid burdening your system throughout the remaining development cycle.

One could expand this to say "any in-house libraries you utilise, trust their testing" just as I stated with the STL in my first point, however, I am not talking about code, I am talking about things which are not code, which are uniquely humanly interpretable.

The advantage of removing them and pre-testing the access to them is that you retain one location at which you have an interlink, one place at which a value appears, one place where they all reside and so you leverage easily converting your programs language, you leverage easily correcting a spelling mistake, and all without needing to change your system code; perhaps without needing to even re-release or re-build the software itself (depending on how you link to the lingual elements)

Ultimately reducing the amount of testing required.

Wednesday, 21 June 2017

Development : Coding Style Clash

I've spoken on these pages before, and even shown, that I generally code to a standard, one of the rules I have it NOT to use Hungarian notation, but to use a notation telling me the scope of a variable, and then give it a meaningful name.

Now, over the last few weeks I've been involved in a new piece of coding with a group of like-minded individuals.  And what getter way to explain this oxymoron than through our coding standards.

Now, I like to use "m_" for member, lots of people can accept this, I like "p_" for parameters, a lesser few reject this than you'd think and some people even quite like this as they suddenly get to reuse their useful meaningful names, and in languages like Python they suddenly get to distinguish between locals, globals and parameters really easily... But then the controvertial one, the one which causes me most angst.

Locals being represented with "l_"... You might say the lower case "L" is asking for trouble, and I would agree, but I'm sticking with "l_" locals, and so did lots of other folks, however... I said we're a group of like-minded individuals... So not a group at all.

And so locals caused a bit of a flare up, because another chap had simultaneously, and without any prompting of mine, also come to the conclusion to use this same naming convension, however with one difference... He didn't call locals locals, he called locals instances, and so he used "i_".

Yes, that was it, the whole difference... "l_" to "i_"....

I could live with this, and when coming to look at his code I could read it perfectly well, and I was more than able to leave it alone, he however, could not, and indeed would not, leave mine alone.  He went so far as to write a script which line by line, looked for "l_" and replaced it with "i_" whenever he pulled from the remote branches.

He then proceeded to commit this massive change, the result... His one liner alteration was lost in a swamp of about 35,000 changes in his check-in.  Making his contributions near impossible to track.  I asked him to keep this just to his branches, and to stick to the "l_" for the master or pushes he tagged for merging, but he simply would not listen, he changed every "l_" to "i_".

Trivial things like:

std::mutex m_TheLock;

void Somefunction()
{
    std::lock_guard<std::mutex> l_LocalLock(m_TheLock);
}

Became:

std::mutex m_TheLock;

void Somefunction()
{
    std::lock_guard<std::mutex> i_LocalLock(m_TheLock);
}

And the change logs got longer and longer, the tracking of bugs became harder and harder, until I decided to pull my support of the project, and this is important, not because it looked like a hissy-fit on my part.

But it demonstrated to me something fundamental about the project, I happily bent to others, I let them name and title things, I didn't fix their code, only stuck to my own, I published my coding standard and people started to adopt it within the group, but I never forced it upon them.  Yet this one chap wanted to import and force his will through this tiny insignificant thing.

So, always, no matter your personal feeling, stay flexible, don't be that guy who insists on something for zero gain (or in this case much loss).

[Foot note: If your project/group/team has a manager, a leader, and is not a collective as the above, please disregard this, have a coding standard, make it clear, efficient and update it regularly, but have ONE person enforce it, don't let two tribes go to war over "i_"].

Wednesday, 29 March 2017

Development : People Error 404 (Scrum)

I talked last week about my implementing three new cards for my Scrum meetings, I'm thinking about another card... a "Person 404 Error"... When I find an empty chair, post scrum, when I expect people to be working feverishly or at least planning their tasks for the day, but instead I find them drinking a coffee in a corridor, eating an apple staring at a wall, or just bemoaning they've been up since 8, I am going to assign them a 404 card.

My reason being, the developers I'm talking about, do not have a fixed start time, they can start anytime they like, so long as they're at the scrum, the scrum is 10 to 15 minutes, and then they have to get on with their task.  Coffee collecting, and apple eating, and especially bemoaning, is not allowed after the scrum for at least an hour, results, progress and some personal planning are required of them.

So, if you're a developer who wants to do the scrum then vanish... 404 you're not found... I'll be watching... And waiting.... And I'll make sure your 404 card is in your least favourite colour!...

That means Pink for you SB!... PINK!.... You have been warned.

Friday, 16 December 2016

Software Engineering : Is not Engineering

Right I'm guilty, and annoyed at myself, and making a change... Though I might still keep this as a tab on posts... I AM NOT GOING TO USE THE TERM "SOFTWARE ENGINEER" anymore....

This makes my degree certificate wrong, as it clearly states "Software Engineering", but even though that is indeed what I do every day, and what I read about every night, it is not what; nor who; I am... I am a programmer, a hacker (in the traditional sense), a tinkerer and a student of all things software.

Many other writers have call us programmers out on this, and finally, I'm going to eat humble pie and agree, when one sits down to write code one is not doing what the great engineers did, we are not forging rail-ways, bridges, hulls of great ships or physical tangible results which must stand the test of time.

We are building a more ethereal, almost smoke and mirror concept, results through the action of our instructions through another, that is programming it is what I do.

Why do I want to make this distinction?  Well, as you may tell from some of the recent posts around here, I've been involved in merging parts of teams and companies, meeting both incoming and shifting personnel to fit them into the matrix that spells "results" for a company.

No code has yet been cut, but a new team, and new ideas might very well be needed.  In turn I have reached out there and been talking to others, to recruiters, to other companies, and indeed I've sat before other people.

My friends also call upon my expertise, as one of the few from our graduating class still working in Software or indeed technology, I am often called upon for a little technical guidance.

Results have been mixed, but the determinable difference I have had between success and failure has relied, nearly exclusively, on the other party understanding the term "Software Engineer", it does not mean we can programme your VCR, set the clock on your Microwave, or save your phone contacts to your SIM card.  It means we are able to employ structured methods, to define procedure, and to design, write and test then document code as products for use or sale.

This does not include our being Electrical, Mechanical or Structural Engineers!

I am not trying, willing, or able to build the next Channel Tunnel, or Skylab, or HMS Bullshit.  I am able to cut code to make an existing system, or device, bend to the will of requirements upon it, I am able to look at the said device and decide whether it is fit for the purpose or not, I am not creating that device!

Creating said device is Mechanical or Electrical Engineering, I am Software, the use of the "Engineer" moniker is causing some confusion, some blurring of lines and so to help delimit this boundary and stop this confusion from now on I will self identify as a Programmer, and cease to try to explain all that this entails.

I am a Programmer, a Lead Programmer, a Systems Programmer, a Device Programmer, a Prototype Programmer, a Senior Programmer, a Team Leading Programmer, a Development Provisioning Programmer, no longer am I an Engineer!

Thursday, 3 November 2016

Software Engineering : Test Driven Development (TDD)

"Test-first fundamentalism is like abstinence-only sex ed:
An unrealistic, ineffective morality campaign for self-loathing and shaming."
 - David Heinemeier Hansson, 2014

I was very recently inflicted a case of TDD... I didn't like it, like the bad taste of medicine it lingered on my mind, so that I had to do some reading to even wrap my mind around the concept, and in wrapping around the idea my mind is made up to throttle it out of existence anywhere near me.

I come from the very much more formal days of development, from systems where you had very limited resources, there wasn't space to run a test suit on top of your editor next to your compiler, indeed the systems I learned to program with one had to chose to swap the editor and compiler and even a separate linker in and out of memory to achieve your build.

Taking that amount of time to do a build, it makes you learn from your mistakes quickly.  Such that I find myself now a rounded, and I'd like to think good, programmer.  I'm not the best, I've met a few of the best, but I'm good.

So combine a propensity to think about the problem and the drive to achieve a solution in code quickly, I'm used to thinking about testing after the fact, used to at least in part sticking to the old mantra of "Analyse -> Design -> Implement -> Test -> Document", with each step feeding each other.

For you see development today is not serial any more, you don't have time to stop and think, you perhaps should.  This was perhaps the only positive I see in employing TDD, and indeed it was one of the positives myself and the chap I was speaking to commonly came to, it makes you slow down and think about a problem.

However, if you're a traditional programmer, a goal orientated programmer, like myself, you've a plethora of patterns, design and experience to draw upon, which tell you your goal is achievable a certain way.

Design patterns and library implementation style, and simple rote learning of a path to a solution can drive development, peer review can share you ideas and impart new ideas on yourself, so why should you let the test; something which intrinsically feels like the end result, or the last step before accepting the solution; drive development of the solution?

I really can't think of a reason, and have now to take to the words of brighter stars than myself to express how it made me feel...

It felt like a litmus test, something being used to make me feel unprofessional, in a single trivial class, which should have taken five minutes to write and check over, an hours struggle ensued where hammer blow by hammer blow by the grace of TDD I was held up as a heretic.  "Thou dost not know TDD", the little voice in the back of my mind said, and I felt low.

But beyond how I felt, it seemed so inefficient to work in that manner, when one has programmed or engineered or done any task for long enough we build a reflect memory of how to achieve that task again, walking, reading, driving, programming... All these life goals and skills we just pick up.

Training in Karate was very much like this, one had to teach people to do things with care... 10 Print Hello 20 goto 10... Then we had to show them how to do more complex packaging and reuse of code procedure example(p_value : integer) and eventually we could let them free fight int main () { std::cout << "Hello World!" << std::endl; } and during this building up we let them drop the earlier teachings into their muscle memory, into their subconscious, we exercised, but didn't re-teach the same things, didn't cover the same ground.

Yet that coverage of the same ground is exactly where I felt TDD was taking me, and it seems to be the consensus among other "non believers" as to where it takes you, to write a test exercising your code, then to iterate over changes, sure it drives efficient code in the end, it drives out tested code before a single functional line has been written, but was it the quickest way to the same solution?

For a seasoned, experienced programmer like myself, No, No it was not, it bypassed so much of my experience as to know my self-confidence to literally brow beat me into worry.

I therefore stand and say "I do not write software test-first", and this is based on having to learn in an environment where one could not afford the processor cycles or memory to test, nor did one have bosses open to the concept of micro-design and iteratively pawing over code, one had to get the job done, and get it right or not have a role any longer.

Huib Schoots over at AgileRecord can be quoted as writing "TDD is a method of learning while writing clean, maintainable, highquality code", I would have to paraphrase that statement as "a method of learning today from scratch whilst writing modern, clean, maintainable, highquality code"  for a programmer setting out to learn their craft today is never going to have the benefit of the environment I learned in, they're not going to catch up to my twenty plus years of industry exposure and some thirty years academic experience on the topic.  They need to learn, and if teaching test proves a good starting point so be it, however, once the learning curve plateau is reached, even before, one has to question whether you need to take that next step back, step away from micromanaging the development process and evolving your code to just delivering the final product in a working form.*



Others on the topic:


http://beust.com/weblog/2014/05/11/the-pitfalls-of-test-driven-development/






* Please note, with this statement I am not advocating stagnation, and not saying that old-boys like myself are superior, however, TDD appears to me to dismiss any other way of working, to a fault and in my opinion its own ultimate flaw is itself, test your development, but don't drive your development with the test, you will seriously only be putting the cart before the horse.

Tuesday, 25 October 2016

Companies : Don't Rush & Ruin your Software!

Why do some companies do software backwards?  I'm not going to be talking about my employer, this isn't a comment about the work I do for them, it's a comment about a company which supplies us, and whom has provided subsystems for us.  Building blocks which we want to stick together into a product... A little like putting together a PC at home, you build the machine, but Intel make the CPU... I hope you're getting me so far...

The problem I have is the increasing number of vendors whom seem to see Software as either, at best, an after thought, or at worst, an evil necessity.

The software in your systems today are the glue which hold everything together, they coordinate the physical to the component level, if you make a great button to turn on a great machine that's fine; if it's mechanical; but if that button is driving a piece of software, a trigger, a service or just a PIC for heavens sake test it, think about it, write the software, try it yourself!

A great chef should never ever deliver a dish to a table before they have tasted it!  So you as a software engineer, as a provider of components, as a system integrator should taste test your own software!

The number of absolutely abysmal software packages backing up otherwise very good products is ever increasing, and it's not acceptable, either as a third party receiving such devices to re-package, integrate & push upstream, or as a consumer spending their hard earned cash on items which then go on to not work.

I review very many things, and many of them are let down by Software, and it's not acceptable; get quality Software Engineers into do your code, don't just pay the tea boy to bash up a script over a weekend!

And if you're not sure about your software offering, you think it might need work, post it clearly and neatly on github (or wherever) for the customer to take a look, don't obfuscate things, don't hide behind great massive Red Wood Tree style tall stacks of build tools.  Because as much as I like Docker & Yocto & CMake & Make & Gradle and all the others I've used right down to DOS Batch files or Bash Shell scripts, if they don't work for the customer, if they need their machine setting up a certain way, with a certain set of libraries DO NOT blame the customer when they turn around and reject your product because your documentation is utterly lacking in depth or accuracy!

Sunday, 16 October 2016

Software Engineering : RegEx in C++ 11/14 with STL

I want to show you how the STL regular expressions in C++ work.... Note, complete source code & makefile at the bottom.

First we'll need a make file, I'm using Ubuntu Linux with GNU G++ v5.4.0, opening a terminal I get a text editor up and we create this makefile:

CC=g++
STD=c++14
WARNINGS=-Wall -Wfatal-errors
FLAGS=-pedantic
OUTPUT=application
FILES=main.cpp

all:
$(CC) -std=$(STD) $(WARNINGS) $(FLAGS) $(FILES) -o $(OUTPUT)
clean:
rm $(OUTPUT)
And I save that as "makefile"... Next we need a simple "main.cpp" file to test this with, so go a head and write:

#include <iostream>
#include <string>

int main ()
{
std::cout << "Hello World" << std::endl;
}

Save that and we can be in the folder and simply type "make".  Everything should complete cleanly, and you can then type "./application" to run the resulting "Hello World" application.

Now lets go back into the main.cpp, and we'll write a function... I'm not going to show you this as proper C++, I am not going to teach you about classes, so just go with me, we'll write this function above the "int main()" we just created, and then we'll define a function to split a string into words whenever it finds a space....

#include <regex>

std::vector<std::string> SplitString (const std::string& p_Source)
{
std::vector<std::string> l_result;
// The actual regular expression
std::regex l_regularExpression ("(\\S+)");
// Process the whole source string through the filter
auto l_regularExpressionResult = std::sregex_iterator(
p_Source.begin(),
p_Source.end(),
l_regularExpression);
// Use the result iterator to get all the individual strings
// into the result vector of strings
for (auto i = l_regularExpressionResult;
i != std::sregex_iterator();
++i)
{
auto l_item = (*i);
std::string l_TheString = l_item.str();
l_result.push_back(l_TheString);
}
// Return the result
return l_result;
}

Lets just take a look at this working, into your main and do this:

int main ()
{
const std::string l_SourceString ("Mary Had a Little Lamb");
std::vector<std::string> l_words = SplitString(l_SourceString);
for (auto i = l_words.cbegin();
i != l_words.cend();
++i)
{
std::cout << (*i) << std::endl;
}
}

We can save, exit and build the program again, running it we see this:

Mary
Had
a
Little
Lamb

So what did our new "SplitString" function do?  Well, lets first of all hope you're comfortable, with STL iterators, because we use one to go through the source string and then another to go through the expression result.

Our important lines of code are, std::regex l_regularExpression ("(\\S+)");  where we define the regular expression string, no I'm not going to teach you all the ins and outs of creating those strings, this expression however just gets individual strings.

The next important line is: auto l_regularExpressionResult = std::sregex_iterator(  where we are going to use the sregex_iterator constructor to actually apply the filter we created on the previous line, and we apply it to the span of the whole source string "begin()" to "end()" on the std::string::iterator there.

We could try to use the std::string::const_iterator too, by simply substituting with "cbegin()" and "cend()".

The final parameter is passing the actual filtering regular expression into place.

The result, and we don't need to worry about the type as we're leveraging auto there, is a copy of the iterator.  Depending on the STL implementation you have will define when the processing takes place, some versions will process as you iterate over the sregex_iterator, making you process the input on the fly, whilst others pre-process everything, holding off your code moving to the next line of code (when you step through) until the complete source has been processed through the regular expression.  This can be a performance trap for some, as they either think it will process, when it does not, or it does not until you iterate, and confusion ensues.  Especially when you are writing cross platform code and the platforms express different behaviours.

The last important piece of code is actually going through the result to see if there is anything in the resulting iterator.

The awkward piece of using auto shows up here, because on some platforms when you try to iterate through the result and get each string you might want to do "(*i).str()" rather than assigning the dereference (*i) to an auto first.  However, some compilers (especially when using -pedantic, GCC on this one) don't like this, so to make the code more maintainable and pre-empt it being on any platform where the dereference of the iterator is reported to "not contain a definition for "str()", I simply assign the dereference to an auto called "l_item" and then use "l_item.str()"... That's a lesson in maintainable code right there folks.

That is a very basic introduction to regular expressions, you can see why I have gone through this below.

Right now through, lets use a more complex regualr expresion, and avoid the complexity of the interator stuff, lets just validate a string as a UK Postcode:

const bool ValidatePostcode (const std::string& p_UKPostcode)
{
std::regex l_Validate ("^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$");

return std::regex_match(p_UKPostcode.c_str(), l_Validate);
}

This might look a little cramped, but I never wanted to make a mistake with the reg-ex.  This isn't a perfect solution btw, I'm still writing a test routine to check it against a full list of UK postcodes online, I think it will let some stranger codes through as valid, but they are edge cases, this will work for 99.5% of addresses, and 100% of those I've tested so far.

There you go, good luck!


=== WHY DOES THIS EXISTS ===
Today I've been using regular expressions in C++, some might consider this dark magic, however, I assure you it is all above board, the problem was the validation of a UK postcode, there was a quite terrible function:

bool Validate(char *Code);

Defined, which had all manner of hackery and trouble within, not least it could not handle some London Postcodes, we'll come back to postcodes later, however I replaced all the functionality of this code with two lines of code... Literally two, it went from around 500 lines of un-maintainable junk, to the two lines of active code to manage which you see above, I in fact could have placed the regular expression string into our master list of "strings" to yet further minimise where constants are defined, but I left that to him, left him a small victory to coerce acceptance of my drastically demonstrating his not thinking about the code changes needed, and spending all week on something which took me two lines and about 10 minutes to make sure the regex was right!

Handing it back to the owner, after my peer review, I think they wanted to cry, instead they rushed off to our common Director, avoiding all code managerial level input from fellow programmers, and said I had "shown them up by using a third party library".

I had used STL, something we use elsewhere, I had also followed the coding standards which exist, so the function had become:

const bool ValidatePostcode(const std::string& p_UKPostcode) const;

This, I think you must agree, is more informative as to what it does, it tells us we can't edit the values, we're still passing everything by reference but we're not changing the type of our system string handing from "std::string" to "char*" and we also define that the function changes nothing in the class it is within with a trailing const.

All these rules are in the coding standard, folks before you go around a peer to complain; a more senior peer at that; please check you are in fact on the right track.

So, having validated my changing the function prototype, I had to explain why I had used a third party library (as all such libraries need formal evaluation)... "Regular Expressions are in the standard library".... Was my simply reply... "Only in the latest technical release!"... Was the mouth frothing reply from the hurt chap.  "No, they've in C++11, we use STL all over the code, it is formally evaluated and signed off by everyone, including yourself".

The guy looked extremely crest fallen, and whatever his motivations for having a go at myself, I realised he just didn't know, he'd not read the books I had, he's not used the code as I have, and he'd simply always used regular expressions from third party sources, and that's fine, but please folks just check  your coding standard and have at least a look on google, before you go shouting to those above in an unprofessional manner.


---- THE COMPLETE SOURCE (main.cpp) ----

#include <iostream>
#include <string>
#include <regex>

std::vector<std::string> SplitString (const std::string& p_Source)
{
std::vector<std::string> l_result;
// The actual regular expression
std::regex l_regularExpression ("(\\S+)");
// Process the whole source string through the filter
auto l_regularExpressionResult = std::sregex_iterator(
p_Source.begin(),
p_Source.end(),
l_regularExpression);
// Use the result iterator to get all the individual strings
// into the result vector of strings
for (auto i = l_regularExpressionResult;
i != std::sregex_iterator();
++i)
{
auto l_item = (*i);
std::string l_TheString = l_item.str();
l_result.push_back(l_TheString);
}
// Return the result
return l_result;
}

const bool ValidatePostcode (const std::string& p_UKPostcode)
{
std::regex l_Validate ("^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$");

return std::regex_match(p_UKPostcode.c_str(), l_Validate);
}

int main ()
{
const std::string l_SourceString ("Mary Had a Little Lamb");
std::vector<std::string> l_words = SplitString(l_SourceString);
for (auto i = l_words.cbegin();
i != l_words.cend();
++i)
{
std::cout << (*i) << std::endl;
}

// Postcodes
std::cout << "--- Postcodes ---" << std::endl;
std::cout << ValidatePostcode("NG16 5BP") << std::endl;
std::cout << ValidatePostcode("NG10 1NQ") << std::endl;
std::cout << ValidatePostcode("Robert") << std::endl;
std::cout << ValidatePostcode("FP52 JTY") << std::endl;
}

---- makefile ----

CC=g++
STD=c++14
WARNINGS=-Wall -Wfatal-errors
FLAGS=-pedantic
OUTPUT=application
FILES=main.cpp

all:
$(CC) -std=$(STD) $(WARNINGS) $(FLAGS) $(FILES) -o $(OUTPUT)
clean:
rm $(OUTPUT)


P.S. Yes this will all work with "STD=c++11" in the make file!