Friday 10 May 2013

3rd sigh of relief

The last few months have been draining to say the least. Today I did a presentation that marks the last if the work I have to do this academic year. I'm reasonably confident that I've passed all my modules with good marks. With any luck I'll be coming away with a first.

This year has been hard work. My award was planned in a way such that I took all the hard modules in semester one and their perquisites in two. It was a pretty steep of a learning curve. But while the modules I had this semester were definitely easier than those of the previous, it seems they were almost twice as time consuming, certainly toward the end.

I've come away this year with a good understanding of software engineering and OO principals. I'm actually starting to feel like a competent programmer, or at least that I could be someday. I've written two graphics engines, a physics engine, a game engine, an ant farm simulation, a concurrent run-way control system simulation, a banking system and project managed an FPS prototype, and I've produced all the reports and subsequent paperwork that goes with. Now that I'm totalling it all up its no wonder that I've been having such a hard time finding time for any other activities, like iOS apps. Between family life, school work and trying to find a placement I've just not had enough time to do much of anything else.

I'm quite proud if myself this year for managing to stay on top of the workload throughout. Doing so means I've spent hundreds of hours hidden away in some corner of the university trying to get through it all. At one point I got RSI so badly in one hand that I could hardly bare to move it, and it came at a hideously inconvenient time though so I had to just grit my teeth a bare it for a couple days until I could give it some proper rehabilitation. When the teachers asked me how I was getting in I proudly and smugly replied, "I'm doing just fine, everything is right on schedule."

Despite my successful self management, I'm glad the year is over.

Unlike my fellow students I've not been much looking forward to the summer break. Summer for me had come to mean a time of boredom. Each year I've become better at managing my time with little projects but without the pressure of academic evaluation it's somehow a little hollow. If I don't get the work done, then I simply don't get it done, there's no real pressure. I setting the bar higher this summer with much more ambitious projects so I guess we'll just have to see how it goes. It will be nice to get back to the more creative elements of software development. I am going to take a few days off though, I think I've earned it.

As this year comes to a close, I'm feeling hopeful for the future. I can see the end in sight and while I don't want to ever leave university I am looking forward to reaping the rewards of all this work. It's been difficult and frustrating and great.

What did I learn this year?
Don't get rid of your work, any work. I handed in an assignment in which I'd removed several functions. These were functions that I've written up for testing or some other purpose and didn't really belong in the final artefact. But I came to find out that they would have got me some extra marks.

If you have a some sort of special help you can get for an exam, in my case it was the use of a computer, use it. I had the use of a computer for my last exam because there was a lot of writing involved and I can type much faster and coherently than I can write by hand. Being able to use a computer means the not only did I finish the exam quite early and thus give myself plenty of time to review my answers, but my answers were legible and well written.

Find a way to keep on top of your work load. It just made everything so much easier and less stressful. When things went wrong I had plenty of time to fix them and when I discovered that I'd missed out and entire element of an assignment, I had plenty of time to handle it. Sure I was busy, but I turned in good, quality work that I can be proud of.

Beware RSI, take preventative measures wherever possible.

If you have glasses for close up work, wear them. You'll find your eyes stop hurting.

Conclusion

 I'm looking forward to a bit if a rest.

Monday 15 April 2013

Coding left handed

I'm a long time sufferer of RSI. From the age of nine I've spent my life playing video games, riding a bike, playing a guitar or working at a computer. The numbness and tingling started to appear around the age of 17 and has gradually become easier and easier to trigger. I consider myself lucky that I've got full use of both hands at the age of thirty, but I've always known that full blown carpel tunnel syndrome is probably in my future.

That's not to say that I don't try to keep it at bay. I do little stretches, exercises, take lots of breaks and ease up when symptoms appear. I have a powerball that I use as my primary method of rehabilitation, I find it's by far the most effective treatment for RSI. I practice good typing and playing techniques and try to favour ergonomics where I can but my hands are degrading slowly.

Thursday I woke with a pain in my right hand. It couldn't have come at a worse time, it's the final week of the semester, I've got a lot of work to finish and exams coming up. I need to be able to type at full speed for the next few weeks. I have regular spells of RSI but its never been anywhere near this bad.

By Friday night the pain was crippling. I was struggling to hold my fork at dinner time. I can't lift, grip, type or really do anything with that hand, it's very frustrating. Saturday morning the pain had eased enough for me to be able to have quick session with my powerball. It helped immensely but normally the powerball takes a few days to restore my hands from mild RSI, I suspect that this time it may take quite a bit longer. One of the biggest problems with the condition is that if I just take pain killers and power through with the rest of my work then the damage accelerates.

So for the foreseeable future I've not much choice but to rest the right hand and favour the left thankfully I've got an abundance of dictation options. I trust that writing and coding left handed wont affect the quality too much.
Lets just hope my left hand doesn't shut down as well.

For more information on RSI you can start here. http://www.rsi.org.uk/

Monday 18 March 2013

Placement

This year I have the option to do up to one year in work placement. My award is a little strange in that the placement for me is optional. If I can't find one I just transfer to the award that doesn't require a placement and that's that.

I initially jumped onto the placement bandwagon with enthusiasm. I'm getting such good feedback from the University that I figured I'd surely be able to find a good placement pretty early on. As time goes on however, I'm not finding this is at all the case.

The biggest problem it seems is me, or more specifically, my living situation. I can't just up sticks and move like most students can, I've got a house and childcare issues. All the best placements for software development seem to be in Reading, Leamington Spa or London, that's simply to far for me to commute. So I'm limited to the west midlands where the pickings, software wise, are pretty slim.

I polished up my CV and applied to everyone who was looking for something even remotely software orientated. Out of something like 20 applications I've only had a couple of interviews. Neither of them came to anything. One gave me no feedback at all and the other one told me to come back in a couple of months and then filled the position that I was supposed to come back for.

It's like being back on the job hunt, only weirder. Where as before, if I wasn't completely ignored by employers I was at least treated like a professional. It was assumed that I had the skills appropriate for the job and was occasionally asked to elaborate.
Going for a placement is all together more soul destroying. You still stand just as much chance at being ignored but now the interviewers treat you like, well... a student. I've been given full blown exams and hour long sessions of critically assessed programming. It's stressful to say the least.

In their defence I've now had the pleasure of working with a variety of students for a couple of years and have, in that time, managed two group projects. If I was in there shoes I'd be testing candidates as well.

This week I had an interview for a role that I would be perfect for. All of my interests and experience are right on the money and the company is next door to the university. When interview day came I was quite nervous about what potential challenges awaited me, so much that I'd spend the days before pouring over all my past work trying to think of everything that I might be asked about or tested on. I even brushed up in my objective c, c# and c++ just to be safe.

As interviews go however this was about the most normal interview I've had since starting my degree. I was a relaxed and respectful and professional conversation. It was all very much, "This is what we do, this is what we want." "This is what I've done, this what why I'm the man for the job." a very familiar format and welcome relief from what I've come to expect from placement hunting.

I used to have a real knack for interviews. My trouble has always been getting my CV through to interview stage, without a degree it's nearly impossible. There was a time when I could proudly state that if I got through to interview, then the job was mine. I seem to have lost that skill somewhere along the way. Maybe it's just that I'm up against a higher calibre of competition now, I dunno.

I'm waiting to hear back from that interview them and I'm hopeful. Aside my compulsively pointing out every little bug or imperfection in my apps as I talked about them, I didn't say anything that would have outright blown the interview. I was relaxed, professional and well prepared the whole way through. It's nice to come away from the interview feeling good about it for a change. I've got another interview on the horizon as well so I'm not readying my award transfer papers just yet.

Monday 11 March 2013

Not Smart Enough for the Room

I recently attended a group meet. The group is a pack of programmers from around the county that meet up every month and discuss issues and industry and so on. Each meet they decide on a small project together and work through it. This project can be anything from Programming Kata ideas to a full blown development project.

This appealed to me right from the start. It's a chance to associate with people in the industry, do a little networking and maybe learn a little something. The meet isn't that far from me a few of my lecturers attend and have been encouraging me to, so I decided to go.

I can honestly say that I've never felt so intellectually inferior in my life. Some of these guys are the people that the people I look up to, look up to. Every time I spoke up I regretted it almost instantly. My input was lagging and often needless, responded to with blank stares and patient slowly spoken sentences. I'm pretty sure that everyone in the room actually started dumbing down the language toward the end.

One of the highlights of the evening was when a team member from a company that had recently declined me for a placement came in. This team member then proceeded to talk about the poor quality of programmers they have had applying this year, my interview was even brought up as one such example.

By the end of the night I was drained and depressed. I felt like such an ameteur and well, like an idiot. Unworthy of referring to myself as a member of their industry.

I'm going to keep attending. I'm aware that I'm naturally very paranoid and have never been very good with those types of situations. I'd like to think that soon I'll do better and that's not going to happen if I run away screaming due to my own insecurities. I am just a student after all and all of these guys are seasoned veterans. They all seemed like genuine, nice, very smart people and I think in the long run it will be good for me on a number of levels. In fact, I learned a lot while I was there. I'm a big believer that if you truly want to get better at anything, spending as much time as possible with the masters is the best way. Coming away from the meeting feeling 2 inches tall is just an indication that I've still got a lot to learn. I'm going to be coming home from the meets with a lot of homework for quite a while.

Tuesday 5 March 2013

Assignment Technique

I have a habit of diving head first into assignments trying to amaze and astound people by implementing very advanced techniques or the like into my work.

I've had several lengthy discussions with many of my lecturers about my attitude toward my work. Nearly all of them keep telling me to, for lack of a better phrase, take it a little less seriously. Generally they tell me to go for easy marks first, then go for the harder stuff. I generally dislike this approach to education as I don't feel it really encourages students to push themselves. It's hard to really push yourself when you already know that you're going to pass. Also, bare pass marks are usually at a very low standard. I want top marks, all the time in everything.

This semester I'm amalgamating all the advice that I've had from my lectures and combining them with my usual approach. So far its serving me well.

For example, I have an assignment for concurrency. I've attempted this assignment several times and keep coming up against the exact same problem. Basically I have a resource shortage and I just can't solve it. I'm reluctant to ask my tutor for any more assistance that he's already provided me. It's a huge class and I'm so far ahead of everyone else that it's not really fair to be taking so much time from those who might be struggling.

I pushed onward and found come up with an implementation that solves the problem except for a very minor, but obvious, cosmetic problem. I've spent weeks on this assignment and it's really starting to get to me.

So I'm taking a break, sort of. The assignment is done bar this single problem and I've got a lot of other, more difficult work to attend to. So rather than spending the next 4 weeks pulling out my hair trying to figure out I've applied my new approach, all be it, in reverse. I took a look at the marking scheme and have implemented each of the, extra marks, items. These are things like pretty graphics and other things that are might be slightly beyond the scope of the module. So counting up the marks I'm easily into the high 90% despite this little problem. The extra marks gained will more than make up for the marks lost. Now, if I don't manage to get back to this assignment before the hand I'll still be looking at an A. My assignment may not be perfect but I'm still getting top marks.

I realize that this might be considered contrary to things I've said in the past. But those were intended to be general student advice. This is specific to me.

Monday 25 February 2013

Scraping a Pass

I received the results from one of my modules from last semester. I've already had my results from two other modules and I was looking at a possible first if everything else went well, realistically though I was probably looking to get a solid 2:1.

Then I got this grade back. Wow, it really ruined my day, I did a little better than expected on the assignment but bombed the test. Thankfully my assignment marks put me over the pass mark but just barely. I'm not happy at all with this grade.

Part of me wants to rage at the system. This was a level 6 module and a hard one at that. I'm currently taking the level 5 module that's supposed to build up to this one. This is the result of years of scheduling and re-scheduling the modules until this was the only fit, it's a major fault of the school, and one that they're rectifying next year, but I can't really blame the school. These things happen with teachers and awards coming and going over the years. However having taken these modules out of order I feel has undermined me, and everyone else on the award. I spent a lot of time trying to figure out the basics of the subject while being taught about the much, much more advanced applications and techniques. It was very frustrating.

All in all though I had plenty of help. I plagued my tutors during this module and I was just happy to have a working application to submit for my assignment in the end.

My study technique failed me tremendously for the exam. The module covered a lot of very complicated subjects over a a fairly short period of time. I didn't understand a lot of the basic stuff so I focused on those for my general study and then looked to the past exam papers for my more focused revision. I revised for two days solid and was fairly confident when I sat down to take the exam. However, the tutors went for a complete re-write on the exam this year and virtually nothing that had been on any of the past papers appeared on this exam. So I basically sat the exam almost completely unprepared.

Worst case scenario this bumps my degree down to a third class, which is horrifying. If I get solid firsts this semester I can maybe scrape a 2:1 which would be fine. So far I'm doing extremely well in two modules and not as well in the other two so I'll just have to wait and see how it goes but I'm optimistic but this is going to be hanging over my head for for the next two months, especially come exam time.

Monday 18 February 2013

Kata 3 - Magic Numbers

This kata comes from the website of one of my old lecturers. It was an interesting problems to tackle and there are a lot of different ways to approach it.

159 * 48 = 7632 contains each of the numbers 1-9. The program finds and displays all the other simple multiplications that also contain each of the numbers 1-9.

I started by creating an algorithm that generated a string containing all the numbers I wanted. This was exceptionally tricky to do. So my algorithm just starts counting from 123456789. Each number is checked that it contains only one of each number. Because I'm using only 9 digit numbers there isn't any need to validate any further than that. If the number is valid it's passed through to another checker that systematically changes the number into a simple multiplication equation. If the equation is valid I win.

The application takes a ridiculously long time to run. After completion I thought of a way to potentially half the run time but I didn't implement it because I've been obsessing about this for far too long.

This was done largely using TDD but I actually wrote the test in Obj C and then transferred the program to C# because of a memory problem I was having in XCode.


 static void Main(string[] args)  
     {  
       string equationString;  
       List<string> createdStrings = new List<string>();  
       //create an array of strings ///159 * 48 = 7632  
       for (int i = 123456789; i <= 987654321; i++){  
         equationString = i.ToString();  
         //validate strings with the checker  
         if (equationCharacterChecker(equationString)){  
           if (equationChecker(equationString)){  
             createdStrings.Add(equationString);  
           }  
         }  
       }  
     }  
     public static bool equationCharacterChecker(string equation) {  
       SortedSet<string> setOfEquationCharacters = new SortedSet<string>();  
       setOfEquationCharacters.Add("1"); setOfEquationCharacters.Add("2"); setOfEquationCharacters.Add("3");  
       setOfEquationCharacters.Add("4"); setOfEquationCharacters.Add("5"); setOfEquationCharacters.Add("6");  
       setOfEquationCharacters.Add("7"); setOfEquationCharacters.Add("8"); setOfEquationCharacters.Add("9");  
       string character;  
       for (int i = 0; i < equation.Count(); i++)  
       {  
         character = equation[i].ToString();  
         if (setOfEquationCharacters.Contains(character)){  
           setOfEquationCharacters.Remove(character);  
         } else {  
           return false;  
         }  
       }  
       return true;  
     }  
     //159 * 48 = 7632  
     public static bool equationChecker(string equation) {  
       int length = equation.Length;  
       for (int m = 1; m < equation.Length-2; m++){  
         for (int e = m+1; e < equation.Length-1; e++){  
           int multiplicand = Convert.ToInt32(equation.Substring(0, m));  
           int multiplier = Convert.ToInt32(equation.Substring(m, e-m));  
           int product = Convert.ToInt32(equation.Substring(e));  
           if (multiplicand * multiplier == product) {  
             Console.Write(multiplicand + " * " + multiplier + " = " + product + "\n");  
             return true;  
           }  
         }  
       }  
       return false;  
     }  

Monday 11 February 2013

Kata2 Binary Search

I did my second Kata this morning. I thought I'd tackle the binary search problem in following with http://codekata.pragprog.com
The idea here is that you have some huge, but sorted, list and you need to find a single element within that list as efficiently as possible. As lists grow in size just traversing through the list element by element can take a really long time for higher numbers.

The binary search solution basically means you start in the middle continually divide the list in half until you find your element. For huge lists it's excellent because it doesn't matter where the desired element is in the list, it will always find it quickly, one drawback though it will more often than not, take several searches to locate the element. So you need to weigh the efficiency lost against the efficiency gained. 

I'm quite proud of my attempt. I've tested it with a list of 50,000,000 integers and it never takes more than 26 searches to find any element. It'll support an array of any size and it should support any data type, but I'll need to test that at a later time. This is a recursive approach as it was the approach that comes most naturally to me. I'm going to have a look at an iterative at a later time.

This was developed using TDD, kind of. I had to test this from a few different directions at once, namely efficiency and accuracy. I couldn't work out a good way of testing for them both at the same time so I'm leaving what test code I did end up with out of this post.

 -(NSNumber*)binarySearch:(NSArray*)array forInt:(NSNumber*)anInt {  
   int numberOfSearches = 1;  
   int min = 0;  
   int max = array.count;  
   int searchingFor = [anInt integerValue];  
   int indexOfGuess = [array indexOfObject:[array objectAtIndex:(max + min) / 2]];  
   int guess = [[array objectAtIndex:indexOfGuess] integerValue];  
   NSLog(@"%d searches", numberOfSearches);  
   while (searchingFor != guess){  
     if (max - min <= 2){  
       return [NSNumber numberWithInt:-1];  
     }  
     if (searchingFor < guess){  
       max = indexOfGuess;  
     }  
     if (searchingFor > guess){  
       min = indexOfGuess;  
     }  
     guess = [[array objectAtIndex:(max + min) / 2] integerValue];  
     indexOfGuess = [array indexOfObject:[array objectAtIndex:(max + min) / 2]];  
     numberOfSearches++;  
     NSLog(@"%d searches", numberOfSearches);  
   }  
   return [NSNumber numberWithInt:indexOfGuess];  
 }  

Monday 4 February 2013

Bruising the Ego

I've learned quite about managing your ego when it comes to development. Every programmer has an ego, don't listen to what they might tell you otherwise. We all consider ourselves the poets of the computing world, thinking up beautifully elegant solutions to impossible problems.

I have a huge ego, I freely admit this. I don't handle criticism well and I'm a sore loser. I constantly aim to blow peoples minds with my genius and when that doesn't happen I fall into pits of self loathing and depression. It's a constant struggle for me.

Two of my apps have received bad reviews recently. I've got another app that I'd written for a client that seems to have given up on me all together, bought my app and immediately reporting a bug and requesting all sorts of changes. I fixed the bug right away and then spent a month re-writing the app. Now they won't respond to my emails, nor have they updated the app. My natural pessimism tells me that they've written me off all together, but I just don't know.

Being that two people have chosen to be vocal about their dislike of my apps, demographically I know that there are a percentage of others out there that feel the same way and have just chosen not to speak up. I spent a lot of time and energy on those apps and I'm very proud of them and their success so far. These were my ideas, my creations, my products and I want everyone to love them.

Now in my defence neither of these two users appear to have read the description of the apps before purchasing, which is their mistake. And the things they're complaining about are actually restrictions put in place by Apple, nothing to do with me. But these are still my app reviews. There is also information within the apps and on the app store that would allow a displeased customer to get in touch with me of there's a problem. But they haven't tried to reach me. I take some solace in knowing, from experience, that there are customers out there that just want to complain about anything that they can. You can't please everyone right, so why don't all those that like my apps post good reviews and make me feel better about it. I'm sat here looking at dissatisfied customers and poor reviews and I'm powerless to do anything about it.

I suppose that I could look at it as there's being an opposing percentage of those that are very happy with my app. There is one good review as well, so that's something.

Monday 28 January 2013

Being The Boss.

21-01-13

I've got a module this semester where in, we're to work as small games companies. It's straight forward enough, the class of 30ish students has been split into two teams of ten and we're using the Cry engine and Scrum to create one prototype game each. The game has to be a FPS zombie killing game, multiplayer optional.

Now, in that we're supposed be working as a games company we were all to be given roles based on skills and personal preference. These roles were to be given out by the company producer, an elected executive type role, basically the producer is the guy in charge. This role has real power in the module, they manage the team, make all the final decisions about the game and if necessary, discipline team members. The producer can actually have members of his team kicked off the module if it's deemed necessary.

I'd put my name in for producer. Thinking that, if I got it, it would be good experience relating to my plans after graduation, I also thought it would be nice if I was actually put in charge of a project by my peers instead of just assuming the role.

The campaign was short, we stood in front of the class and presented our fitness for candidacy for 2 minutes each. I'm not well known at the university and I don't even think I'm well liked, I have a habit of winding up total strangers and openly mocking design students, many of whom were on that module. I screwed up my 'speech' delivery pretty royally and made myself look a real idiot. But when the votes came in I (having snuck a peek at the count) was on top... oh... goodie.

So now, here I am leading one of three teams in making a game from the ground up. We're using a commercial grade engine so it's not nearly as much work as it sounds, but there's still an awful lot to do, especially for me. I've got 10 other students relying on me to get a good grade in this module, I've got to manage their time, their tasks and the quality of their work. I've got to organise and lead regular meetings, orchestrate documentation and be held accountable for any and all the problems. I've also got to track it all and report on it. I have a lead artist, designer, tools developer, scripter and 6 team members assigned to various areas. In all I have 2 game designers and 8+ programmers, I'm still waiting for a couple a stragglers to be assigned to my team. All looking to me for decisive guidance and support...

What have I gotten myself in to?

Monday 21 January 2013

My First TDD Kata - Objective C - Xcode 4.5 - OCUnit - ARC

Ok, so I've taken the entire day to work on a programming Kata using TDD.

I started with the same exercise that I was given during an interview for an industrial placement a few weeks ago http://codekata.pragprog.com/2007/01/code_kata_one_s.html just so that I had an idea of where to start.

This code has taken me all day but for good reason.
Firstly I've never used TDD before, nor do I have any idea of how to use OCUnit. I have quite limited experience in programming generally so this was all a bit of a learning curve for me.
Secondly, this paradigm is basically the opposite of the way in which I've learned to program. I find it very, very difficult to think this way.

I'm actually quite pleased with the result. As applications go it's functional, seems robust and the design isn't far off from what I would have designed otherwise. It will be interesting to come back to this Kata later and see what differences there are.

What did I learn?

TDD is a concept, I could hear the criticisms screaming out at me as I did it but once I got going it actually started to come really naturally.

Two problems.
From time to time a tricky change comes up. For example in my application I made the decision to change from scanning in Strings to scanning in item objects. Looking back now I can see how I maybe could have handled this differently and maybe made things a little bit easier on myself. But still there was a lot of time spend pondering this, while outside of TDD the change would have been a no-brainer, just change an argument here and a return type there an done. TDD meant that I wound up writing a whole new function for it to save failing the older tests. I'm hoping that some more practice in TDD will help me to handle this type of situation in the future.

There was a real sense of fragility when programming. When implementing the BOGOF feature I found myself tip-toeing around the code trying to change as little as possible as not to fail my older tests, again I hope that experience will take care of this but I'm not so sure.

The design comes from the refactoring stage really. Refactoring seems to be the time to do a little bit of 'Crystal Balling' a little bit and try to introduce some good code and design practices.

Oh and if you're wondering about the weird way I've worked with NSNumber, well I can't really explain myself, I just had a really hard time with it and the primitives. I may do my next kata in a different language.

My Code.
Tests

 -(void)testCheckOut {  
   NSNumber *expected = [NSNumber numberWithDouble:0.0];  
   NSNumber *result = [scanner checkOut];  
   STAssertEquals([expected doubleValue], [result doubleValue], @"Expected %g, but returned %g", [expected doubleValue], [result doubleValue]);  
 }  
 -(void)testScanItem {  
   NSNumber *expected = [NSNumber numberWithDouble:0.60];  
   [scanner scanItem:(@"apple")];  
   NSNumber *result = [scanner checkOut];  
   STAssertEquals([expected doubleValue], [result doubleValue], @"Expected %g, but returned %g", [expected doubleValue], [result doubleValue]);  
 }  
 -(void)testScanningTwoItems {  
   NSNumber *expected = [NSNumber numberWithDouble:1.20];  
   [scanner scanItem:(@"apple")];  
   [scanner scanItem:(@"apple")];  
   NSNumber *result = [scanner checkOut];  
   STAssertEquals([expected doubleValue], [result doubleValue], @"Expected %g, but returned %g", [expected doubleValue], [result doubleValue]);  
 }  
 -(void)testScanningAnItemWithADifferentPrice{  
   double expected = 0.7;  
   [scanner scanItem:@"banana"];  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  
 -(void)testScanningTwoItemsWithDifferentPrices {  
   double expected = 0.7+0.6;  
   [scanner scanItem:@"apple"];  
   [scanner scanItem:@"banana"];  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  
 -(void)testScanningMultipleItemsObjectsOfVaryingPrice {  
   Item* apple = [[Item alloc] initWithDescription:@"apple" andPrice:[NSNumber numberWithDouble:0.6]];  
   Item* banana = [[Item alloc] initWithDescription:@"banana" andPrice:[NSNumber numberWithDouble:0.7]];  
   Item* orange = [[Item alloc] initWithDescription:@"orange" andPrice:[NSNumber numberWithDouble:0.5]];  
   double expected = 0.0;  
   [scanner scanItem:apple.description];  
   expected += [apple.price doubleValue];  
   [scanner scanItem:banana.description];  
   expected += [banana.price doubleValue];  
   [scanner scanItem:orange.description];  
   expected += [orange.price doubleValue];  
   [scanner scanItem:apple.description];  
   expected += [apple.price doubleValue];  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  
 -(void)testScanningItemAsObject {  
   Item* apple = [[Item alloc] initWithDescription:@"apple" andPrice:[NSNumber numberWithDouble:0.6]];  
   double expected = 0.6;  
   [scanner scanObject:apple];  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  
 -(void)testScanningMultipleObjects {  
   Item* apple = [[Item alloc] initWithDescription:@"apple" andPrice:[NSNumber numberWithDouble:0.6]];  
   Item* banana = [[Item alloc] initWithDescription:@"banana" andPrice:[NSNumber numberWithDouble:0.7]];  
   double expected = apple.price.doubleValue + banana.price.doubleValue;  
   [scanner scanObject:apple];  
   [scanner scanObject:banana];  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  
 -(void)testBOGOFWithTwoOfTheSameItem {  
   Item* apple = [[Item alloc] initWithDescription:@"apple" andPrice:[NSNumber numberWithDouble:0.6]];  
   double expected = apple.price.doubleValue;  
   [scanner scanObject:apple];  
   [scanner scanObject:apple];  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  
 -(void)testBOGOFWithMultipleVaryingItems {  
   Item* apple = [[Item alloc] initWithDescription:@"apple" andPrice:[NSNumber numberWithDouble:0.6]];  
   Item* banana = [[Item alloc] initWithDescription:@"banana" andPrice:[NSNumber numberWithDouble:0.7]];  
   double expected = 0.0;  
   [scanner scanObject:apple];  
   expected += apple.price.doubleValue;  
   [scanner scanObject:apple];  
   [scanner scanObject:banana];  
   expected += banana.price.doubleValue;  
   [scanner scanObject:banana];  
   [scanner scanObject:banana];  
   expected += banana.price.doubleValue;  
   double result = [[scanner checkOut] doubleValue];  
   STAssertEquals(expected, result, @"Expected %g, but returned %g", expected, result);  
 }  

Application

 -(PriceScanner*)init {  
   self.total = [NSNumber numberWithDouble:0.0];  
   self.list = [[NSMutableArray alloc] init];  
   return self;  
 }  
 -(void)scanObject:(Item*)item {  
   [self.list addObject:item];  
 }  
 -(void)scanItem:(NSString*)item {  
   if ([item isEqualToString:@"apple"]){  
     self.total = [NSNumber numberWithDouble:[self.total doubleValue] + 0.6];  
   }  
   if ([item isEqualToString:@"banana"]){  
     self.total = [NSNumber numberWithDouble:[self.total doubleValue] + 0.7];  
   }  
   if ([item isEqualToString:@"orange"]){  
     self.total = [NSNumber numberWithDouble:[self.total doubleValue] + 0.5];  
   }  
 }  
 -(void)applyBOGOF{  
   double newTotal = [self.total doubleValue];  
   NSMutableSet *tempSet = [[NSMutableSet alloc] init];  
   for (Item* i in self.list){  
     if ([tempSet containsObject:i.description]){  
       newTotal -= [i.price doubleValue];  
       [tempSet removeObject:i.description];  
     } else {  
       [tempSet addObject:i.description];  
     }  
   }  
   self.total = [NSNumber numberWithDouble:newTotal];  
 }  
 -(NSNumber*)checkOut {  
   double newTotal = [self.total doubleValue];  
   for (Item* i in self.list){  
     newTotal += i.price.doubleValue;  
   }  
   self.total = [NSNumber numberWithDouble:newTotal];  
   [self applyBOGOF];  
   return self.total;  
 }  

Wednesday 16 January 2013

On Studying

I've been asked a number of times recently on studying. How do you go about studying for an exam, or studying in general? So I figured I'd write a post on it.

1. Time-Keeping

Pace yourself. Students are in the habit of cramming before exams, which is fine as long as it works for you. But even when cramming it's important to keep a steady pace. I'm not a crammer, the thought of leaving studying till the last minute freaks me out and as I have a hard enough time absorbing information it just seems like academic suicide. So I use all the time I have available to review in short bits with a break in between.

Let's say I had 2 weeks to review for a math exam. Each day would schedule 2 lots of 1 hour for a subject, so day 1 I would look at one subject and only one, such as Vectors. After those 2 hours I'd stop regardless of where I was at. Day 2 I would pick another subject and do the same. Each day I pick a new subject and don't repeat the same subject two days in a row. If I wanted to go over vectors again that's fine, just make sure to put something between it, otherwise you end up spending half of the time on one subject.

2. Choose your subjects wisely.
As far as choosing the subject order I start with the things that I'm best at. Ideally you want to cover the course subject matter in its entirety but there's not always time. Because I'm best that them they'll take the least amount of time to review and most importantly, I find the harder things are easier to understand when you have a firm grasp of the easy stuff. And if you get to exam time and you've spent all your time trying to understand only a couple of the very difficult subjects, how prepared are you? Especially if those subjects don't appear on the exam. This can be applied over any time scale, but I suggest that you stick to hour long blocks of study time. I.e. shorten the breaks, not the study.

3. Crowd-sourcing.
I'm against crowd sourcing generally for two reasons; 1. A crowd sourced opinion is no opinion at all. 2. there's a lot of crap out there and some of it is... less correct than it should be. That being said, hit the internet and look at how other people interpret and express the subject. Especially in regards to math and programming I found it really helps.

4. Conversation.
Find someone who understands the subject at about the same level, or another people who is reviewing for the same exam maybe. And converse with them about it. I don't read well, so library books and other literature is largely wasted on me, so I converse, with tutors, with students and some time with my 6 year old son. Any one who will listen and respond to me so that I can assimilate the information spoken out loud.
After explaining this technique to a fellow-student he responded with "So that's why you're always quizzing all us before exams?"

So that's it. That's my studying technique and it's served me pretty well

Tuesday 15 January 2013

Test Driven Development: Prologue.

I'm putting down, for the record, that I'm going to endeavour to do more testing in my software. I plan to do this by means of Test Driven Development. While I plan to do as much work as possible in Xcode probably using GHUnit or OCUnit, visual studio is proving inescapable so I'll probably be using NUnit as well.

What I already know.

I went for an interview for an industrial placement at a software company that uses Extreme Erogramming with TDD for all of their software. Now, I'm a big fan of XP and this has proven hugely successful for this company so I paid attention to their processes.

  1. Write the test. Make sure you give it a name that describes what the test is for.
  2. Fail the test. This was really important, especially as the application starts to grow, because new tests won't always fail, but they should. If you skip this step you can end up wasting a lot of time trying to fix a problem that isn't there.
  3. Get the test to pass as quickly as possible. This is also very important because it stops you spending hours trying to implement the most ideal solution and losing scope of what you're trying to do. Literally just throw in whatever you can to get that test to pass.
  4. Refactor. Make it look nice, now is that time to maybe think about the ideal implementation, but not too much.

This approach gets a lot of criticism from people saying that it promotes bad design, or poorly written code. But the idea behind TDD is that you're focussing on a single problem at a time. So when you start, yeah you have a bunch of really inflexible code and virtually no design in place. But as the number of tests grows and likewise the application, better design falls right into place and you end up with a very robust piece of software.

Anyway, I'll see how I get on. It may be a bit naive of me to just be saying All my products will be TDD from now on but I'm going to give it a go and see how far I get.

Monday 14 January 2013

Group Work

This post may come across as whiny, it's really not meant to be so, I'm just trying to document the entire experience so that the lessons learned are more clear.

This semester I had the pleasure of a group assignment. This particular module awarded a great deal of freedom in the assignment and looked to be very very fun. I was excited about this class.

I was given some advice earlier in the year on group work, that was a few items that are roughly as follows.
1. Find a group of good people, not your friends.
2. You're going to get roped into being the team leader sooner or later.
3. Don't forget that others struggle with this stuff more than you do.

The assignment can be summed up as this; as a group make a game engine and use it to make four different genres of game to demonstrate the engine. Awesome.

Firstly there was the division of work.
We talked and talked about what kind of games we wanted to make in the hopes that it would give us an idea of what types of engine components we needed. 2 weeks of these talks got us no where, so it came down to me to make the decision for everyone.
So I decreed: "I want AI, you do physics, you do graphics."
"But I don't want graphics."
"Fine I'll do graphics. You do physics"
A little time passed and I actually wrote a working tile engine for the game before.
"I can't do physics I want something else, but graphics is too easy."
and so on.

The end resulted in me on physics, him on AI and him on Graphics. But surely the more astute of you have noticed that me, him and him only amount to three, and I mentioned four before.
That's because another 'friend' found himself without a group. So me being the charitable person I am had suggested that we wouldn't have a problem with him joining our group. He was a sharp guy, if a little unreliable, very unreliable... What the hell was I thinking? I regretted this decision the moment I spoke up. Having this guy in our group could only mean disaster...

So then, what should the new guy do? Sound? No too easy. Physics? No too easy (thanks). I want to do a lighting engine. Great, it wasn't a crucial component to the engine and if he finished, it would be a cool effect.

The weeks went on and our graphics were finished in an instant, well done you. We had a tile engine and a screen manger and some basic artwork. Meanwhile I'd created some of the framework of my physics and got a particle system working pretty quickly.
More weeks rolled by and I worked and tuned my physics and started working on collisions and all that goes with it. All was going relatively well, except that guy number 4 vanished. He stopped attending classes, didn't so any work, wouldn't answer messages, nothing. So we counted him as lost and resumed as a three piece. Or so I thought.

Week 10 rolled up, two weeks to go before christmas break, 4 weeks before hand in. I proudly finished my physics engine and started working on my physics based game. The graphics stuff still lay there, unchanged, no sign of AI.
Week 12 came around, it was christmas break and I'd finished my game, I had no more work to do...
First week of christmas break rolled by and there were quite a few premonitions of work but none actually appeared. Second week is when suddenly my team burst into a flurry of activity. Guy number four appeared out of no where with a complete lighting system, which I greedily incorporated into my game, and then he vanished again. The graphics stayed the same and still no sign of AI but I was assured that the work was being done.

3 days before hand in work started to appear, first part of a graphics game and some additional features, then some AI that didn't work, but would eventually. Oh goodie. I was bombarded with questions and problems and ideas, none of which I had any time for but couldn't ignore because my grade was on the line.

I'm happy to report that we made hand in with a working game engine, 4 game demos and a report. It all looks like it was put together by drunken monkeys. I've asked for the project to be graded on an individual basis in hope that I can save some of my marks but we'll have to wait and see. The entire thing was very frustrating for me and while I did my best to be Mr. Optimism and Support I came very close to negotiating a solo contract with the module leader.

In the end our demo received praise, the tutor was impressed by the number of features it engine included and said it was a good project. So alls well that ends well I guess, hopefully we've come away with good marks despite the issues and hopefully we all learned something about working as a team.

What did I learn?
Take advice from academics when it's given to you. They've seen countless students fail and succeed and thus, they're in the best position to advise you on such matters.

Friends usually don't make good co-workers.

As flattering as it is to have people leaning on you for support, it doesn't help you stand up straight.

Never underestimate the amount of work a student can get done in one night.