This week it was back to (somewhat) familiar territory for me as we spent the week in C#. I’ve spent a number of years doing various C# classes, but being able to focus on just this rather than squeezing in studying around a fulltime job and all the other day-to-day things we have to do is invaluable in being able to keep all the dots connected in my brain.
Well, now I’ve stated my belief that code should be readable and not include unnecessary additions, let me get off my soapbox and back to C#.
We had two assignments tonight – both small. One was a lot of fun: just playing movie sound-clips from a URL – a random choice from the three I put in. Mostly it was fun for the quotes I selected:
“I cannot allow you to do that, Dave” – HAL
“Hasta la vista, baby” – The Terminator
“The needs of the many …” “… outweigh the needs of the few …” “… or the one …” – Spock & Kirk
Now you know my awesome taste in movies!
Next up was collections and boy, does C# ever like to collect collections. Beyond arrays there are <deep breath> ArrayLists, Hashtables, Generic Lists, Generic Dictionaries, and a few others we didn’t cover (like HashSet – something to read up on another time: it has some speed advantages over Lists for operations like determining if an item exists). We didn’t cover (but I read up on) making asynchronous calls using async & await, although this is something I’ll need to revisit as I was battling the homework, which curtailed my reading time. One thing I find challenging as a developer is figuring out certain kinds of algorithms. I usually get it in the end, but sometimes the time I need exceeds the time I have available for figuring it out. This, I have been assured by developers far more experienced than myself, is something that comes with time & practice – and I will practice this. I’ve identified some resources to look at for strengthening my skills in this area (here, for example), but given it will likely come down to repetition & practice I will be seeking out opportunities for doing just that.
Wrapping up our formal instruction for the week was a introduction to writing robust C# code. Internet connections go down; files get moved, renamed, or deleted; external resources that your application needs can mysteriously vanish. This is where Try-Catch can be very helpful. You don’t use it for everything, but if you need to access something you don’t have control over via your application logic (whether it’s your database or Google.com), you want to wrap that attempt to access it into a Try. And if your attempt to access it fails, Catch can give you a more meaningful error than simply crashing the program.
Testing your code before it’s released to QA is always a good thing – and with complex applications where errors in logic can be made (“+” is mistakenly typed as “-“, for example), it’s good to test potentially problematic methods with some unit tests. Now, there are various options for unit testing out there – we focused on the concept and so wrote a (very simple) unit test manually. In doing so we learned the fundamentals – test a unit of code at a time; use known data for testing; and check the expected output using Debug(Assert). Writing unit tests by hand can be time-consuming, of course. But tracking down a typo in hundreds of thousands of lines of code is also time-consuming. There is a school of thought that says “well, we’ll know we have a problem if it errors/returns bad data”. However, there are applications that deal with unknown data, such as in the eDiscovery industry (searching text in millions of documents, correctly identifying file types among millions of unknown files are two examples where you have no easy way of checking the output). You could easily fail to return all documents with a given string and not know it; or incorrectly identify certain file types and not know it. This becomes a problem of how do you validate results when the input data is not known well enough? And unit testing is ideally suited for that type of scenario.
I got back to work a little on my project this week too: jumping ahead into next week’s material I started working on creating the backend for my project: a Web API and server-side controller for the “items” data part of my web application. I’m looking forward to having a real database to use instead of just objects! I was able to get the retrieve functionality working (with a little help), but I was pleased with my progress on this. You can see my updated project here.
Over the weekend I spent a good few hours exploring more than a few rabbit holes. Our task was to create a simple, console-based Blackjack game. Now, you may recall that I have said before that I’m not a games person, and especially not a card games person. Just never appealed to me. But I dug out some simplified rules (i.e. ones that I could understand and would make a purist wince), and got to work. Of course, I needed a collection to hold my deck of cards, but also needed to be able to update that collection each time cards were dealt out by removing said cards. And of course I needed to be able to randomize (a/k/a “shuffle”) which cards were dealt to each player. Well, I got very excited when I discovered there was such a thing as an ordered dictionary – reason being that this could hold both a key (the name of the card), a value (the value of that card in the game), and, most important for my purposes, an index. Why was an index so important? Well, so I could track which card I had dealt and needed to be removed, of course.
However, I eventually discovered that although an ordered dictionary had an index, it wasn’t possible to actually access a specific card via the index. So that was an interesting rabbit hole I went down for 4 or so hours. But if you have any questions about an ordered dictionary, I can probably now answer them!
Next up: a list. A list may have been the more obvious choice to begin with, but as it was the “suggested” solution, I didn’t want to just go with it without doing my own due diligence. Maybe I’m just stubborn … In any case, I eventually ended up with a list of card objects (the deck) from which I randomly pulled (math.random, with the highest value set to the length of the list), either 4 or 2 cards, depending on the stage of the game. Then I would put those dealt cards into another list which was used to assign the cards to the players. Having done that, I would then go back and pull the cards from the deck, by index. I did realize, a little too late, that there was an issue with this in that when you pull an element from a list, it shrinks the list – so the index could be out of bounds. There are a few ways I could fix this: pull the item by it’s unique name property, for example; or look for a match between the “cards to assign” list and the “deck” list; or add a boolean property to my Card class that simply flags the card as already dealt or not. But time ran short and I wanted to work some more on my project, which is due in less than 2 weeks, after all …
Halfway through – and I’m still having fun!