Friday, September 10, 2010

Usability Mnemonic: Map and Fetch

I read this and felt like the sum-up of each of Nielsen's heuristics into a single word was useful for memorization. I wrote down the first letters and jumbled them around a bunch until I found something that could be construed into a memorable phrase:

MMP RN FEDCH, 'map and fetch' - from this, I can remember:

memory
metaphor
prevention

recovery
navigation

feedback
efficiency
design
consistency
help

Just by going over this list a few times, I can keep these words in memory as the correct way to fill out the "map and fetch" letter list. Next up is keeping good associations with the words:

memory

don't make the user remember things; keep data visible

metaphor

bring real life metaphors and interactions into your designs

prevention

even better than good error messages is to keep errors from occuring. Prevent them.

recovery

Show a clear path to recovery; no codes, just step-oriented, precise information

navigation

The user should always be able to see how to get places; including an escape hatch

feedback

system status should always be visible

efficiency

put in just enough ui to use; make it flexible. Experts get accelerators, novices get ui

design

minimalist aesthetic - needless words compete with useful words for attention

consistency

keep your metaphors the same everywhere; don't make similar things act differently

help

searchable, step oriented, easy to find, easy to use, precise, detailed, available

I just wrote out paraphrases of nielsen's rules beside them - and in order to keep myself thinking about it a bit, I wrote this quick blogpost. Hopefully it's useful to someone else, too!

Monday, August 16, 2010

The Next Big Thing

Edited: Some HackerNews comments have prompted me to clarify that this was written with a sense of humour. The alleged 'pattern' of 2 little, 2 big was a joke, and the sensible expectation of persistence or new input/output technology just happened to fit with it. So I commented on it.

This article, The Web Is Passing Most Of You By... And You Are Asleep put my mind back onto the topic of what tomorrow's great tech fads that shape our world will be. It seemed prudent, at the time, to make a chart:

(click to see it a bit bigger, dumb blogspot)

The thing speaks for itself, generally. I chose the timeline to be every five years because it was easy, and it didn't seem too far off the mark for the rise of each of these technologies - in some cases it's closer than others. Paradigm is intended to be a one word description of the fad, be it product or idea. 'why' attempts to explain how that fad fit into society, again in a word, and then who is done in two categories, generally did big or little companies make this happen / profit from this fad, and then specifically what companies they were.

The letters are for reference to be briefly discussed here:

a: this is what we're trying to find out
b: this word will help us figure out a
c: a "pattern" of 2 big, 2 little seems to have emerged. I'd call shenanigans, but it does seem likely that a big company will be winner of the next major fad - if it's either of the fads I'm going to identify in a moment.
d: looking at the history of companies, if it's big, we can take some guesses
e: two steps in the future is worth thinking about, but predictions a decade out are like shooting a pistol at the moon
f: following the 2 by 2 trend from before
g: these are the people we want to be, if the aforementioned trend is an actual thing

Now, the two things I can think of are related; they both focus on one answer to b. I think the next word will be 'whole', 'full', or 'all'. The idea is that cell phones do not do everything laptops and desktops do yet, and should. They perform an excellent subset of what we need, but the winners in the next 5 years (I think) will be the ones who complete the experience and give us full functionality through our phones. There are a few key things that need to happen:

Input and output will change drastically. Tiny buttons don't cut it, and maybe touch screens are the shit but I think voice, gesture, and projection will be reaching a point soon that they'll exceed even apple's multi-touch magic. Just watch Pranav Mistry go (ted talk; you've likely seen it).

Coding on phones is a perfect example of an everyday task that's kind of ludicrous, due to input and output, but also due to synchronization. It just isn't worth the effort to a user of making a workflow persist between a larger machine and a phone yet. This leads to the second key thing, I call it persistence. It would be great if people would call it this, because it gets across the concept really well: your workflow or session persists while you transit between devices. Email and some chat programs have this already - web browsing has got it in a patchy fashion, but the rest of the computing experience has to come along too.

Size (physical and disk space), bandwidth, and cost restraints are also still in the mix, but they are second to input/output and persistence. Google and Mozilla seem to have done the most work so far in persistence, and MIT has all the best work on projection input/output systems. Microsoft has the money to catch up, and Apple has sufficient investment that it will need to keep up. It's moved in this direction already by trying to create a more complete, and yet mobile experience with the iPad. Apple seems to believe the answer here is a new form factor - maybe they've got it, but I think they're too early. If you wanted to, you could look at persistence as the final advent of "the cloud". It's about time.

If correct, this will leave us in 2013-2015 with new input schemes, new output schemes, and a lot of power to play with. Cue little companies to rush in and do interesting things, causing the next fad of 2020.

This is just fun conjecture, but it suggests that small facebook-killers like diaspora or next-googlers will not become juggernauts of the industry any time soon -- though it certainly does not bar them from success. The listed companies were just the ones that got into huge dominant positions from exploiting the fad of the day.

It also suggests that the coolest and most important work of the next 3 years will be done in big companies working toward these fundamental gains, and the next 6 years after that will be building the foundations of what we need to use this stuff well, and doing cool 'world-of-tomorrow' shit with it.

I'm excited, are you?

edit: added a chart filled with my assumptions, for the sake of visualization:

Sunday, July 25, 2010

A whole new world...

Well, not really. I've just added a lot to the tests. Codedump:
class World
def initialize(x_size=20, y_size=20, building_control=10)
remake(x_size, y_size, building_control)
end

def remake(x_size=20, y_size=20, building_control=10)
@x_size = x_size
@y_size = y_size
@building_control = building_control

@map = createMap
placeBuildings
placeRobot
end

def createMap
map = Array.new(@x_size)
map.each_index do |col|
map[col] = Array.new(y_size)
map[col].each_index do |i|
map[col][i] = " "
end
end
map
end

def display
@map.each do |col|
col.each do |i|
printf(i)
end
puts ""
end
end

def placeBuildings
1.upto(@building_control) do
placeObject("B")
end
# fills the world with buildings
end

def placeRobot
placeObject("P")
# puts Robot in a place where buildings aren't
end

def placeObject(string)
placed = false
while placed == false
x = rand(@x_size)
y = rand(@y_size)
if @map[x][y] == " " then
@map[x][y] = string
placed = true
end
end
end

def line_of_sight
# returns position of next visible object
end

attr_reader :map, :x_size, :y_size, :building_control
end
require 'test/unit'
require 'src/world.rb'

class WorldTest < Test::Unit::TestCase

@@x_size_list = Array.new(10) {|i| i+10}
@@y_size_list = Array.new(10) {|i| i+10}
@@building_control_list = Array.new(3) {|i| i+50}

def setup
@space_count = 0
@building_count = 0
@player_count = 0
@other_count = 0

@w = World.new(@@x_size_list[0], @@y_size_list[0], @@building_control_list[0])
end

must "properly set the x_size parameter" do
assert_equal @w.x_size, @@x_size_list[0]
end

must "properly set the y_size parameter" do
assert_equal @w.y_size, @@y_size_list[0]
end

must "properly set the building control parameter" do
assert_equal @w.building_control, @@building_control_list[0]
end

must "generate a 2D map" do
assert_equal @w.map[0][0].class, String
end

must "generate a 2D map to at least the specified dimensions" do
assert_equal @w.map[@w.x_size-1][@w.y_size-1].class, String
end

must "generate a 2D map not exceeding the specified dimensions" do
assert_raises(NoMethodError) do
assert_equal @w.map[@w.x_size][@w.y_size].class, String
end
end

@@x_size_list.each do |x|
@@y_size_list.each do |y|
@@building_control_list.each do |b|
# puts "#{x} #{y} #{b}: layout"


must "place #{b} buildings on size #{x} * #{y}" do
# puts "#{x}, #{y}, #{b}: buildings"
@w.remake(x, y, b)
count_map_contents
assert_equal b, @w.building_control
assert_equal b, @building_count
end

must "place #{(x * y) - (b+1)} spaces on size #{x} * #{y}" do
# puts "#{x}, #{y}, #{b}: spaces"
@w.remake(x, y, b)
count_map_contents
assert_equal ((x * y) - (b+1)), @space_count
end

must "place 1 player on size #{x} * #{y}, building control #{b}" do
# puts "#{x}, #{y}, #{b}: 1 player"
@w.remake(x, y, b)
count_map_contents
assert_equal 1, @player_count
end

must "not put any ambiguous spaces on size #{x} * #{y}, building control #{b}" do
# puts "#{x}, #{y}, #{b}: no ambiguous"
@w.remake(x, y, b)
count_map_contents
assert_equal 0, @other_count
end
end
end
end

def count_map_contents
@w.map.each_index do |col|
@w.map[col].each do |i|
if i == "B" then
@building_count += 1
elsif i == " " then
@space_count += 1
elsif i == "P" then
@player_count += 1
else
@other_count += 1
end
end
end
end
end


Sooo yeah. 1340 tests, 1640 assertions, 0 failures and 0 errors. I'm not sure whether I should do the line of sight/check code next or the linking code next, to pass the messages around. I'm betting the line of sight will be a lot easier, but it may have to change when I glue tings together - so I'm wary of pushing into it. Glad to get world into a good, test-passing state before I head to Ottawa for a week. I think I'd like to put something into the Hunters story over in Fiction, after I'm back. And keep learning physics -- and of course, finish off this robot game. It's good to design something small, to wean myself onto the process.

Sunday, July 18, 2010

Continuing with the ruby text game

Posting from Ubuntu 10.04 now, so I'm much more ready to use ruby properly.

I've made updates to my files, as shown here:

Rakefile:
require "rake/testtask"

task :default => [:test]

Rake::TestTask.new do |test|
test.libs << "test"
test.test_files = Dir[ "test/test_*.rb" ]
test.verbose = true
end
test/test_game.rb
require 'test/unit'
require 'test/extension.rb'
require 'stringio'
require 'src/game.rb'

class GameTest < Test::Unit::TestCase

command_list = ["left", "right", "forward",
"go", "back", "shoot", "pew",
"pewpew", "map", "look", "check"]

bad_command_list = ["up", "down", "north", "3", "go wildcats",
"wepwep", "a map", "map ", "go map"]

def setup
@input = StringIO.new
@game = Game.new(@input)
end

command_list.each do |command|
must "set the inputted command: \"#{command}\"" do
#puts "set the inputted command correctly when parsing #{command}"
provide_input(command)
@game.get_command
assert_equal @game.command, command
end
end

command_list.each do |command|
bad_command_list.each do |bad_command|
must "retain the command \"#{command}\" and fail to set \"#{bad_command}\"" do
provide_input(command)
@game.get_command
provide_input(bad_command)
@game.get_command
assert_equal @game.command, command
end
end
end

def provide_input(string)
remember = @input.pos
@input << string
@input.pos = remember
end
end
src/game.rb
class Game
attr_reader :command

def initialize(readin=STDIN, output=STDOUT)
@input = readin
@output = output
@command_list = ["left", "right", "go", "back",
"shoot", "check", "look", "pew",
"pewpew", "exit", "map", "forward"]
end

def get_command
temp_command = @input.gets
temp_command.chomp!
if @command_list.index(temp_command) != nil then
@command = temp_command
end
end

def loop
while @command != "exit"
get_command
puts @command
end
end
end
This has all gone rather well. Running 'rake test' gives:
(in /media/sda1/Users/wcarss/code/ruby)
/usr/bin/ruby1.8 -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/test_game.rb"
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
..............................................................................................................
Finished in 0.012626 seconds.

110 tests, 110 assertions, 0 failures, 0 errors
Excellent! Now that's out of the way...

What next?

We've got a game class accepting commands - I think it'd be pertinent to have a Robot who can receive them. A robot ought to have a position, ought to be able to take actions, and have a name. I figure that means making the files test/test_robot.rb and src/robot.rb

test_robot.rb:
require 'test/unit'
require 'test/extension.rb'
require 'src/robot.rb'
require 'matrix'

class RobotTest < Test::Unit::TestCase

directions = ["north", "east", "south", "west"]
base_pos = Vector[5,5]

forward_list = ["go", "forward"]
backward_list = ["back", "backward"]
new_pos = [Vector[0,1], Vector[1,0], Vector[0,-1], Vector[-1,0]]

def setup
@bot = Robot.new
end

directions.each_index do |i|
must "change direction to #{directions[i]} from #{directions[i-1]} on right" do
@bot.direction = directions[i-1]
@bot.right
assert_equal directions[i], @bot.direction
end
end

directions.each_index do |i|
must "change direction to #{directions[i-1]} from #{directions[i]} on left" do
@bot.direction = directions[i]
@bot.left
assert_equal directions[i-1], @bot.direction
end
end

forward_list.each do |command|
directions.each_index do |i|
must "move correctly forward when facing #{directions[i]}, using #{command}" do
@bot.pos = base_pos
@bot.direction = directions[i]
@bot.send(:"#{command}")
assert_equal @bot.pos, base_pos + new_pos[i]
end
end
end

backward_list.each do |command|
directions.each_index do |i|
must "move correctly backward when facing #{directions[i]}, using #{command}" do
@bot.pos = base_pos
@bot.direction = directions[i]
@bot.send(:"#{command}")
assert_equal @bot.pos, base_pos - new_pos[i]
end
end
end
end
robot.rb
require 'matrix'

class Robot
attr_reader :pos, :direction, :name, :score
attr_writer :pos, :direction, :name, :score

@@directions = ["north", "east", "south", "west"]

def initialize(name="Killbot 4000", x_pos = 0, y_pos = 0, direction="north")
@pos = Vector[x_pos, y_pos]
@name = name
@direction = direction
end

def left
@direction = @@directions[ direction_as_int() - 1]
end

def right
@direction = @@directions[ (direction_as_int() + 1) % @@directions.size]
end

def direction_as_int
@@directions.index(@direction)
end

def next_pos
angle = 90 * direction_as_int() * Math::PI/180
Vector[Math.sin(angle).round, Math.cos(angle).round]
end

def forward
@pos = @pos + next_pos()
end

def backward
@pos = @pos - next_pos()
end

def look
puts "Your windows are fogged!"
# not implemented
end

def shoot
puts "KABOOM (probably)"
# not implemented
end

alias back backward
alias go forward
alias check look
alias pew shoot
alias pewpew shoot
end
So, what on earth's going on here? Hopefully a lot of it is self-evident! The robot knows 4 directions, and I generated tests to check that left/right properly cycle through those. Then I generated a set of tests to check that, for every command, for every direction, the robot alters its position correctly. For example, if facing north using 'go', the robot should increment its y-position by 1. (I'm using north as positive, south as negative y, while west is negative x and east is positive x).

The bot itself is a little scattered for the moment - I'll collect private/public methods together next iteration, and I'm thinking I might make a "Direction" class, because a surprising amount of direction-logic had to go into the robot class. If I could just say the bot has a facing = Direction.new("north"), then print facing.to_s or .to_i, facing.left, facing.right, all these things - it would simplify the robot code tremendously. And it's all mostly done already!

Next after that I think is the World class, which will have a text-representation and some notion of simple buildings. From there I'm going to have to implement shooting stuff and looking around, which I think will involve line of sight, which I've never even really /thought about/, so it should be pretty cool.

OH! Actually, what I'll do next iteration is the following:

actually make the game loop send commands to the robot (haha, kinda important)
split direction into its own class with its own tests

then the one after that will be the world class / displaying the map

then like a half iteration should be all I need to make buildings blowupable and implement score. Sounds fun. :)

Thursday, July 15, 2010

Let's make a small text game in Ruby

Want to do some stuff with Ruby? So do I! I'm going to make a small text game, where you control a robot and blow up buildings.

So let's start by thinking about how the game will work. Pretty much, I want it to be command-line interactive and turn based. So you enter a command, and then something happens, and then you can enter another thing, and so on. You should be able to turn left or right and move forward and backward, and check what's in front of you. You should also be able to shoot.

I'm thinking sensible commands would be:

left
right
forward (maybe also go)
back
shoot (also pew or pewpew)
look (or check)

everything should be lower case for now. There'll be buildings randomly placed about, and when you are facing them and shoot, they should blow up. Maybe an extra command,

map

would be useful so you can see there's a building (demarcated by a B) somewhere, and a blown up building (demarcated by an X) somewhere else, and you the player, demarcated by a P. Later, I could make you be one of ^ v > < depending on your facing or something. A score for how many buildings you blown up would be neat too.

COOL!

So where do we begin? Well, if I want it to be interactive I'm going to have to have some kind of game-loop. I *could* just make this a game you play by issuing Class.command commands in irb or something, but that feels cheap. So it makes sense to me that I'd have some sort of controller class I'll call Game. I'm also going to need a Player.. or a Robot who moves around. Yeah, I like the thought of Robot being the thing that shoots. Then I'm gonna need Buildings, and a Map.

So, the Game will have a Robot, Buildings and a Map.
each Building will have a location and a status: either it exists or it doesn't!
the Robot will have a location, a direction, and maybe a name.
the Map will have to show the Robot and the Buildings, and eventually (I hope) the facing.

So let's get started already!!!

First, Iteration 1: Let's make the Game class and the main loop inside it, which will receive commands. What do we do now? That's right, we write some tests!

I'm going to lift some code pretty closely out of Ruby Best Practices here, because it does just about exactly what we want:
class GameTest < Test::Unit::TestCase
def setup
@commandlist = ["left", "right", "forward",
"go", "back", "shoot", "pew",
"pewpew", "map", "look", "check"]
@input = StringIO.new
@game = Game.new(@input)
end

commandlist.each do |command|
must "set the inputted command correctly when parsing #{command}" do
provide_input(command)
Game.get_command
assert_equal Game.command, command
end
end

def provide_input(string)
@input << string
@input.rewind
end
end
not having run this yet or ever done testing in ruby before, I have /no idea/ if this will actually work. Having written it though, I'm going to throw my Game class together (which now essentially writes itself)
class Game
attr_reader :command

def initialize(readin=STDIN, output=STDOUT)
@input = readin
@output = output
@command_list = ["left", "right", "go", "back",
"shoot", "check", "look", "pew",
"pewpew", "exit", "map", "forward"]
end

def get_command
temp_command = @input.gets
temp_command.chomp!
if @command_list.index(temp_command) != nil then
@command = temp_command
end
end

def loop
while @command != "exit"
get_command
puts @command
end
end
end
I don't have rake or rubygems on this computer, so I can't test this yet! I'll have to do so a little later - after a quick manual test of the Game class, it looks like it is in the right place. I realized while making it though, that I forgot to test that I'm not taking inappropriate commands! Fortunately I built it into the game class, and I'll modify the test soon to check for it.

Also of note, my directory structure at the moment:
/
/Rakefile
/src/
/src/game.rb
/test/
/test/test_game.rb
ah, and what exactly is in the rakefile? I've never used rake before! But again lifting from Ruby Best Practices (a fantastic book!), I've got
require "rake/testtask"

task :default => [:test]

Rake::TestTask.new do |test|
test.libs << "test"
test.test_files = Dir[ "test/test_*.rb" ]
test.verbose = true
end
And that's where I'll leave it for now. More later when I can actually run tests and find out all the things I've done incorrectly. :)

Friday, May 14, 2010

Corporations are re-enacting the histories of Nations

At least in some sense, Corporations and Nations are each large hierarchies of people that serve a common purpose. It's interesting to look at some recent corporate situations and see how far the comparison takes us.

Apple v Adobe

Apple and Adobe, founded around similar times by similarly minded people, have each grown spectacularly, and each hold very similar values. Recently, Apple decided that Adobe might have a bit too much control, and so decided to attack(No Flash, and Section 3.1.1, various written statements). Adobe has counterattacked in various ways (working around tech limitations, but mostly written statements), and the two could be said to be at war with one another. It's interesting to see how they manage to fight each other without spending lives, and while continuing to hold similar ideologies.

Google v China

Google is at war with China over ideology. One of the world's largest companies is fighting the government of the most populous nation on earth over what comes down to human rights. That a corporation can see itself as an adversary and competitor to an enormous (super?)power like China shows how much corporations are themselves like nations today.

Facebook v The People

Facebook is currently dealing with a revolt. The large-scale population of its users may or may not be aware of it, but a vocal minority is calling for the downfall of the site, and regularly publishing articles, studies, and anti-facebook propaganda, while organizing events designed to help get people to quit. I'm not particularly a fan of facebook myself, but it doesn't change the tactics that are being used. Facebook, a corporation, is at risk of being overthrown by its population and disbanded.

Conclusions

To my mind, there are at least three major corporate wars taking place in the tech world at the moment. There are classic rivalries like Coke v Pepsi, Nintendo v Sega (or Sony (or Microsoft)), acquisitions and annexations occur all the time, and corporations live their own lives as entities on a scale above our own, just as nations do, only corporations are borderless and have the ability to pivot themselves. Religious organizations may fit within this class of entity as well, and certainly wars and revolutions have occurred within them, but perhaps they are not as successful as the corporate being is, because there were by necessity so many fewer of them? Small population, small diversity, slow evolution?

Regardless of what my own spin is, living in a time where such tremendous conflicts as Apple v Adobe, Google v China, and The Facebook Revolt are taking place has me excited. The balances of power are shifting restlessly, and that means there's probably a way to gain advantage and come out with a lot of power.

Tuesday, April 27, 2010

Good work

Learned a lot about SDL in the last day or two. Making a tile-based game of some sort this evening. I'll get back with screenshots tomorrow.

Once I've got some experience, a Tetris RPG will be on its way (I've had this idea on a backburner forever waiting for a key concept to make sense that finally worked itself out in my head a few days ago)

Then I'll settle into drupal and wiki stuff, and see what I can do with a Wiimote.

Saturday, April 24, 2010

It's a reasonable thing to do

My last posts were correct, I suspect. One of my largest issues is that of distraction, and of a lack of focus. When I get focused, I can get into a fantastic groove (and produce excellent things quickly! Looking at you, lexical analyzer for pish I wrote in an evening), so the problem becomes getting focused.

My day-to-day activities have helped to breed a lack of focus in me. I switch contexts so frequently that it is now habitual. I wake up, check hackernews for articles, read a few sentences from an article, and then engage switching between MSN, email, getting ready for school, and reading whatever little bits of whatever article I go to when alt+tabbing or ctrl+tabbing around. This has left me switching contexts in places where it's not demanded, and not focusing in when that's precisely what I need.

So the question becomes, "how can I focus?". It may be something I need to learn, but again, how? My thoughts are that it comes down to the mental discipline to force myself to finish a task. If I am blogging (for example) and I decide I would like to watch the new episode of Lost today, or check out a book on my shelf, or read old blog posts, I must force myself to finish my task and then switch instead of just switching as soon as the thought occurs.

This is likely applicable at a larger scale. Getting a project off the ground, or getting a serious improvement to one's self going, takes a lot of energy, which is present in the early stages. As time progresses though, New Task Energy wears off and you want to switch to something more exciting. I've got to learn to be fuelled by Achievement Energy (when I've finished a task) instead of by the energy I get from having something new to work on. I've got to pick reasonable goals and work toward them, and not start new things until I'm done chewing what I've bitten off.

This summer, I have some hopes. I'd like to build two things minimally, and five things maximally:

compiler
code style switcher
3d drawing environment
zoomable code editor
knowledge map collaboration station

I'm not even certain which of those is toughest. I also want to do other things, like dissect some open source code and mess with it (particularly the Cube engine used in games like Sauerbraten) and learn some webGL/jQuery/drupal stuff, and then general stuff like math and science skills, etc.

So, knowing that these are the things I'd like to end up with, I should draft some goals, some critical paths to the goals, and see what seems reasonable. The things which have my attention most at the moment are the knowledge map collaboration station and the 3d drawing environment.

That said, my plan is to not be especially productive until I want to be. I'm going to watch television, sleep, play video games, and read until I'm very bored of doing these things (I predict just less than 2 weeks of slacking) and then to come out of it a masterfully productive sort of person.

The biggest point I need to make here is that once I've set these goals up, I can break down tasks for what I'd like to finish, but once I am in the midst of a task, I must perform it to completion. Working on something halfway and dropping out is how to not finish it. Once I start a thing, I will go until it's done. Then it just becomes a problem of starting.

Good luck, future me.

Sunday, March 28, 2010

Failure and success

Goals are coming along, but I didn't report back on Friday or even really start the phil paper. I'm working on it at the moment, finally picked up some steam.

Will report once it's a reasonable thing to do.

edit (many days later): post coming tonight

Wednesday, March 24, 2010

It's been a fun couple of months.

I am realizing that I need a framework for living - not as a ruleset, but as a guideline. One that permits failures, and has guidelines to return onto track.

Regularly, I'll have things to do, and I'll suddenly be really tired. Or really distracted. Or really want to do something else first (in one of those right now). Somehow I'm never getting to sleep on time, never getting home on time, never getting projects in on time, never getting to school on time. Never doing enough, always planning more than I can achieve.

This ultimately means that I'm less capable than I think. Whether that's because I lack the attention span or discipline to achieve what I would be ideally capable of, or because I set my sights far beyond even what I'm ideally capable of, I'm uncertain. What I am certain of is that I need to change, because I'm not in a good spot. There are too many deadlines approaching, too quickly, even after having made sacrifices.

So this is what my spare cycles will go into for the next while. Wait a minute, how can I have spare cycles with so much to do? Well that's precisely the problem. I feel like my programs aren't optimized to my hardware -- rather than packing 4 1-cycle instructions together for alignment, I've got empty space floating around and do nothing with it. So I'll make this my ambient thought-topic: what guidelines can get a person back on track, and keep them on track?

Off the bat, I see that I need goals. These goals will provide motivation and metrics, and from those I can set myself tasks and make plans. I can develop small heuristics to remind myself with whenever I suddenly decide "this'd be a great time to write a blog post", "I could hang out with Sophie later", or "man, I'm tired. Sleep is good for me -- I'll (stay asleep / go to sleep) even though I've got stuff to do."

Alright, hope I can stick to it even marginally. A first goal: report back on friday with some progress. A second goal: finish my philosophy paper this evening.

Wednesday, February 10, 2010

How I solve problems

I'm not really sure how I solve problems. What I'm betting though, is that I could improve my problem solving ability by paying attention to the process as I bumble through it. Maybe we all could. So let's define this with a touch of formalism.

Where I'm at

I have a problem to solve. I've got an existing program, and I need to make some changes to it to enhance its functionality. I must think that this is a hard problem, because I have procrastinated significantly on it, and every time I go to start it, I get a little lost.

The sense of being lost comes from a few directions.

1) There are multiple ways to solve the problem - some easier than others, but with hard to quantify costs of later complexity and code to rework.

2) The existing program is a hacked together mess.

3) I haven't really solved this problem before.

4) There are technical tools which would help with some of my possible plans for moving forward, but I am not certain that those are necessary or, more importantly, allowed.

Knowing this, I see my primary boundaries (and solutions to them) as:

1) I have a goal and a starting point, but no real hints about a transformation function to arrive there. I need to choose what path I'll walk along.

2) The existing program may be useful later, but for now, it must be disregarded. I'll see what I can salvage once I know how I want to do this. Note: this is easy, because the existing program is only a few hundred lines of C/C++ in a single file.

3) This just makes me a little less sure of myself.

4) I do not know enough about the limitations on the assignment to make good assessments for technology to use or to not use. It is unspecified in the design document which technology I cannot use. So, I'll just assume it's allowed unless we're told it's not. Within reason.

What next?

I need to choose a path, and that would be easiest to do if I just start working along a hypothetical path. I've been bogging myself down in the different possibilities at the start and not wanting to commit - well, I'll just start thinking my way through the beginning (and then the rest) in as high level a manner as I can. This is a problem well suited to a top-down design, and I know (from up above) that I don't have to keep much of my existing work.

So the next step is: draft out some plans.

Depending on the sort of work I'm doing, I like to make plans a variety of ways. I tend to work well by expressing things verbally, which means I like to talk through them. This is why I'm writing this blog post.

Next up, I want to do some more specific planning. Like code planning. But rather than pop open vim (where I'm fast when I know what I'm doing, and slow when I don't), or MSVC++ (where I'm constantly trying to think of how to do things better), I'll work on paper, with a pen. This will make diagramming (should I want to do it) faster, and help to free me from thinking about technical details for the moment. Right now I don't want technical details; I want high level organization, overall understanding, and to work through some math. Paper is the perfect technology for this.

But what I really have to do right now, is mark some students in a class I'm TAing, for the next three and a half hours. It'll be hard to work during, but hey, it's a living. :)

Monday, January 25, 2010

School's on

Entering week 3 of Semester 6, all looks well. The lineup for this semester:

CIS 4800: Graphics
CIS 4650: Compilers
CIS 3120: Digital Systems
PHIL 2100: Critical Thinking
PHIL 2370: Introduction to Metaphysics

The rundown for each of them:

Graphics

OpenGL and its associated helper libraries - pushing and popping matrices and gluing together random bits of code to make a game called Qix(beware the audio!), which is rather fun to play.

Compilers

Constructing a compiler to translate a Pascal-ish language (termed Pish) into MIPS Assembly. We're starting with DFAs and simplistic ideas of scanning, then walking forward through parsing, generating meaningful symbol tables, abstract syntax trees, intermediate code, register allocation, and machine code generation. It should be an awesome project to get through.

Digital Systems

Starting with CMOS networks of transistors to build basic gates and then gluing gates together to make a half-adder, then a simple 8 bit ALU, then a CPU with a data and control path. We'll be seeing the theoretical and practical side of digital design - touching on minimization of boolean expressions, hazard detection and reduction, designing for cost/speed/safety, and some neat things at the end about FPGAs and such.

Critical Thinking

A lot of hullabaloo about arguments. This is a course about using, identifying, and thinking about people's arguments in day to day life and an academic context. It's really the english half of symbolic logic (conversely the math half), which I took over a year ago. I'd better do pretty damn well in it.

Intro to Metaphysics

We read a bunch of old stuff and discuss it with the prof, basically. Good reading, good discussion, all about foundational and arguably (oh so arguable!) useless topics like identity, time, the structure of universe, and the nature of reality. Some smart people in there.

Also going to put my name in the hat for B. Comp Senator again, and.. yeah. Good semester, I think. (And hope.) (And a democamp this week! I will try to go!)