Some quick guidelines to Clean Code

I recently read Clean Code by Robert C. Martin, and here is a very summarized compilation of tips/principles that I understoo or found useful.

Naming

Names should convey correct meaning. (descriptive and correct)
Names should be pronounceable.
Names should be searchable.

Functions

Functions should be small, < 10 lines.
Functions should do one thing and do it well.
A function that takes 2 parameter is good. A function that takes 1 is better. A function that takes 0 is best.
Avoid flag arguments (i.e. Boolean values), it shows that a function does >1 thing.
Functions should not have side effects (i.e. do things other than stated in its name).

Comments

Avoid comments if possible, your code should be explanatory.
Good comments: explaining intent, clarification of obscure parts, amplification of seemingly unimportant parts, TODO, warnings.
Bad comments: redundant, misleading, journal.

Formatting

Small files are easier to understand than big files.
Newspaper metaphor: Headline -> Quick summary/Gist -> Details.
Use blank lines to separate different concepts.
Code that is related should be close together e.g. variable declarations in a loop.
Use white space between words to emphasize relation.
There are no laws for indentation, just set rules within the team and stick to them.

Objects and Data Structures

Objects hide data behind abstractions and expose functions that operate on the data.
Data Structures are containers for data and have no meaningful functions.
Avoid train wrecks (i.e. someThing().anotherThing().lastThing().orIsIt()).

Errors

Use exceptions instead of return codes, this enables separation of error checking and function logic.
Write try-catch statements first (in line with TDD).
Write Unit Tests.
Three laws of TDD:
1 – You may not write production code until you have written a failin test.
2 – You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
3 – You may not write more production code than is sufficient to pass the currently failing test.
Tests, like your production code, should be clean.
Single concept per test.

Classes

Classes should be small, just like functions.
Single Responsibility Principle (SRP), a class or module should have one, and only one, reason to change.
Classes should be open for change.

Good Designs (Rules by Kent Beck)

1 – Runs all the test
2 – Contains no duplication
3 – Expresses the intent of the programmer
4 – Minimizes the number of classs and methods

Successive Refinement

Advertisements

Quickview for YouTube

-UPDATE- My first user review on Chrome Web Store 😀

5-stars yay!

5-stars yay!

I released Quickview for Youtube on the Chrome Web Store last right, it was a really exciting 30 mins.

Beads of sweat trickling down my faces as I waited in anticipation for the zip file complete uploading, cursor hovering above the “Pubish now” button, as if I need to click it before it disappears suddenly. “Completed.” Within a split second I pressed my mouse left button as hard as I could and then it was live, on the Chrome Web Store. I would get millions of users and everyone would love what I did. But first let me see if it works. Bam. Reality strikes hard. I uploaded a wrong version. “Take it down, take it down” I told myself as I maneuvered what seemed like a labyrinth of links to finally reach the console where I could remove it. No way I was going to ship something that broken. Within minutes, things have turned out well.

Perhaps things weren’t that dramatic but it really was a unnerving experience publishing my first Chrome extension. But that night I did so, friends told me they are using it, liked it, and shared it with their friends. So I’m very happy they found it useful.

From a technical perspective, this extension is definitely not difficult. I had to learn bits about DOM, constantly refer to the jQuery API, check out Web Platform and the MDN; and I’m really glad there are so many great resources for anyone interested. I recently read a book called Clean Code by Robert C. Martin, and I wanted to apply some principles I learned, such as proper meaningful naming, and simple do one thing functions. It is not as DRY as I like it to be, so there’s lots of room for improvement.  While building Quickview, I had moments where I needed to decide which was the better way to do things. Here I learned something about trade-offs, such as clever-looking code v.s. maintainability.

I have a long way to go, but Quickview is definitely a small step, and hopefully in the right direction.

PS. Quickview is open-source.

10 Rules for a Productive Programmer

I just read The Productive Programmer by Neal Ford, and this is my takeaway:

10 Rules for a Productive Programmer.

Rule 1: Never do things your computer can do faster than you

This applies to finding files, launching applications.

Rule 2: Those who forget history are condemned to repeat.

Command history (Ctrl+R in bash), clipboard (in your editors), web history, macros.

Rule 3: Turn off needless notifications

Email/ does not need to be checked every 5 minutes.

Rule 4: Computers are for automation, use them.

If you notice yourself repeating some steps, automate!

Rule 5: Test

Testing makes you less fearful of changing things. It ensures that things always work. And it allows you to benchmark

Rule 6: YAGNI

(There’s no explanation here ‘cos YAGNI!)

Rule 7: Occam’s Razor

When given multiple explanations for something, the simplest is the most likely.

Rule 8: Law of Demeter

For any object or method, the only methods that should be invoked are:
– The methods of the object itself,
– parameters of the method
– any objects created within the method.

Rule 9: Question authority

The idea here is not revolting, but rather seeking explanations, for current processes and practices.

Rule 10: Use the perfect tool

The perfect tool is the one you know best, so find one that satisfy your requirements, use it, learn it inside out and master it.

What I learned about fonts

I started on this because I wanted to use unicode characters for LemonBoy’s bar. I wanted to display funky symbols without installing a new font, so I decided to use Dejavu Sans Mono to display them.

I had to get bar to find my font, and that is the gist of this post. In X, a font is specified in a funny way. Here’s an example:

-misc-dejavu sans mono-medium-r-normal--17-120-100-100-m-100-iso10646-1

Most of the time though, we will not need to be so specific, can this will do:

-*-dejavu sans mono-medium-r-normal--17-*-*-*-*-*-iso10646-1

If you’re as curious as me you’ll probably want to find out what all those numbers as me, and if you’re as stupid too, you’ld probably spend an entire afternoon finding out.

If you’re just interested in the answer jump to the bottom, ’cos I will be going though steps to find this information yourself.

  1. xlsfonts is is the server font list displayer for X (man xlsfonts) This is the most crucial thing we need. Get it from your distribution’s package manager, I’m on arch so I just had to

pacman -S xlsfonts

  1. skim through

xlsfonts --help

  1. try this:

    xlsfonts

You should see a bunch of fonts displayed similar to what I showed you above.

  1. If you have DejaVu Sans already installed you can probably try this:

    xlsfonts -l -fn -misc-dejavu sans mono-medium-r-normal–17-120-100-100-m-100-iso10646-1

Make sure you type the backslash as well, you have to escape the spaces.

  1. If not you, pick a font from the list generated by xlsfonts, and do:

    xlsfonts -l -fn -the-font-you-picked-some-numbers-blah-blah111

Or if you’re lazy to type we can just select the first font in the list:

xlsfonts -l -fn $(xlsfonts | head -1)
  1. Now thats not very interesting, a bunch of short cryptic headings, so lets try this:

    xlsfonts -ll -fn $(xlsfonts | head -1)

Note the 2 l’s this time. So this gets much more interesting, lots of information, not that difficult to understand. Most are self-explanatory, such as direction, rows, columns. To go more in-depth, try these search terms: character encoding, character map, fonts in x.

  1. Now things become clearer, lets separate the full font name by hypens, and match them to the properties in the output:
misc FOUNDRY
dejavu sans mono FAMILY_NAME
medium WEIGHT NAME
r SLANT
normal SETWIDTH_NAME
ADD_STYLE_NAME
17 PIXEL_SIZE
120 POINT_SIZE
100 RESOLUTION_X
100 RESOLUTION_Y
m SPACING
100 AVERAGE_WIDTH
iso10646 CHARSET_REGISTRY
1 CHARSET_ENCODING

SLANT has to do with the italics, r stands for Roman, there is also o for Oblique. Mystery solved! I don’t know what every property means, but I guess you can probably find out if you want to

This worked for bar, with the specific full font name. I also learned that the PIXEL_SIZE and POINT_SIZE should not both be set at the same time. For example, looking at the information above, you can set PIXEL_SIZE and POINT_SIZE to 17 and 120 respectively, but 12 and 120 will fail.

I suppose this has something to do with font rasterizing, so setting one will optimize the other for you. As such I chose to fidget with PIXEL_SIZE and leave POINT_SIZE as *.

What I’m using now is this:

-misc-dejavu sans mono-medium-r-normal--11-*-*-*-m-*-iso10646-1"

Which ensures that I get the correct font family, weight, encoding, which I guess are the most important parts, just leave the rest to the computer!

Notes: xlsfonts has a -lll flag to, shows you every character in the font, pretty crazy and useful at the same time! And guess what I think I’ll be back to stlarch so it looks so much better.

Udacity CS 212: Learning more

A new toy we can play with, itertools.

The module itertools include methods to build iterators effectively. Its pretty hard to understand this description from the Python documentation, so we’ll just look at some examples from the website:

repeat(1,5) # object representing (1, 1, 1, 1, 1)
imap(func,(1,2,3),(4,5,6)) # object representing (func(1,4), func(2,5), func(3,6))
product('ABC','xy') # ('Ax', 'Ay', 'Bx', 'By', 'Cx', 'Cy')
permutations('ABC', 2) #('AB', 'AC', 'BA', 'BC', 'CA', 'CB')
combinations('ABC', 2) # ('AB', 'AC', 'BC')

Do remember to import itertools and prefix every method you want to use with itertools.

A very important concept to know is list comprehension.

[s for r,s in cards if s == 'H']
# this has the format [(term) for (for clause) ...optional if and for clauses]

The expression above is basically the same as the block below:

result = []
for r,s in cards:

if s == 'H':

result.append(s)

The benefits of writing list comprehension is that it is simple to add more for and if conditions, just add it to the back of the line. The entire list comprehension is read from left to right, ignoring the first term.

A very similar concept generator expression.

The format of a generator expression is very similar to that of a list comprehension:

g = (s for r,s in cards if s == 'H')

Note the differences, using parentheses instead of square brackets. A generator does not evaluate the expression in the parentheses when you first assign it. Instead it represents a generator object, which is sort of like an understanding that g will evaluate the expression when called to. So the way to ask g to start evaluating is next(g). This will get the first s (since it is still on the 0th place as g has not started to evaluate. The next of 0th place is the first term)

A simpler way to iterate through a generator to print out every term in the expression is:

for i in g: print i

This ensures that you will not iterate through the end of g (by manually calling next), which will cause Python to throw a StopIteration error.
Alternatively, you can convert the expression into a list using list(g), this will return a list containing each term of g as an element.

A cool looking thing *args

You usually see *args in definitions:

def something(fn, *args):

fn(*args)

In the definition, *args means that the function can take any number of arguments, and all the arguments should be joined together into a tuple called *args.
And when it appears in the block, it means to unpack the tuple, and apply the function fn to all the elements in the tuple.

The interesting thing to note here is that functions can be passed around as arguments, like strings and integers. So we are able to decide when to execute the functions, which is useful to checking how long a particular function takes to run, by calling time.clock() once before running, and again after running.

This Udacity post references Udacity CS 212 Unit 2.

Udacity CS 212: Starting out

I’m already halfway through CS 212 (today is day 2 of starting), and have learned so much more! Below I will document some new knowledge of Python I have gained.

First we start of with a new data type, tuple.

Tuples are constructed using parentheses, and contains items separated by commas, similar to lists. For example (1, 2, 3) is a tuple.
Tuples are also non-mutable, which means that like strings, once a tuple is created, you will not be able to modify the entries in the tuple.
A tuple and a list is similar in that they both below to a type of data called Sequence Type, and hence many methods which are available for lists can also be used on tuples:

x in tuple
x not in tuple
tuple[0] # first item in tuple
len(tuple) # number of items in the tuple

Additionally, I learned new methods which are available to both list and tuple types:

min(tuple) # returns the smallest item in tuple
max(tuple) # returns the largest item in tuple
tuple.index(i) # returns the index of the first occurrence of i in tuple
tuple.count(i) # returns the number of occurrence of i in tuple

Next, I learned another new data type, set, which is an unordered collection of distinct objects.

Continue reading

Udacity CS 101: Unit 7

I sped by Unit 7 really quickly, in about 2 hours. The videos were really interesting, introducing you to some history of computers, open source software, companies with social improvement goals, and university students with their projects! Right now whats left is the Exams. And we probably can’t discuss that! So I guess its the end of CS 101 for this blog! Its been a quick but fruitful journey, and I hope what I documented here will be helpful to some of you. I’ll be moving on to CS212, which began 3 weeks ago. Time for some catching up!

This Udacity post references Udacity CS 101 Unit 7.