Welcome to my twice-yearly post about “What I Did This Semester”. Hopefully this will be the last one for at least a few years, unless I’m back in school just for the heck of it because I struck oil or won the lottery or something.
Let’s start off with one of the most memorable quotes from my time doing tech support:
“I don’t know what a web browser is! Stop using jargon!”
She sounded like a relatively young woman, and I sometimes wonder if she was a plant. (I wouldn’t have put the client above having people call in pretending to be less knowledgeable than they were in order to see what help they would receive. It was a toxic situation all-around.)
Anyway, I found her defensiveness perplexing. As an analogy, you’d expect someone driving a car to have some idea of what a steering wheel is. A web browser is such a fundamental part of most people’s computing experience that I have no hesitation in expecting people to know what it is.
I didn’t, though, say that I was going to have an attitude about it if you didn’t know what it was. I won’t look down my nose at you and exclaim, “How could you not know that?!” though my younger self probably would. If you don’t know, I’ll happily explain, “It’s a program on your computer that lets you interact with websites.” I don’t know if I ever put it that succinctly, but generally if someone asks a question like, “What’s an operating system?” you can answer “It’s a very large program* on your computer that manages your hardware and lets you run other programs. Windows, which you may be using, is one such operating system.” and everybody moves on to happier things.
It’s okay not to know, or even care. (And boy howdy, Microsoft is good at cultivating that attitude.) But getting indignant with me about having mentioned web browsers and operating systems as if you knew about them is like getting upset with your auto mechanic when he uses complicated terms like “engine” and “brakes.” Just, I dunno, ask. Now, for my part, I’ve often asked for explanations that I didn’t end up understanding – not everybody is really all that great at explaining things to someone who isn’t themselves – but you can give your interlocutor a chance instead of just getting mad that they weren’t intimately familiar with the shores of your ignorance.
This all being said, I am going to make an attempt to talk about what I did in this fourth semester in a way that the person I was before starting the program could understand it. This will be a fun challenge!
* - If you’re asking this question, you’re probably not running MINIX or GNU Hurd, unless it’s the 22nd (or 23rd?) century and they’re what everybody has.
Programming 2200 – Advanced Object-Oriented Programming
This was really more of an “advanced topics” course than it was about object-oriented programming itself. Well, there’s our first bit of jargon – what is object-oriented programming? As far as I understand it, it’s a paradigm that lets you code in terms of instances (“objects”, like willsHouse) of things (defined by blueprints called “classes”, like a House) and what those things can store and do. I think it’s fair to say that there is a bit of a fetish for objects even when there would be no apparent purpose for them – C++ lets you use functions outside of classes (so don’t make the mistake of thinking you know OO just because you use C++), but Java and C# don’t – even the code that starts a program has to be defined inside a class*.
* - To confuse you further, this code has to be static – that is, it is not only applicable to an instance (object) of the class it lives in, but rather the program’s entire environment. Sometimes a static method / function is handy because you don’t have to have an instance of something to use the function. (And when you’re starting a program, you have to start somewhere – a loading method wouldn’t work if it weren’t static.) It’s a lot easier to design complex programs with classes and objects, once you get the hang of them, but sometimes the overhead isn’t worth it – if you only need a square(x) method, why write a Math class just to hold it?
So I told you all that to tell you that this course wasn’t really about object-oriented programming, but we did use it constantly, since we were developing in C#. What we really covered was:
- Writing a basic network chat program.
- Writing a multi-threaded chat client. (A client is a term for a program that uses a service. A server is a program (or piece of hardware running such) that serves a service.) This client had to be multi-threaded (running in more than one discrete process) because a message could come in at any time, so we needed (at least) a message listener. We needed an extra thread for that because you can only do one thing at a time on one thread, so if you didn’t put your message listener on a different thread, the whole user interface would lock up (because your thread would be listening for messages rather than responding to your mouse clicks and whatnot).
- Writing a simple game of our choice that used graphics (for me, Maize, see below).
- Learning something development-related of our choice that had not been covered in any of our courses and presenting it to the class (a “Gap Analysis” – I did mine on Python, see below).
This was a good follow-up exercise to the maze-solvers we wrote for data structures. It turns out that building a maze with a stack (visualize a stack of papers on your desk that you can only set down or remove sheets from the top of) of x/y positions bears a lot of similarity to solving a maze with a stack. Describing either to anyone who isn’t a brilliant verbal-visual translator won’t work well, but I’m fairly confident I could explain either algorithm with a whiteboard.
I’m very proud of the fact that my game works with Windows Forms and not in spite of it. :-p You can minimize, maximize, resize – though I did put a lower limit on the size of the window to stop the maze from disappearing entirely. We were required to use double-buffering, too. But for layout reasons I was drawing on a panel, not directly on the form, and for some reason double-buffering isn’t something you can just turn on for panels. I followed these directions to subclass* a panel.
You can download Maize here.
* - To make a descendant class of an existing class, override particular things from the ancestor, then instantiate an object of the descendant class instead of the ancestor so I get the blend of the built-in and overridden behaviour I need.
For my “Gap Analysis”, I picked the Python programming language. I did so because I’d already started Zed A. Shaw’s Learn Python The Hard Way tutorials. (I found them through an article about PHP: PHP: a fractal of bad design.)
Python is a good language to write in because the syntax is compact yet very readable – you can bang out entire classes in just a few lines! You can also have functions outside of classes, like in C++. Boilerplate stuff is kept to a minimum, and things just tend to work the way you hope they do. If you’re interested in programming at all, give Python a try!
I used the Python I learned to put together a little satire called NSCiCi. You can even run it in your browser! It’s also part of the “teachback” package you can download that has my report and code samples.
Programming 2400 – Data Structures
To some extent, this course was about how to store things in a structured way. But it was also about the algorithms that work using these structures. C++ was used throughout. We were encouraged to try to get our code working on another operating system, so I developed and tested on a Linux distribution called OpenSUSE in a development environment called NetBeans. (Eclipse is just too much for me.)
An example assignment would be: Create a stack (yourself – don’t use the built-in libraries). Again, a stack is like a stack of papers on your desk that you can only set down or remove sheets from the top of. Then use this stack to solve a maze. (I went on to make a C# library that generates a maze – it’s part of my Maize program for Advanced OOP.)
Describing maze-solving without extensive visual aids is probably futile, and I’m not showing the related assignment in the portfolio anyway. (Okay, you can have this picture.) Instead, here’s some information about two other important assignments that I did:
Explaining most of my assignments requires some preamble! Consider this tree:
4 2 7 1 3 6 8
(I deliberately omitted 5; don’t worry about that for now.) You start at the root (4) and check if the thing you’re looking for (say, 3) is equal to, less than, or greater than the thing you’re looking at. If they’re equal (you found it), hooray, we’re done! If what you see is greater, you go down the left branch to look at things that are less – if it’s less, you go down the right branch to look at things that are greater.
So in our example of looking for 3, we go left from 4, we go right from 2, and boom! there’s our 3.
That was the “nice” scenario. That tree was “balanced”. Instead of explaining what a balanced tree is, let me show you an unbalanced tree, and you’ll get it right away:
1 2 3 4 6 7 8
See the difference? In the previous tree, everybody was only two steps from the root at most. Here, 8 is six steps from the root! But you’re going to get a tree like this second example if someone feeds you a list of sorted numbers and asks you to make a tree out of it: 2 is greater than 1, 1 has no right child, so put 2 down the right side of 1… 3 is greater than 1, 3 is greater than 2, 2 has no right child, so put 3 down the right side of 2… you can see how you’d end up with a vine instead of a tree! (We care about this because we want to be able to make large trees that perform acceptably, and all these extra search steps take time.)
Now imagine if this was a much bigger tree, full of dictionary words in alphabetical order. Our job was to create this tree and somehow make it so that it was balanced (for this, I used my own hackneyed implementation of the Day-Stout-Warren algorithm).
We then processed a text file and displayed the misspelled words – anything that wasn’t in the dictionary. You know that something isn’t in the tree at all if you fall out of the tree instead of finding the thing: someone searching for 5 in the numeric examples would just hit the dead end trying to go left from the node holding 6.
A bubble sort is very easy to code – if you are sure that you are only ever going to have a handful of items, go ahead and write one. It’s not a bad place to start learning.
But a bubble sort generally takes time proportional to the square of the items you have to sort. As you can imagine, that gets out of hand in a hurry. What you want is an algorithm that tends to sort in time proportional to, say, the number of items you have to sort times its logarithm. That’s not nearly as bad.
We tend to develop programs using “tiny toy data sets”, and it’s easy to write something that provides perfectly acceptable performance in the testing environment but performs abysmally poorly when subject to real-world tests. Read more here: Everything is Fast for Small n.
So for our assignment, we generated a list of 10,000 random integers. We implemented various sorting algorithms and timed the results. You can see this in the “Sorting” project in the download.
But the real pièce de résistance was the external merge sort. So you have your file with 10,000 numbers. What if you only can store 1,000 numbers in memory at a time?
What you do is you load the file in 10 runs of 1,000 numbers – at the end of each run, sort the numbers (with a mergesort if you need stability), and save them somewhere else.*
So now you have 10 files with 10 sorted lists. Your task now is to merge them. You can set up 10 file readers and one output file writer. Start by having every file writer load their first number. Take the “left lowest” number, and write it to the output file. Then move the corresponding file reader to the next line. Repeat. You can see this in the “ExternalMergeSort” in the download – I used 10 file readers on two buffer files instead of 10 buffer files, but it’s the same idea. (We might as well have used one file, but the assignment requirements were fairly prescriptive.)
* - With my program, if 1,000 really was a hard limit, I’d have to do 20 runs of 500 or something, because my mergesort is not “in-place” – it needs extra memory to work with. A quicksort can be done in-place, but is not stable – number n from line a won’t necessarily slot in before the same number n from line a-plus-something.
Programming 2500 – Windows Programming / C#
When I posted my schedule for the semester on Facebook, one of my friends exclaimed, “‘Windows programming’? Is that a history course?”
Well, this is another case of a course in search of a better title. We weren’t really learning programming for Windows so much as we were learning to do some desktop-application stuff in C#, for the .NET Framework, which in turn runs on Windows. I’m a fan of .NET but writing applications for it is not nearly the same thing as writing directly for Windows. But the good part about writing for .NET is that someone can cook up another implementation, for example Mono on Linux, and you can bring your stuff over there (at least that’s the vision).
We started off by porting our Dungeons and Dragons projects from Java to C#, which was a good way to see first-hand the similarities and differences. (I didn’t implement multithreading and delegates, though, because I hadn’t yet been trained how to use them. I didn’t know how to use them in Java, either, but I didn’t let a silly thing like that stop me.) Most of the rest of the course was integrated with our Capstone project, except for an individual examination at the end.
Okay, so how do I explain what the exam was about? We started with a single table of records… well, we had to make the table and the records. Then we set up a data access “program” (well, a library) capable of connecting to, executing commands on, and returning result sets from this database. On top of that, we wrote a “business layer”, a go-fer that translated between a pure entity class (think “Hi, I’m newStudent, a Student! My name is ‘Bob!’”) and the database (think database stuff like a name column in a Students table). Finally, on top of all that, there was a desktop application that wrote and saved in pure entity terms, without any idea of what the database was. Architecture!
Oh, and then we built a web service to return the pure entities in XML, a plain-text markup language used for information exchange. This was a lot easier than it sounds. Then we made a quick-and-dirty website to consume this webservice and display these records. Again, fairly easy – if you know what you’re doing.
The instructor released a practice exam with the same specifications, but on a different entity (like, say, Questions instead of Students). So for that reason I don’t feel like I’m betraying the system by providing information here. Anyway, I completed the practice exam to its full specifications. And the real thing still took me four-and-a-half hours!
I could have done this project in half the time – or less! – if we’d been allowed to use LINQ to SQL. It can do all the business layer stuff we did manually automatically and reliably. There’s no reason not to use it (for those who might wonder, yes, you can use stored procedures, and it’s a snap). LINQ is relatively new, coming to .NET in 2007. (There’s also the more complex Entity Framework that can even build a database that fits your application code, but for this it would have been overkill.)
So one of my friends taught me how to do all the database stuff manually. Without him, I would have been up the creek. In the end, I guess it was a pretty decent learning experience, if a bit jarring and last-minute because we didn’t need to do the translation stuff manually (at least not between SQL Server and a .NET app), except for this exam.
Writing object-relational mapping stuff yourself is becoming the programming equivalent of churning your own butter. So I guess this was a history course.
Web Development 2000 – Rich Internet Applications
We did four things in this course:
- Design and build a responsive portfolio. (“Responsive” here means responsive to the dimensions of the browser being used.)
- Design and build an e-Commerce site in Flash Builder. Made even easier in Flash Builder 4.7, since Adobe took away the design tools. Flash Builder is also based on Eclipse. Just kill me now.
- Design and build a video player in Silverlight. Even though the code-behind can be C#, it’s enough unlike coding a desktop app to be seriously jarring. Here’s just one example of something that ought to work but just doesn’t work, and you get no reasons anywhere why not. Fortunately, Expression Blend had a design tool, so the experience overall wasn’t so torturous – for the first time I was able to deliver a finished product that looked remotely like my design!
- Do a 20-minute teach-back on an internet technology we learned. I did mine on Django, a web application framework for Python. It was a serious overreach – I wanted to get everyone from scrach-zero to the working sample polls application from their tutorials, but the plane exploded on the runway. I integrated the highlights of the presentation into my Advanced OOP project on Python in general.
So I did up a subset of my portfolio in a newfangled responsive format. (It's live here.) By the way, if you know how to get figures with figcaptions to display neatly inline (i.e., beside each other), let me know! Go under “Coursework” and you’ll see what a hack I had to do, in the absence of inline figures-with-captions. One of my personal gripes with CSS is that everything I do feels like a hack. Maybe I just haven’t been motivated enough to actually learn good web design. But I really like the responsive media queries, and I will be doing mobile-first design for all of my future projects. I got started with Initializr – doubtless there are other choices, too.
(But why they couldn’t just have a “layout” pseudo-table that switches to stacking as part of plain-old HTML, I don’t know.)
Web Development 3000 – Web Application Development II
In this course we learned to make soup-to-nuts web applications on the Microsoft stack – ASP.NET websites leveraging SQL Server databases.
We also learned how to make and use Web Services that generate and return lists of objects in XML (a plain-text markup language used for information exchange). I love Web Services, because they’re somebody else’s job to consume! (Me give you data. You do UI.)
Our final project was the e-Commerce site for our Capstone projects. I talk more about it there. For the purposes of this page, though, I’ll show you our “Publishers” assignment that used the good old “pubs” database. It’s relatively low on the whiz-bang, I admit, but it has a few tricks like dynamic theming and dynamic charts.
Information Technology 3000 – Capstone
In a nutshell: We got into groups and held meetings with a (pretend) client to glean the requirements of a project, we wasted a few weeks on diagrams and use cases, and then we ignored the diagrams and use cases and delivered the project. I worked with Jamal Rahhali, Brandon Richard, Richard Sayat, and Alan Smithee.
The centerpiece of this course was a desktop application that would automate the procedures of the client’s ordering and manufacturing departments.
The good news is that we got the desktop application sort of working. It was far, far, far from perfect. Sure, “perfect” is a line you can never ever quite reach, but we were, it’s safe to say, measurably far from it.
If I were doing this again, I would have banged out the database manually instead of trying to use the Entity Framework. We probably weren’t using it properly and, among other things, we ended up with a bunch of duplicate foreign keys* in the database.
This was a difficult project to manage for several reasons: first, if one person needed to make a change to the database, that change would have to be mimicked in everyone else’s environments. Worse, the desktop application, tabbed though it was, was all in two classes – manufacturing and ordering, so you were always hanging around in the same scope as the tabs your teammates were working on - this might have worked if we were better coordinated! You also had to think about when to load your data so that yours wouldn’t get out of sync because of something a user might do in another tab. As always, the wonderful Index out of Range Exception** was the bane of our existence.
After the desktop application was “finished”, we turned our attention to the e-Commerce website. A user can register for the site, then the admin will figure out which client account the user is associated with, make that association on the back-end site, and then the new user can sign in to place orders, view their order history, and manage client contacts. The security is role-based: this user is an admin, this user is a registered user, this user is a new user… and the role determines what pages can be accessed and also the links that they see in the navigation menu.
I started coding from the back-end and my teammate started from the front, and we had our Great Moment™ when he made a user submit an order (the checkout was the last thing he made) and we saw that order appear on the order history page (the history page was the last thing I made). It was like the English and French meeting under the Channel.
The whole kit and caboodle is in the download.
* - Picture a table of Students. Students are registered to one and only one Campus, so there’d be a Campus_ID foreign key in the Students table. In it is the record number of the Student’s corresponding Campus in the Campus table. Our use of the Entity Framework was mucked up enough that we had the equivalent of a “Campus_ID”, but also a “Campus_Campus_ID”, both containing the same record number.
** - This happens when you try to do something at an index/position of an array or list that doesn’t exist yet. For example, here is a zero-indexed list, let’s call it myList: 1 3 5. If I do this: myList + myList, that’s 1 + 5, so I get 6. If I do this: myList + myList, the computer explodes and everybody dies.
OK, now I’ll crow about my grades. The legions of you who don’t care can stop reading.
|Windows Programming / C#||100|
|Rich Internet Applications||96|
|Web Application Development II||100|
According to my calculations, my average for the entire program, weighted appropriately (that is, I counted 30 credit hour courses once, 60 credit hour courses twice (most courses were 60), and 90 credit hour courses three times), is 98.23. I'm hoping that's enough to win the award for the highest grades in the concentration. It might be a hollow achievement. But it's my hollow achievement. :-)