luminousmonkey

The land of marking

Wednesday 10 October 2012, 21:30 WST

The land of marking

I’ve come across my lecturer’s blog!

And honestly, I think it’s a good read (I’m not trying to get points here, I liked reading though the posts). Anyway, the thing that I’ve found most interesting are his observations on marking, and I found this little nugget of a graph that he posted. The graph actually does touch on some things that we have talked to some of the 2nd/3rd year students and some of the tutors, that marking student assignments isn’t always easy.

(Go read Dave’s posts on marking for the perspective of someone who has to mark/assess/teach students, not now though, finish this first!)

I find it interesting, because as I’ve mentioned before, I’ve been worried about knowing too much, and being “that guy”. OK, now if you’ve gone off and read that post, then there’s a strong chance you think I’m a dick. Seriously, I’m not trying to be a dick, and I certainly don’t think that I know anything! If I did, then I wouldn’t be going back to Uni. But, being human, I’m biased by knowledge I already possess. And I’ve decided to, hopefully clear up what I actually mean, because, luckily I’ve got a reference from the other side of the whole teacher/student thing.

A problem that exists in computer science degrees (and I’m sure other degrees), is what do you teach the students that is relevant to the field they’re studying. So, for computer science, thinking about problems, breaking them down, the math behind algorithms, data structures, and trying to form good programming habits. Now, you can get a mix of a degree that focuses on a more “pure” mathematical/theory type of course and a course that is more “practical”.

Why “pure” and “practical”?

Now these are two different thoughts an the same axis. Either approach isn’t wrong! You can also have a mix between the two. But people who have their own experiences with developing software/computer science have their own opinions. I’ll just fire off some that I found with a quick Google search:

I’m not using any of those links other than as an example that there’s a “pure” and “practical” mindset. I obviously see some value in going to University to study computer science, otherwise I wouldn’t be going! I would like to get a job in a computer science/programming type role, but I’ve already got a pretty good job where I can code occasionally, but not as much as I would like. Actually, I even have a three screen setup, only way to fly. Right, sorry, back to my point.

So, “pure” and “practical”, and this is where having some knowledge bias comes in, because I have my own thoughts on “the way things should be done”, but! And I mean BUT! It really isn’t largely to do with the teaching methods, I obviously have no qualifications on teaching at all. Plus there are just some things that are limited by time and money. However, the content, that’s where I have some bias. And, now finally bringing it back to the point that the graph made me think about. (Finally!!)

So your point is?

Actually, I have two that I really hope to get out in this incoherent ramble, the mindset of the student in regards to marks, and thoughts on things that should maybe be included.

So, marking? The graph is a pretty good indication of this problem (Smartarse Plateau). When working on the exercises, tests, and assignment, as a student you’re usually interested in getting marks, getting marks means you get to pass the units, which means you get to get out of Uni and out in that wide real world. Without prior knowledge, not so much of a problem, you’re learning what they’re teaching and you generally don’t have you own bias. Ahh, but a little bit of knowledge is a dangerous thing.

The problem is, that for the sake of making marking easier (and encouraging a higher grade), you do some things that wouldn’t be “right” normally. I don’t think much can be done to really change the situation however. Because it’s just one of those things, for the sake of being practical you have to make concessions.

I just recently handed in my assignment, I really feel my effort was a bit clunky, I’m just not an outright brilliant programmer, he’s a little snippet of me cutting corners:

    // NAME:    equals
    // PURPOSE: To compare two CarPolicy instances for equality.
    // IMPORTS: inCarPolicy - CarPolicy we want to compare to.
    // EXPORT:  boolean, true if they are equal.

    @Override public boolean equals( Object inObj )
    {
        boolean result = true;

        // Handle if we get handed in null, or completely different
        // classes.
        if ( !(inObj instanceof TravelPolicy) )
            {
                result = false;
            }
        else
            {
                TravelPolicy testObject = (TravelPolicy) inObj;
                result = testObject.dateString().equals( this.dateString() ) &&
                    testObject.policyCountry.equals( this.policyCountry );
            }

        return result;
    }

I’m testing equality of my dates by comparing the strings, rather than using an equals method from the superclass.

Er, OK, so your second point?

OK, so my thoughts on what should be touched on for a first semester programming unit? Really, I’m completely unqualified, I have no degree, I’ve never worked at a software company, and I haven’t produced anything. I’m an armchair software developer, sadly. But, my own opinion?

I don’t think object orientation should be the first thing that is taught, source control management software should be used, or encouraged, and they probably shouldn’t be using Java to start with.

OK, it’s late, and I want to get these thoughts posted, otherwise I’ll never post it and it will remain in my drafts for eternity. And coming back to these points will be a good excuse for some more posts.

Clojure for Java Development

Friday 07 September 2012, 20:24 WST

I’m just working on my Uni assignment, a program that allows you to show and add some insurance policies. It’s a test of object orientated principles, so we have different insurance policies that we’ll have to use inheritance for home, car, and travel.

Anyway, I’m working on getting date parsing and handling of the file format, and I have an advantage. I have the Clojure REPL.

So, I just have a little bit of a play to understand how it works:

;;; Get our Java class for handling dates in.
(import java.text.SimpleDateFormat)
;; java.util.SimpleDateFormat

(def date-formatter (new SimpleDateFormat "yyyyMMdd"))
;; #'user/date-formatter

(.parse date-formatter "20120101")
;; #inst "2012-12-31T16:00:00.000-00:00"

;;; I was getting confused why the date was coming up wrong, but then
;;; after a bit more playing, trying different Locales, I realised that
;;; the date is being stored internally as UTC. When I output to a
;;; string:
(.toString (.parse date-formatter "20111102"))
;; "Wed Nov 02 00:00:00 WST 2011"

;;; I get the correct date.

I might have wasted a little time because I was getting tricked at looking at data the wrong way, but I also was getting feedback quickly enough to learn a little bit more than I otherwise would have if I wasn’t using a REPL.

Object Oriented Program Design 110 – Workshop 1

Thursday 30 August 2012, 21:39 WST

I did the first workshop about five weeks ago, and, as usual, I’ve been slack doing any sort of posting to my blog, so I thought that I would at least do a post now.

The first week exercises, are as can be expected, pretty easy. So, I thought I would write a Clojure version as well, for practice, so without further delay.

import io.ConsoleInput;

class MyFirstApplication
{
    public static void main( String[] args )
    {
        // Read in our integers from the user.
        int integerOne = ConsoleInput.readInt( "Input first integer" );
        int integerTwo = ConsoleInput.readInt( "Input second integer" );

        // Print out the results, one per line.
        System.out.println( "Sum is: " + (integerOne + integerTwo) );
        System.out.println( "Difference is: " +
                            Math.abs( integerOne - integerTwo ) );
        System.exit( 0 );
    }
}

Nothing too hard, just reading in two numbers and returning the difference to the user. They provide the ConsoleInput class, so we don’t have to worry about any complicated user input stuff.

Here’s the Clojure version, since it runs on the JVM, I can still use the ConsoleInput class.

(ns P01.my-first-application
  (:import io.ConsoleInput))

(defn -main
  []
  ;; Read in the integers from the user.
  (let [integer-one (ConsoleInput/readInt "Input the first integer")
        integer-two (ConsoleInput/readInt "Input the second integer")]
    (println (str "Sum is: " (+ integer-one integer-two)))
    (println (str "Difference is: " (Math/abs (- integer-one integer-two))))))

There’s nothing really overly significant here between the two versions as the program is so simple.

A case of knowing too much?

Monday 16 July 2012, 05:25 WST

Ok, so, I’m back at Uni, after a long time. So long that I can’t claim credit for anything I’ve done before. However, I haven’t even started and already I’m feeling. There just isn’t a way to say it without sounding like an arrogant prick, overqualified. Of course, this is something I expected. The unit that I’m doing is the ground level programming unit. And it’s a level that I was expecting, but that’s not the problem. For example, the first real programming exercise is that we take two numbers from the user, and we provide the sum, and the difference between the numbers. Standard fare for the first week of a programming unit.

No, what has got me, is the very small contact I’ve had from the unit coordinator. Who I won’t name, because honestly, I think his heart is in the right place. Not only that, but I’m basing these thoughts on just the unit material that I’ve read so far, which isn’t much. Plus, also, I’m simply not qualified. I never finished my degree, I’m the definition of the arm chair expert, I never finished my degree in the first place, plus I’ve never once actually coded professionally. I’m kept in touch with programming, and I’ve got plenty of books on the subject. I’ve never stopped trying to at least keep an interest in programming. That is, after all, why I decided to go back. Not for any reason such as a career, I feel like I’m going to end up too old. I’ll be forty, forty-five years old when I finish.

Anyway, what worries me, and the actual point of this drunken blog post, is that I’m worried about the state of the computer science course I’m on. For example, I e-mailed the unit coordinator asking if it was OK if I worked ahead because some of the early stuff was very easy, and I’m trying to work fulltime at the same time, so I have to try and make the best of the time I have. I also mentioned that I had done the course before, and I had never stopped practicing, playing with Clojure and just touching on OCaml. His reply was poilte, and explained that there wasn’t any problem, which is fine!

However, he then mentioned that he had never heard of “Ocami”, and said that he didn’t know much about “Closure” except that it was a LISP? And here I get to my point (At last I hear you cry), how can the unit coordinator of a computer science course, not know these two languages? Now, I can understand someone working at a company not hearing of these languages, however, I feel that someone who is responsible for trying to teach the craft of software engineering should at least have a very basic knowledge of a shitload of languages. I mean, I’m not a software professional, but I’ve heard of them, hell I’m trying to learn them. How can someone who teaches this not at least know of them, played with them, or even just looked up the Wikipedia article on them?

So, I’m asking myself, do I know too much? Am I making a bad assumption here?

Object Oriented Program Design 110 – Week 1

Thursday 12 July 2012, 22:17 WST

Well, the unit material has been released, meaning that I can have a look through to get a feel for the unit. A little bit nervous, haven’t been at Uni for over ten years. However it doesn’t look like anything overly difficult, at least nothing in the first week. It’s just basic coverage of working with UNIX, changing directories and the idea of programming. So I’m just going to break it up into sections.

Worksheet

OK, this is just basic stuff, for example, logging into UNIX (I’m not too sure what *nix they’re running yet until I log on), opening up Firefox (so I assume it’s going to be Linux, just a hunch though), and setting the home page. There’s a few other miscellaneous things, nothing interesting. There’s also a bit about setting up the directory structure for the unit. I remember this from when I was attending years ago, they pull the program source code, etc, from your home directory so they expect it to be laid out in a specific way.

This is a chance for me to try and learn something I don’t know. Creating directories is easy enough, “mkdir”, however, you’re also supposed to have a series of directories inside the ST151 directory. P01, P02, P03… So, I thought I could try something different. Now, I did look it up, and (under Linux at least) you can create sub-directories in the one mkdir command as follows:

mkdir -pv ST151/{P01,P02,P03,P04,P05,P06,P07,P08,P09,P10}

So I’m wondering if there’s a way to do this nicely? I just did a quick look (ahhh Wikipedia, you were never around in my day), and the {} bit isn’t even something that mkdir does. I like learning stuff, and behold, I very quickly found Creating directory hierarchies in Bash. Brilliant! This is something that Bash does, so in theory it should just work under Solaris too.

So now, the command becomes:

mkdir -p ST151/P{01..10}

And it works! (I had to drop the -v, Solaris mkdir complains about it)

What problem is ORM trying to solve?

Monday 21 May 2012, 12:10 WST

This isn’t going to be a rant about ORM, more of a statement of my own problem I’m trying to solve. With the internal work sales application that I develop, I have the problem of not being able to specify business logic in one place. It seems to be a general rule with ORM systems (at least with my very small experience with Rails), that business logic all goes in the ORM layer.

class PurchaseOrder < ActiveRecord::Base
  include Shared::TracksSerialNumberExtension

  order_lines             :received

  validates_presence_of   :supplier, :despatch_by
  validates_inclusion_of  :ongoing, :in => [true, false]
  validates_date          :created_at

  owned_by                :supplier
  add_filter              :ongoing

  tracks_serial_numbers   :items

  sendable  :supplier

  attr_accessor :force_create     # This is if the user wants to create a new
                                  # order, even though an ongoing order may
                                  # exist.

  validate_on_create :check_for_ongoing
  validate_on_update :ongoing_set_on_create_only

  def initialize( params = nil )
    super
    self.created_at   ||= Time.now.to_date
    self.ongoing      ||= false
    self.despatch_by  ||= 'Most Economical'
    self.force_create ||= false
  end
...

This is pretty typical in Rails, and after all the model object needs to know these sorts of things so it knows how it’s all supposed to fit together. That’s fine. The problem is when you do what I like to do, and actually use the database as, well, a database.

It’s the job of the database to enforce data integrity, this includes things like making sure invalid data doesn’t get in. So those “validates_” bits, they also need to go in the database, not only that, but if you want to have a nice interface that shouldn’t piss off your users, you need those validates in your UI code as well.

So, the problem should be apparent, three separate layers need to follow the same rules, clearly a violation of DRY. That’s the problem, each layer needs to know the business rules and to do their bit to follow those rules. The UI needs to give the user feedback as quickly as possible about any errors, the application layer needs to know how everything fits together, and the database needs to make sure that the data is correct completely independently from the other layers.

So, we need a way to have business logic in a way that all three layers can use, in one place to make updates easy and as error free as possible. ORM doesn’t do that, I want something that does. I want to be able to define my business logic in one place, and to have it taken care of across all three layers.

Of course it has to be flexible enough that you can override anything you need to, otherwise you end up stuck in a framework like Rails and ActiveRecord and it becomes a pain to do anything outside of that.

The deal with ORM

Monday 21 May 2012, 09:37 WST

I’ve been reading lately, and by lately I mean my very long back log of Reddit. That there seems to be a few noises being made about ORM, and I thought I better just write a little note to myself in the form of this blog post.

Fuck ORM.

Except for the case where you’re writing a small, quick, throwaway program, in which case you should then admit that in most cases no such thing exists and you should be writing it properly. ORM is just a bad idea, ORM is just a case of programmers wanting to fit something into an easier way for them to handle databases. Isn’t that something that we should be doing anyway? We do it all the time. Yes, but, and you knew a but was coming. The correct abstractions should be applied, and showhorning an object model onto something that is relational data is going to be a problem.

Learn SQL, fuck it, pick a database and learn to use that. Use triggers, don’t use the database as a dumbstore!

Obviously, this post is all opinion and no substance, but I’m going to see about coming back and fixing it later on, I have to work.

OSX and being anal about music organisation

Monday 21 May 2012, 09:37 WST

I’ve previously blogged about my migration from Windows to OSX. A problem I have found, is that OSX is not really the best environment for how I prefer to organise my music collection. It seems that the software just isn’t quite right, however, first, an explanation of my setup.

Storage

To keep my music safe, and to save on my desktop hard drive space, all my music is copied from my CDs to my storage server (which runs Solaris). This is because Solaris has ZFS, which is an absolutely brilliant filesystem. Nothing else offered is as easy, nor as mature as the ZFS filesystem. For example, I had recently needed to upgrade my storage.

Normally something like this would involve backing the data somewhere else, installing the new drives, and copying the data back again. This approach has always been a little problematic, especially with larger and larger harddrives. However, with ZFS upgrading harddrives becomes an easy and safe operation.

Since I was more interested in keeping my data secure, I decided to go with a four drive mirrored zpool: Two 1GB drives, and two 500GB drives, for a total of 1.5TB. Such a configuration is not really about maximising drive space, since you only get half the actual space of the drives. However, it allows me to survive two drive failures (as long as both drives that fail aren’t the paired ones), and also means that if I want to upgrade the space, I need only replace two drives.

So, I needed to upgrade my storage, so how did I do this with ZFS? Basically I bought two 2GB drives, and first replaced one of the 500GB drives and booted. Then all I had to do was run the ‘zpool replace’ command (with the correct arguments of course), wait for the drive to re-silver, shutdown, replace the other 500GB hard drive, again ‘zpool replace’.

Once the re-silver there has finished, it’s a matter of ‘zpool autoexpand=on storage’ and I now have 3TB of storage space. The advantage of a mirrored ZFS config like this, means it’s much easier to expand in the future. No mucking about copying data from one place to the other (while also worrying that it may get corrupted in the transfer).

Ripping

First off, I use dbPowerAmp for ripping my CDs, since this is a very nice ripper, I don’t plan on changing it any time soon. So I will still have to boot into Windows to use it.

Music file layout

I organise my music files in a particular way, just because I find it easier to keep track of them. There is never one true way, but this is how I do it:

Music/Artist/Album/Disc <disc>/<track> - <track name>.m4a

Music that is only on one disc skips creating a “Disc 1″ directory.

Now this isn’t all done by hand, what I actually do (ensuring that anything I rip has the correct tag information) is use the best player on Windows (actually the best player on any operating system) Foobar. With the file operations module installed (an option when you install it), you can write a little bit of code so it will correctly move/copy files based off the tag information.

The one I currently use is:

$if(%tracknumber%,$if2($trim(%album artist%),Unknown Artist)/$if(%album%,$ifgreater(%totaldiscs%,1,$trim(%album%/Disc %discnumber%),$trim(%album%)),Unknown Album)/$trim(%tracknumber% - %title%),%album artist%/%title%)

However, I still need to refine it.

Next, I need to make sure that I have album art, and soundcheck data for the tracks. Now iTunes will calculate soundcheck data for tracks, however it’s all based on a per-track basis, which really sounds horrible if you’re listening to a continuous mix album. What you really need, is album level replaygain.

Again, foobar to the rescue, the replaygain functions of foobar will allow you to calculate the album replaygain. Unfortunately, iTunes doesn’t support replaygain, so I have to use mp3tag to convert the album replaygain data into iTunes soundcheck format.

This is further complicated by the fact that soundcheck data is stored differently if it’s a MP3 file, or an AAC/ALAC file. Luckly you just need to create an action, and add the two following rules:

Format value: COMMENT ITUNNORM
$if($eql(%_extension%,mp3),$rg2sc(%REPLAYGAIN_ALBUM_GAIN%),)

Format value: ITUNNORM
$if($eql(%_extension%,m4a),$rg2sc(%REPLAYGAIN_ALBUM_GAIN%),)

I’m a git at Git

Friday 27 April 2012, 19:18 WST

Korma is a SQL library for Clojure, one that I’ve started using at work (which you can probably pick up reading my previous posts). However, I’ve had some problems, one for example is the lack of support for HAVING.

However, Korma is hosted on Github which means that with a Github account I can fork and submit updates. So that’s what I’ve done, however, I’m used to Mercurial, and the workflow of Git is taking me a little getting used to. I’ve sent some pull requests, but I think I’ve made a bit of a hash of it.

So, it looks like that it might be a good idea for me to really start learning how to use Git. I figure that I really should be working on some more open source projects, etc, in an effort to improve my skills in preparation for the computer science course I hope to get into.

One of the reasons I like Clojure

Monday 02 April 2012, 21:02 WST

I’m pretty sure it was in The Pragmatic Programmer, where they have a tip that mentions “Delight your users”. This is also something that you need to keep in mind when your users are developers.

I’ve been working, on and off, updating our internal sales application at work, and I’m rewriting it using Clojure, I’m lucky enough to be in a situation where I can do this without practical issues about language choice coming into it. I’ve recently been trying to Korma library to do the SQL backend stuff.

I’m not doing anything too complicated, and I was just working on building up a basic select query, now what I wanted to do was call some SQL functions on fields that I’m pulling out, and I have to say that I’ve been pleasantly surprised by how easy Korma does this. In fact, I was expecting that this would not work and that I would have to find some way of getting the RAW SQL lines in the query where I wanted them.

The code is as follows:

(defn get-iso
  "Given an ISO number, return the ISO, this includes looking up the
  customer name, etc, but not any lines on the ISO."
  [iso-number]
  (select iso
          (with customers/customer)
          (fields [:ixIso :job-number]
                  [(sqlfn upper :sPurchaseOrderNumber) :purchase-order]
                  [:Customer.sCustomer :customer-name]
                  [:dtCreated :date]
                  [:bQuote :quote]
                  [:invoiced_at :invoiced-at]
                  [:sPublicNotes :public-notes]
                  [:sPrivateNotes :private-notes]
                  [(sqlfn coalesce :sDeliveryAddress :Customer.sDeliveryAddress) :delivery-address]
                  [(sqlfn coalesce :sDeliverySuburb :Customer.sDeliverySuburb) :delivery-suburb]
                  [(sqlfn upper (sqlfn coalesce :sDeliveryState :Customer.sDeliveryState)) :delivery-state]
                  [(sqlfn coalesce :sDeliveryPostCode :Customer.sDeliveryPostCode) :delivery-postcode])))

What I was surprised by was the sqlfn calls, using upper and then coalesce. (Actually I haven’t checked yet, but I think I need to put :Iso.sDeliveryAddress for the first parameters instead of :sDeliveryAddress, etc.) It just worked, I really thought that it would cause a problem, simply because I’ve had problems like that before. It gave me so much of a warm and fuzzy feeling that I wrote this blog post.

Isn’t that just great?

April 2014
M T W T F S S
« Oct    
 123456
78910111213
14151617181920
21222324252627
282930  

Other: