Sunday, December 15, 2013

How to flash Samsung Galaxy Nexus with the latest factory image

I was running CyanogenMod on a Google/Samsung Nexus Galaxy and decided to go back to the stock Google image from the Factory Images for Nexus Devices page. The latest factory image for the Galaxy Nexus is 4.3 (JWR66Y).

Make sure to download the correct image for your Nexus phone. In my case it's "yakju" for the Galaxy Nexus "maguro" (yakju-jwr66y-factory-09207065.tgz).

I downloaded the yakju archive and extracted the .tgz with 7za:

cd \temp
curl -k -O https://dl.google.com/dl/android/aosp/yakju-jwr66y-factory-09207065.tgz
7za x yakju-jwr66y-factory-09207065.tgz
7za x yakju-jwr66y-factory-09207065.tar
cd yakju-jwr66y

I wanted to see if I had the Samsung driver installed on my Windows 8.1 laptop:  Go to Device Manager:


So, no clearly I didn't have the driver for the phone yet: Device Manager shows the Nexus phone as "Unknown USB Device (Device Descriptor Request Failed)".

At this point, I decided to put the phone into fastboot anyway and see if I could flash the factory image without the Samsung driver (hint: no, it didn't work):

To use adb.exe and fastboot.exe, I just used the Android SDK in my Android Studio installation. I added the sdk/platform-tools folder to my PATH and put the device into fastboot mode:

set PATH=%PATH%;D:\Android\android-studio\sdk\platform-tools
adb reboot bootloader

Now the phone is in fastboot mode (while in "fastboot mode" you can "flash" the Android firmware, i.e. modify the system image / operating system):


However, as I feared, fastboot.exe couldn't see the phone, because the Samsung driver wasn't installed, i.e. when I ran  "fastboot devices" no devices were listed. While in fastboot mode, Device Manager now shows the phone as "Other Devices" -> "Android 1.0":


I downloaded Samsung_USB_Driver_for_Mobile_Phones_v1.5.14.0.exe from Samsung's website. 

During the process of installing the Samsung USB driver I had to reboot my Windows 8.1 a few times (and I also had to take the battery out of the phone once to get it out of fastboot mode because the phone seemed to hang).

I right-clicked on the "Android 1.0" device and clicked "Update Driver Software...". Then I selected "Let me pick from a list of device drivers on my computer" and then selected the "SAMSUNG Android Phone" from the list:


And on the next screen I selected "SAMSUNG Electronics Co., Ltd." ->  "SAMSUNG Android ADB Interface":


Windows confirms that the Samsung driver is installed OK:


After updating the "Android 1.0" device's driver to "Samsung Android ADB Interface", Fastboot now shows the device:

C:\temp\yakju-jwr66y> fastboot devices
0356B9BB0201A005        fastboot

Now run flash-all.bat from the downloaded factory image folder. That's it! That batch file runs fastboot.exe a few times to install the new factory image. Now Android 4.3 is installed successfully on the Nexus phone.

Monday, December 09, 2013

Keep it simple

I was browsing around on the Quantified Self website and saw these nice easy tips / lessons learned on QS, but clearly these are 100% applicable to software development (and practically any aspect of life). They are pretty obvious points, but worth reminding yourself of now and then, especially when you're as easily distracted as I am :-)
  1. Something is better than nothing. Engaging yourself in some experiment, no matter how flawed it may be, is better than never starting. The best way to learn is to do. So go out and do something!
  2. When you decide to start something try and do the simplest thing that you think might give you some insight. It’s great to have ambitious ideas, but keeping it simple ensures your experiment is manageable.
  3. Mistakes are worthwhile. Some of our best knowledge comes from learning from our failures so don’t be afraid of failing. By keeping it simple you also keep the mistakes small and manageable.
  4. Seek help from others.

Monday, November 25, 2013

Ireland English dictionary for the non-Irish

Random musings on living in Ireland:

As a South-African who's been living in Ireland for over 4 years, let me show you some of the Irish lingo (I think) I've learned so far. Please feel free to add/correct as necessary.

First the Irish-English phrase and then the "international" English phrase would be understood by South-Africans and Americans alike (I would hope).
  • It's half eight = It's half past eight.
    • This one I especially used to find confusing because in Afrikaans the direct translation "half agt" actually means the equivalent of "half to eight" i.e. "half past seven".
  • What's the craic? = Hey, what's up?
  • What's the craic and all? = Hey, what's up? (as said by an Indian living in Ireland - hi Ramesh :-)
  • Just call in to pick it up. = Just come in and pick it up. (I still keep falling for this one and actually CALL people on the phone, only to discover I didn't have to call but only have to call in, duh!)
  • evening = afternoon
    • example: Yesterday evening I worked on...
    • translation: Yesterday afternoon I worked on...
  • Did you enjoy that dinner? = Did you enjoy that lunch? (I think 'supper' is reserved for 'dinner'..?)
  • Do you want to come over for tea? = Do you want to come over for dinner? (Not sure about this one...?)
  • Runners = tekkies (South-African), sneakers (American)
  • Pants = underwear / underpants
  • Cheers! = Thanks! (Not 'bye'!)
  • So I told yer man = So I told the guy
  • Jumper = Jersey
  • Are you dosed? = Do you have the flu?
  • I'm wile dosed = I'm very sick
  • Bap = bun (bread)
  • At the minute = At the moment
I admit that some of these might not necessarily be purely Irish words/phrases but may be influenced by British-English, which is possibly slightly closer to South-African English, but not quite. I'd say South-African English is, when spoken, perhaps the closest to US-English (but closer in spelling to UK-English).

Also, just a silly story to add:

I've been in love with Ireland my whole life, so on previous occasions (before moving to Ireland) I've bought some Irish wool caps and a very nice (and expensive I want to add) jersey. Then we moved to Ireland in 2009. I got a little book about Ireland and Irish culture. In this book I learned about the concept "More Irish than the Irish"... I realised that if I wore my Irish-made wool cap, which I bought in the same county that I live in now, but years ago (around 2000 or so), then I'll just seem like an idiot tourirst who's trying to look Irish. For the same reason I'm reluctant to wear any Irish-branded stuff (like a nice Ireland t-shirt I also bought years ago) for the fear of looking like a silly foreigner trying to look Irish :-)

I must admit, occasionally when I visit a neighbouring town in Donegal, and a shop-keeper doesn't understand my weird accent, it is convenient to pretend that I'm just visiting from SA. It does get weird when you keep pretending to be a visitor from SA every time you visit the same store though (like that from the lovely Mr. McGinty's in Donegal Town - hi Mr. McGinty, I love your shop, but I've bought lots of stuff from your shop over the years and I expect a discount next time... haha ;.)

Sometimes when people in Letterkenny don't understand this crazy unfamiliar accent, they assume that I'm Polish. Not sure why. In the US people thought I'm either Scottish or Australian...?

I hope this post doesn't cause any offense to the occasional Irish or Western-European visitor :-)

Friday, November 22, 2013

The correct way to read a text file in Python

When you search for examples of reading a file on the web, most examples you see show:

with open('file') as f:
  text = f.read()

But it's quite hard to find examples of the "correct" or "proper" way to read text files in Python. Of course correct/proper is a matter of opinion and depends on what you're trying to accomplish. In many cases you really want to slurp the full file into memory as above, but in my case I more often need to process one line at a time (perhaps in conjunction with a generator), in which case this is what I need:

with open('file') as f:
  for line in f:
    yield line

Not to mention that you'd deal with binary files in a different way as well...

Friday, November 08, 2013

Automated install of PowerShell on Windows XP

The problem: I want a batch script to perform an unattended/silent install of PowerShell on Windows XP.

We need to download the PowerShell installer from Microsoft, but it needs to be downloaded from an HTTP server. I'm not aware of an easy way to download files from the command-line or script in Windows XP, other than the FTP command. But what we can do easily, is to download cURL via FTP first.

So we need to download 4 things from the batch script:
  1. We need to get 7-Zip to extract cURL.
  2. We need to get cURL (or wget) to download PowerShell.
  3. Download and install .NET Framework 2 since it's required by PowerShell.
  4. Finally we download PowerShell itself from Microsoft via HTTP.
Step 1: download 7-Zip archiver's command-line version (7za.exe) from an FTP server. You need to search for any FTP server that hosts 7za.exe.

This FTP script would work to get 7za:
open ftp.cadwork.ch
user
anonymous

cd /DVD_V17/CADWORK.DIR/COM/
bin
get 7za.exe
Step 2: download curl from one of the official FTP mirrors if you can. I didn't have any luck with the official mirrors so I just searched around until I found an older version.

This FTP script would work to get curl 7.19.3: 
open ftp.gr.freebsd.org
user
anonymous

cd /pub/net/ftp/curl/
bin
get curl-7.19.3-win32-nossl.zip
Now we can use 7za.exe to extract the curl zip file.

Step 3: download .NET Framework 2.0 and install it silently:
curl -O http://download.microsoft.com/download/c/6/e/c6e88215-0178-4c6c-b5f3-158ff77b1f38/NetFx20SP2_x86.exe
start /wait "Installing .NET" NetFx20SP2_x86.exe /qb
Step 4: download PowerShell for Winfows XP and install it silently:
curl -O http://download.microsoft.com/download/E/C/E/ECE99583-2003-455D-B681-68DB610B44A4/WindowsXP-KB968930-x86-ENG.exe
start /wait "Installing PowerShell" WindowsXP-KB968930-x86-ENG.exe /passive /log:powershell-install.log
The final batch file to put it all together is here.

If you're curious why I'd be using Windows XP: I sometimes need to test old software. In this case, I want to install Visual C++ 6 to see if some old C++ code compiles without warnings before I start the process of converting it to a newer Visual Studio.

Note: I used FileWatcher.com to search for FTP servers that host the 7-Zip command-line tool (7za.exe) and cURL.

Tuesday, October 29, 2013

Automating software installs

This is my favourite software development topic: automating installs.

I'm a lazy programmer, in the sense that Larry Wall talks about when he says laziness is one the three great virtues of a programmer: that means I hate doing things manually over and over again. I'd rather spend an hour writing a script to download and install a utility, then doing it manually many times on multiple machines. Automating the installation of tools also has some other benefits: (a) it ensures the consistent replication of environments and (b) it serves as documentation of exactly what was done for future reference.

Nowadays I make a lot of use of virtual machines (mostly using Hyper-V recently) for my development on Windows. This allows me to easily delete VMs and start over as often as I like. It also means I can keep my development environments separate: e.g. one VM for Java/Eclipse, one for an older version of Visual Studio, one for playing with Ubuntu, etc.

When you install a lot of development environments over and over, you need to be aware of the different tools available to help automate things. In the Linux world, automated/unattended installs are the norm (using things like apt-get), but in Windows it takes a bit more effort to automate the installation of applications.

Here's a few ideas for installing utilities/tools from the command-line (i.e. from scripts):
  • Chocolatey - very cool tool to install lots of popular applications with a simple command like: cinst notepadplusplus
  • Ninite - Pick the applications you want to install and it generates a single installer to package them all.
  • DISM.exe - a Windows tool to Enable/Disable Windows Features from the command-line. Use this to enable things like IIS or Hyper-V from a script.
  • WebPICmd.exe - Microsoft Web Platform Installer - install certain products like SQL Server Express from the command-line.
  • In some cases it's easy enough to just write your own customer silent installer for a product. A lot of applications use InstallShield or other well-known installers and a lot of them behave the same way, so it's usually possible to figure out which command-line parameters to pass to the installer to do an unattend/silent install.
In addition to the above tools, you obviously need to be comfortable writing scripts of some sort. In the old days, I used to use Perl for all of my scripting needs. In recent years I've done more plain Batch files and some PowerShell. PowerShell is great because it's so ubiquitous on Windows systems, but it does have a steep learning curve in my opinion. I'm currently trying Python as my primary scripting language instead of plain old Batch files.

Using Chocolatey:

As an example of using Chocolatey on Windows, let's install the first two tools every developer needs on their machine: cURL and the 7-Zip Command Line tool for extracting archives from the command-line:

First, install Chocolatey itself (requires .NET Framework 4.0 to be installed) and then we use cinst to install curl and 7za:
C:\> powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin
C:\>
C:\> cinst 7zip.commandline
C:\> cinst curl
And that's it!

Using Web Platform Installer (webpicmd):

Let's install webpicmd with Chocolatey and then we'll install IIS Express using webpicmd:
C:\> cinst webpicmd
Now list all packages matching "IIS":
C:\> webpicmd /List /ListOption:Available | findstr "IIS"
From the above we see that we're looking for the package called just "IISExpress", so install it:
C:\> webpicmd /Install /Products:IISExpress /AcceptEula
Using PowerShell to install utilities:

Now, for contrast, let's say you've got a clean Windows 7 machine and Chocolatey won't work yet (because the .NET framework ins't installed), then it's easy enough to roll your own automated installs of 7-Zip and cURL using PowerShell. Once we have 7za and curl, this bootstraps everything: next we can easily script the download and install .NET Framework and Chocolatey...

To download 7-Zip command-line version (7za) and extract it using PowerShell:
function Unzip-File
{
    param ([string]$zipFile, [string]$destFolder)
    New-Item -ItemType Directory -Force -Path $destFolder
    $shell = New-Object -Com Shell.Application
    $zip = $shell.NameSpace($zipFile)
    $shell.NameSpace($destFolder).CopyHere($zip.Items(), 16)
}

Write-Host "Installing 7-Zip Command Line (7za)..."
$dest = "$env:ProgramFiles\7-Zip"
$destFile = "$env:ProgramFiles\7-Zip\7za.exe"
if (!(Test-Path $destFile))
{
    Write-Host "Downloading 7za..."
    $wc = New-Object Net.WebClient
    $url = 'http://downloads.sourceforge.net/sevenzip/7za920.zip'
    $file = "$env:TEMP\7za920.zip"
    $wc.DownloadFile($url,$file)
    Write-Host "Unzipping to: $dest"
    Unzip-File $file $dest
    Remove-Item $file
}
else
{
    Write-Host "7za already installed."
}
Next, let's download cURL and copy it into the Windows directory (because it's a single file and then it's already in the PATH for easy use):
function Unzip-File
{
    param ([string]$zipFile, [string]$destFolder)
    
    $7z = "$env:ProgramFiles\7-Zip\7za.exe"
    if (Test-Path $7z)
    {
        $info = New-Object Diagnostics.ProcessStartInfo
        $info.FileName = $7z
        $info.Arguments = "x -y -o""$destFolder"" ""$zipFile"""
        $info.Verb = "runas"
        $proc = [Diagnostics.Process]::Start($info)
        $proc.WaitForExit()
    }
    else
    {
        $shell = New-Object -Com Shell.Application
        $zip = $shell.NameSpace($zipFile)
        $shell.NameSpace($destFolder).CopyHere($zip.Items(), 16)
    }
}

Write-Host "Installing cURL..."
$wc = New-Object Net.WebClient
$url = "http://www.paehl.com/open_source/?download=curl_732_0_ssl.zip"
$file = "$env:TEMP\curl.zip"
$wc.DownloadFile($url,$file)
Write-Host "Unzipping to: $env:windir"
Unzip-File $file $env:windir
Remove-Item $file
Now download the .NET Framework 4.5.1 using cURL (of course you can download it with PowerShell as well, but I like to use cURL):
C:\temp> curl -L http://go.microsoft.com/fwlink/?LinkId=322116 -o c:\temp\NDP451-KB2858728-x86-x64-AllOS-ENU.exe
C:\temp> NDP451-KB2858728-x86-x64-AllOS-ENU /q
Resources:

Wednesday, October 23, 2013

Parenting: guilt when your child follows in your footsteps

Tonight my daughter, Emily (5 in a few months) called me and told me she can't sleep because she can't stop thinking about something even when she tries to think about something else. She asked: "Pappa, how can you stop your brain from thinking about something?" I replied: "It's very difficult to stop your brain from thinking! I know what you mean. I also find it difficult to stop thinking about things sometimes."

I was a bit scared to ask what it was that she was trying not to think about.

So tried to explain to her a technique I've been using for many years to fall asleep. I do it almost every night. I think I may have read about it (at least in some form or another) from a book about lucid dreaming by Stephen LaBerge when I was probably around 16 years old. It works almost every time, except when I'm really struggling to sleep, such as when I wake up in the middle of the night and start worrying about random stuff (in that kind of situation the only way to get rid of the anxiety is to get out of bed and watch tv or read for a while until I feel really tired). The idea is to think about (focus on) one part of my body at a time, making sure my body is totally relaxed. I start focusing on my left foot: is my foot totally relaxed? OK, move on: is my left leg totally relaxed and flat on the bed? Next leg. Then my lower body. Etc.

Emily seemed unsure whether she'd be able to do that, but she said she'd try.

Then I dared to ask: "What is it that you're trying not to think about?"

And it was what I thought it might be. She suddenly visibly tried not to cry and said: "I think about how I'm playing outside the classroom by myself. And then I look around and there is no one to play with."

My heart sank, because my wife and I have been talking about exactly this every day for the last few days. My wife recently discovered that our daughter is not as popular at school as we had assumed for some reason: my wife went with Emily to a classmate's birthday party a few days ago and realized that all the other kids were playing together and apparently didn't even seem to know Emily. I kept telling my wife she was worried about it for no reason, because as long as Emily doesn't see it as a problem, then there is no problem, because she's still young and lots of time to make friends.

However, the problem is: Emily has obviously been noticing that she hasn't got friends at school and it clearly bothers her a lot.

I told Emily: "Don't worry, once other kids get to know you, you'll make friends." She said: "The other kids do know me."  I said: "OK, I'll tell you a trick: look for another kid who is also playing by themselves, even if it's a boy, then go to them and ask if you can play with them. Ask them lots of questions, like what games they like to play, what shows they like to watch, what food they like, and then see if they want to play with you. If not, don't worry, just keep doing that. And one day, you'll have lots of friends!"

The topic has been so active on my mind that just this morning I asked my son's (3) teacher Patricia, when dropping  him off at preschool, if he's making friends. She said he's making lots of friends, and he's one of a band of about 5 boys who are apparently always playing together. So at least he's doing well socially.

The reason this has been a fear for us: my wife and I haven't really been the best examples. Not to mention whatever influence our introverted genes might have had on the kids. And living in a new country where we have no friends or family certainly doesn't help either.

In my childhood days I never had any friends at school until I was 13. It never bothered me the least bit. I liked being by myself. But it is really sad when the story seems to repeat itself with Emily, and I have no idea what we as the parents can do about it.

Monday, October 21, 2013

Do not design for reuse - design for loose coupling

I came across this cool line today:
"It can be better to copy a little code than to pull in a big library for one function."-- Go at Google by Rob Pike
Nowadays we keep hearing about all the virtues of code reuse, so much that it's almost becoming unheard of to question it. People may look at you funny when you suggest that some DTO class should be a separate class even though it happens to contain all the same properties as an existing model class.

It can be difficult to determine where to draw the line, but remember: just because two classes happen to look the same doesn't mean that it is necessarily the same thing. Sometimes copying & pasting is better than reuse e.g. using inheritance.

Reuse means coupling (or a dependency) when there is no need for that dependency.

I've always like this OOAD 101 blog post about coupling and cohesion:
"DO NOT design for reuse. Design for loose coupling, high cohesion. Do that and reuse will happen on its own."
Also see: Is code reuse a lie?

Wednesday, October 16, 2013

Mac OSX Keyboard Shortcuts

If you're a Windows user and new to Mac OSX, like me, here are some useful keyboard shortcuts and other tips:

Key Action
+space Quick search for an app or file to open
+tab 'Alt Tab' to another application
+` To 'Alt Tab' between windows of the same app (e.g. another Chrome window)
+control+shift+4 Select an area and take screenshot to clipboard
+shift+4 then space Click on a window to save that window to a file on the Desktop
⌘+option+esc Force quit applications

If you're using Remote Desktop Connection to connect to a remote Windows machine:

Key Action
+` To 'Alt Tab' between windows within the same app e.g. to another dialog window
fn+option+F1 Windows key (Start menu)
fn+option+F1+R Run dialog

You can configure your keyboard shortcuts in the Preferences of the Remote Desktop Connection application:

Also see:

Monday, October 14, 2013

Free private Git repository on TFS

You know GitHub of course, but it's not free for private repositories. Another nice option is BitBucket by Atlassian, which supports Git and Mercurial.

In this quick post I'm going to show you an option you may like especially if you're doing work in Visual Studio (like .NET/C#).  Not many people seem to know that Microsoft has a free Git hosting option called Team Foundation Service. This is basically a free online/hosted version of the TFS that we all know and love. (A bit of sarcasm there. Maybe.) The online TFS supports up to 5 users in your project for free.

Go to tfs.visualstudio.com, log in with your "Live ID" (like Hotmail/MSN/Outlook email address), and choose your own subdomain under .visualstudio.com. Create your new Git repository, 'test' in the example below.

When you're just starting with your new repository, initialize the new repo:
git init
Let's create our first file in the new repo:
echo '# Welcome!' > README.md
Now see what's going on in our repo:
git status
This shows us that we have the new README.md file as an "untracked file". Let's add the new file:
git add .
If you want, do a git status again, and note that the file is now added and new. 
Next, commit the change:
git commit -m "Initial commit"
Add the remote server called 'origin':
git remote add origin https://myname.visualstudio.com/DefaultCollection/_git/test
Now upload your newly created repository:
git push -u origin --all
(Note that your username and email address defined in your global git config is what will be displayed when you commit changes to this Git repo. This may perhaps be different from your TFS login, which is not necessarily what you want. So just make sure to check your config if you're using multiple Git accounts.)

Now add your friends to your private repo, and then they can clone the repository:
git clone https://myname.visualstudio.com/DefaultCollection/_git/test
Also see:

* SourceTree (Very good GUI for Git by Atlassian)
* GitHub for Windows client (also useful to get the PoshGit shell which is nice for command-line work)
* To create a new Git repository from Visual Studio, see: Publish your code into Team Foundation Service

Wednesday, October 02, 2013

Good development team practices

Some good software development practices:

Automate everything.

It often takes much longer to automate a small task than just doing it manually. I don't know about you, but I hate doing the same mundane task over and over. I admit, it's sometimes possible to take it too far as well. Yesterday I easily spent at least 30 minutes creating a single line cURL command for downloading JDK 1.4 from the Oracle Archive Download site.

Automation also serves as documentation. When you write the steps for installing some utility in a script, then you don't need to explain to another developer later what needs to be installed. Just read the script to see what's needed.

Remember that there are lots of existing tools to help automating things, like NuGet and Chocolatey.

Consider choosing a standard scripting tool like PowerShell or Python for everyone in the team to use. You can do a lot with just plain old batch files too.

At a very minimum, please, please don't do your builds manually! For builds/compiling your code, you obviously need to use something Jenkins, TeamCity or TFS. Even in very small teams you should do automated builds / continuous integration.

Test everything.

If you're not already doing some kind of automated tests, you absolutely have to start. There is no excuse. Automated testing is not something you wait for your QA team to do - it's a development task.

Unit tests are possible even with legacy code. At least start writing any new code in a testable way and build your tests up over time.

Integration tests should be possible for most projects. In .NET with WPF, start using Microsoft's Coded UI tests. It's a very easy way to automate your WPF UI. If you're using ASP.NET, then you'll want to use WatiN.

Just don't get too religious about testing and code coverage and forget what you're actually trying to accomplish. Sometimes we spend ages unit testing something of pretty low value, while the actual problem areas aren't covered well. There's no point in having 100% code coverage when you don't have enough tests to prove that you've met the acceptance criteria.

Follow good check-in/commit etiquette.

Commit often in small chunks. Pull / Get Latest often. This makes it easier for yourself because you reduce the number of conflicts to deal with.

Use good comments for your commit messages, not just something vague like "fix".

When merging conflicts, be considerate. Don't just throw away someone else's changes because you're too lazy to carefully merge your changes. If you can't tell what's going on and a merge isn't feasible, be considerate and take the server version then carefully put your bits back again.

Keep learning.

Encourage individuals to stay up to date with the continuous changes in technology. Follow famous developers on Twitter and Google+. If you don't know where to start, just follow one famous person you know and go from there. For .NET, follow Scott Hanselman on Twitter and/or Google+.

As a team, make time to learn together by: (a) trying new things, (b) doing Patterns & Practices meetings, (c) doing informal "show and tell" presentations. Encourage the team to work on side-projects when you have a spare moment now and then.

Maximize savings / Eliminate waste.

Remember why we're working here. We're not here to have fun, to learn, to write unit tests or even to write code. We're here to solve business problems. Bottom line: to make the business money. (But yes, of course we want to have fun and learn while solving the real business problems.)

Before you write that cool ORM (or CSV parser or some other way to reinvent the wheel), ask yourself: are we in the business of writing ORMs (or CSV parsers etc)? If a perfectly good open source or commercial solution already exists, then don't reinvent the wheel. I love reinventing the wheel myself, I know how much fun it can be to write libraries that you imagine might be usable by someone else, but use your time wisely.

The same goes for other things that costs the company money. Don't waste printer ink & paper! Why are you still printing articles for reading? (or even worse, printing source code!?) Learn to read on a screen. Or buy a Kindle if you claim you don't like reading a computer monitor or tablet. Use Pocket or Instapaper to save articles for later reading on a suitable device.

Always look for improvements.

I often hear a colleague say something like "But  that's not Agile/Scrum!", then my response is "We call it Agile because the process itself is agile." Don't treat your processes/methodologies like a religion. Change things that don't work and do more of what works well. Have regular retrospectives and follow up on improvement actions identified. An exception would be when you're starting with a new process like Scrum: first follow the rules strictly (do "Scrum by the book"), then only tweak your process at the end of each sprint according to issues raised in the retrospective.

Use the team's strengths.

Avoid specialization, but know your team's strengths (and weaknesses). Consider team members' interests. People who work on something they find interesting will generally be more happy and more productive. Consider what's the best use of everyone's time. For example, does it make sense for the most senior team member to perform the team's admin (sprint reports, keeping documentation up to date for CMMI, etc)?  Does it make sense for the most junior team member to spend a week figuring out how to install the new TFS server when another member could do it in an hour? It's important to let everyone work in as many areas of the project as possible to distribute the knowledge as much as possible, but there's a balance to keep.

Be pragmatic.

Don't be scared to go outside of your comfort zone to use the right tool for the job. For example, if you just spent half the day searching for a Markdown to PDF converter, and the only good solution you could find is a Ruby & Linux-based solution, then don't disqualify it just because your team only has experience using Windows.

Tuesday, October 01, 2013

Programming syllabus for the absolute beginner

A friend wants to start learning programming. In fact, she's considering getting a Computer Science degree and changing careers! I want to teach her everything I know: principles of object oriented design, dependency injection, high cohesion & loose coupling, unit testing, code contracts, MVC, jQuery, Python, NoSQL, Android, and .... Aargh, where do I even start?!

I need to come up with a learning plan for the absolute beginner. I want to get to the point where we could use Learn Python the Hard Way to work through the usual programming concepts and hopefully eventually build something interesting like a website or a mobile app. But I want to start at the very basics.

I'm thinking of starting with the following topics:
  • Introduction to HTML (design a page using a few tags and some minimal CSS)
  • Numeric expressions (operator precedence etc)
  • Hello world! (string expressions)
  • Binary math (bitwise operators, bytes, and, or, xor, not, shifts etc)
  • Boolean algebra / if-then-else
Some links I want to look at for learning Python:
  • Tutorial – Bit Banging and Boolean Math without the Math
  • http://lgm.fri.uni-lj.si/PA/PYTHON/PythonProgrammingfortheAbsoluteBeginner.pdf
  • https://wiki.python.org/moin/BeginnersGuide/NonProgrammers
  • http://learnpythonthehardway.org/book/ex1.html
  • http://www.ucs.cam.ac.uk/docs/course-notes/unix-courses/PythonAB

Monday, September 30, 2013

Positive team culture

A positive and healthy team can have fun together. A healthy team is mature. Mature doesn't mean super serious - if you can't have fun, I can't see how you can enjoy your job.

Mature team members:
  • Don't complain about "too many" meetings but help improve efficiency & communication to reduce the number of meetings.
  • Don't play with their phones in meetings, but interact.
  • Don't feel embarrassed or under-qualified to question and correct other team members, even more senior team members.
  • Don't get offended or hurt when corrected by another member.
  • Don't get hung up on team hierarchy. We're all just developers.
  • Help and support each other. There is no point in individual success. There's no place for selfish behavior in a team. The product/company doesn't benefit if the team isn't working together.
  • Don't complain when asked for help. If you're the guy who always says "I've got my own work to do" then don't expect others to help you next time. I always remember this Ace of Base line from my school days: "To help another person will make you feel important". It's satisfying to help someone and a good learning experience on top of that. There is no better way to learn than to teach.
  • Have a sense of humor! Don't take things too seriously. We might as well try to have fun while we're doing this.
I admit this is much easier said than done. You need the right (i.e. compatible) people in the team and you need the right manager to motivate the team. There will definitely be some exceptions to the above, for example I'm sure there are some highly successful teams who don't see how I could even mention that I value a sense of humor, similarly I'm sure there are lots of funny but incompetent teams out there. However, I think these points above go a long way towards accommodating the widest range of personalities.

At a previous company, all teams had names. X-Men character names like Cyclops, Havok, Wolverine, etc. So when I started at my present company, I suggested giving the teams names. It wasn't a popular suggestion :-) Apparently I was the only one who thought that giving teams names like that was a 'fun' idea. Of course, that's perfectly fine, I just had to realize that this team has a different idea of what's fun than I did.

Sunday, September 29, 2013

How to fix "Install Parse Failed - Inconsistent Certificates" when installing .APK file

If you install an Android application (.apk file) to your phone from one machine, and then try to install it again later when it's built on another machine with a different apk signature (e.g. from a CI build) then you will get the following message on the phone:  (In this example I've tried to install the app from an email attachment directly on the phone.)



"Application not installed. An existing package by the same name with a conflicting signature is already installed."



Similarly if you try to install the app on another development machine using ADB (or from the IDE) you get the following "install parse failed inconsistent certificates" error message:

$ adb install TestProj-debug-unaligned.apk 
1539 KB/s (45347 bytes in 0.028s)
 pkg: /data/local/tmp/TestProj-debug-unaligned.apk
Failure [INSTALL_FAILED_ALREADY_EXISTS]
$ adb install -r TestProj-debug-unaligned.apk 
2659 KB/s (45347 bytes in 0.016s)
 pkg: /data/local/tmp/TestProj-debug-unaligned.apk
Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]

You also get the exact same message as above if you try to run the application from within Android Studio of course:

Waiting for device.
Target device: CB5A1QHGNF
Uploading file
  local path: /Users/lombard/src/TestProjProject/TestProj/build/apk/TestProj-debug-unaligned.apk
  remote path: /data/local/tmp/com.example.testproj
Installing com.example.testproj
DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.example.testproj"
pkg: /data/local/tmp/com.example.testproj
Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]

You've got two options:
  1. Copy the first machine's debug.keystore file to the second machine. See: How to deal with INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES without uninstallation on StackOverflow.
  2. Completely uninstall the application first and then install again. You may have to do this if you don't have the debug.keystore file for some reason. Perhaps your Jenkins CI build has a different release keystore.
I've had to go for the second option.

I was hoping I'd be able to keep the application's data, so I first tried uninstall with the -k option to keep the data files, however that results in an "update incompatible" error:

$ adb shell pm uninstall -k com.example.testproj
$ adb install -r TestProj-debug-unaligned.apk
1532 KB/s (45347 bytes in 0.028s)
 pkg: /data/local/tmp/TestProj-debug-unaligned.apk
Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE]

The only solution seems to be to uninstall the application completely:

$ adb uninstall com.example.testproj
Success

Now the app will install from Android Studio.

Ideally I want to find a way to force an app to reinstall without needing to completely uninstall it first.

Wednesday, September 18, 2013

Nexus 7 with wireless keyboard and mouse

A few months ago I cracked my Google/Asus Nexus 7 screen/digitizer and the touch is no longer working on 90% of the screen. Only a small part in one corner still detects touch. The display still works fine otherwise, but it was essentially useless.

I looked into several ways to try and make the Nexus 7 usable again, including:
1. Tried to find an app that might all me to use the small working touch area to control apps (e.g. keyboard apps that can be controlled without needing the entire screen);
2. Tried to use MonkeyRunner to script apps to control them. However, this required me to accept the PC in USB debugging mode, which I couldn't do without being able to tap on the "OK" button...
3. Tried to find a cheap replacement screen/digitizer on eBay but I wasn't willing to spend more than EUR60.
4. Seriously considered getting a new Nexus 7 2013 model.

Eventually I've found an amazingly simple solution to make it fully usable again: A cheap OTG cable (Micro USB male to USB female), which allows me to plug my Logitech K260 wireless keyboard & mouse into the Nexus 7.

It's not exactly a tablet anymore, but compared to a broken piece of unused electronics lying in my drawer, this is great! The Nexus 7 with keyboard and mouse is now basically like a small Android laptop. Still perfect for surfing the web etc. I'm extremely happy that for only 3 GBP I've now got a working device again.

Tuesday, September 17, 2013

How to configure the Samsung Galaxy 5 / Europa to work with ADB / Android Studio

I want to deploy an Android application from Android Studio to an old Samsung GT-I5500 (known as Galaxy 5 or Galaxy Europa) running Android 2.2 Froyo (API level 8). (Yes, it's probably worth testing on old phones too, although I admit Froyo is at the very bottom 2.4% of distributions!)

Summary of steps:
  1. Enable USB debugging
  2. Select USB connection mode to "UMS mode only"
First enable USB debugging by going to Settings -> Applications -> Development -> enable "USB debugging".

Plug in the USB cable from the computer to the phone. The phone will pop up the "Setting USB" dialog and ask you to select "KIES" or "UMS mode only". You want to select the first option: UMS mode only. (Kies is Samsung's software for updating the phone's software etc).

Now the I5500 shows up on my devices list in Android Studio. My Android application was configured for minSdkVersion 10 so notice the "no" in the Compatible column when I tried to run the application:


I modified the build.gradle file to minSdkVersion 8 and also set android:minSdkVersion="8" in the AndroidManifest.xml file. Now the app deploys OK.

Of course ADB.exe also lists the I5500 correctly now:

D:\Android\android-studio\sdk\platform-tools> adb devices
List of devices attached
I550030d7c481   device


Thursday, September 12, 2013

OK, I admit it! I was wrong!

This morning I saw this tweet:
I had a similar thought earlier this week at work. As many others, I've always got a long To Do list and it never seems to get any shorter. As result, I try to prioritize as I go and sometimes I don't make the wisest choices and some very important tasks fall way behind schedule (even though they remain at the top of my To Do list for weeks!)  This week one such task culminated in my manager coming over looking for the reasons why I hadn't completed the work yet, as the issue is now highly visible. I went into a half hour rant explaining the various reasons and excuses why I couldn't finish the task. That night, in bed (probably around 3am, the time when I usually reflect on this type of thing), it occurred to me that I was being completely dishonest to myself and my manager. The simple reason I have not yet finished that task, is because I find it boring and I will always pick a more interesting task that I can justify to myself as being more "urgent" at the time. The next morning I talked to my manager and admitted: "The simple answer is: I found it boring and I made some judgement errors in my prioritization and procrastinated too long." It feels good to take responsibility for your mistakes.

This ability we have to find excuses to justify our decisions even when we're wrong, is called Cognitive Dissonance. Check out the book called "Mistakes were made (But not by me)". It covers this topic quite well, I recommend it.

As developers, we want to prove ourselves. We want to be right about our opinions and we want others to see our point of view. It's difficult to be completely unbiased when there is any room for ambiguity in a debate.

I'm sometimes lucky to catch and recognize the feeling of the cognitive dissonance as it sets in, and that makes it easier to control it. It helps a little bit just be aware that we're all susceptible to biases and cognitive dissonance, but I doubt anyone can completely eliminate it.

For many years I've been keen to try doing regular Code Reviews at work, but I'm "worried" that my team members may feel insulted when I "criticize" their code. At the same time, I feel like I can handle the criticism myself. Does that mean I'm mature enough not to experience cognitive dissonance when faced with disagreement, or is that a type of bias in itself to think that I'm somehow less susceptible to the emotional effects of criticism and conflict? (By the way, no one should feel offended when their code is criticized - you are not your code).

As software developers, I think we are often too scared of making any mistakes. Especially "debilitatingly-perfectionist" and High C developers like myself. We want certainty and facts. We want to stick with the tools we know. We get religious about our tools (languages, text editors, brands of keyboards, etc) and we can't understand when others can't see that they're wrong and we're right.

We have to learn to embrace risk, taking chances, making mistakes, and admitting our mistakes. The Agile mindset is to embrace failure (fail early). Learn to make better mistakes in the future. Making mistakes is the key to making progress, as Daniel C. Dennett says in his book "Intuition Pumps and Other Tools for Thinking".

Links:



Sunday, September 08, 2013

Remote Desktop Connection for Mac OSX - cannot verify the identity of the computer

Short version: If you have issues with the Microsoft RDC for Mac client connecting to Windows Server 2012 R2, then give CoRD a try.

I'm having a lot fun playing with Azure lately. It's so quick and easy to create new Ubuntu- or Windows-based VM servers for trying something, and then deleting the virtual machine again when I'm done. For the Ubuntu servers I just use ssh of course, but for Windows Servers you need to use a Remote Desktop Connection client.

At home I connect to the Azure cloud services on OS X using the "Microsoft Remote Desktop Connection for Mac" RDC client. It's just cool seeing the remote Windows server on the Mac. I don't even need to use VMWare or Parallels to run a local Windows installation.

However, I've come across this error on the Mac when trying to connect to a remote Windows Server 2012 R2 on Azure:
"Remote Desktop Connection cannot verify the identity of the computer that you want to connect to. Try reconnecting to the Windows-based computer, or contact our administrator."

When this happens, the only solution currently seems to be to use CoRD instead of the Microsoft RDC client.

First ensure you've disabled the "Allow connections only from computers running Remote Desktop with Network Level Authentication (recommended)" setting. To do that, first connect to the remote Windows Server 2012 R2 using RDC on a Windows client, then go to Server Manager:



Go to Local Server -> Remote Desktop. Make sure the NLA setting is unchecked:


Now get CoRD from http://cord.sourceforge.net/

Add the server, making sure you've got the correct domain name for the Windows login:


Now you should be able to connect successfully to the remote Windows 2012 R2 server in the cloud.

On other versions of remote Windows servers you may also have success trying the following with the Microsoft RDC client for Mac:
  1. Close Remote Desktop Connection for Mac
  2. Go to: Finder -> Documents -> RDC Connections
  3. Move the Default.rdp file to Trash
  4. Open RDC again and connect to the server.
  5. When the Enter your credentials window pops up, the Domain field is populated with the DNS name of the host, which isn't necessarily the correct domain name. Try the correct domain name or try clearing this field.
  6. Just supply the correct username and password. Click OK.
Sources:

Monday, March 25, 2013

Configure Google Nexus 7 to work with Android SDK Tools / ADB.exe

I wanted to deploy my first “hello world” Android application from Eclipse on Windows 8 to my Google Nexus 7 tablet. I plugged the Nexus 7 into my development PC using the USB cable and then I used adb.exe to list the devices, but no devices were found.

The summary of steps I took to get the device to show with ADB:

  1. Enabled the USB debugging setting on the tablet
  2. Changed the USB connection mode to Camera (PTP)
  3. Updated the Google USB Driver in Windows

Initially Adb.exe shows no devices:

01-adb-shows-no-devices

If the Android emulator is running, it shows as the only device:

02-adb-shows-only-emulator

The first step is to enable the Developer options the Nexus 7. Go to Settings –> About tablet. Then tap the “Build number” 7 times!

02-tap-build-number-7-times

Now you will see the “Developer options” setting. Go into Developer options and enable the “USB debugging” setting:

02-enable-usb-debugging

When you get the “USB debugging connected” notification, tap the “Connected as a media device” option.

02-usb-connected

The default USB mode is “Media device (MTP)”, change this to “Camera (PTP)”:

02-select-camera-ptp-mode

Install the Google USB Driver using Eclipse / ADT: Window –> Android SDK Manager. In the Android SDK Manager, select Extras –> Google USB Driver. This installs the driver to your android SDK folder under sdk\extras\google\usb_driver.

Now update the device driver using Device Manager in Windows 8:

03-open-device-manager-win8

Find the “Nexus 7” device in the Device Manager under “Other devices”, then right click and select “Update Driver Software…”:

04-device-manager

Provide the path to the Google USB Driver:

05-select-driver

Select “Always trust software from Google Inc” and install the driver:

06-install-driver

Now the “Android Composite ADB Interface” will show in the Device Manager:

07-android-device-in-device-manager

Run ADB.exe again and confirm the new device is available. It may show as offline:

08-adb-shows-new-device

If the device shows as “offline”, then make sure to confirm on the tablet that you allow USB debugging:

08-allow-usb-debugging

Now the device is online:

09-nexus-online

That’s it!

I’m using Windows 8 64bit, Android Developer Tools (ADT) v21.1.0-569685 and the Nexus 7 is running Android 4.2.2. I used the information on this StackOverflow post to figure everything out.

Sunday, March 24, 2013

Asus Google Nexus 7 3G – Setting up O2 Ireland mobile broadband micro SIM

When I got my new Google Nexus 7 32GB/3G tablet, I immediately went to the O2 store in town and bought a prepay data Micro SIM for €20. (I actually first went to Carphone Warehouse, but they don’t have data-only Micro SIMs for O2). I went to the O2 website and activated the free 24 hour pass.

First thing I did was, I used the wee SIM ejection tool which was included with the Nexus, and plugged in the new SIM. Not too surprisingly, the mobile broadband didn’t just start working by itself. The Nexus showed the “H” mobile icon (HSPA) but the internet wasn’t working. I expected to receive an SMS text message from O2 to active the SIM, but nothing happened after waiting a few hours.

The next day, it occurred to me to plug the SIM into my iPhone 4S to see if I receive the activation SMS that way, but still nothing. I contacted O2 customer service (twice) and tried to explain my situation. Even though the second support person was completely unfamiliar with using the data SIM in a tablet, he did give me a good tip: a mobile data-only SIM doesn’t work at all in an iPhone, so even if the SIM had been activated, it still wouldn’t have worked in my iPhone, secondly, he reset the SIM completely, at which point I finally received the SIM activation code SMS on my phone.  Luckily that was all it took, I went to the O2 website and activated the SIM using the code I received in the SMS, and put the SIM back into the Nexus tablet. But still no internet on the tablet.

(As a side note, after the SIM was activated, my iPhone automatically sent an SMS to some +44 international number, which cost me a few cents, at which point my €20 prepaid credit was no longer enough to activate a 30-day pass, so I had to buy €20 more of credit, but that’s another story).

Next, it occurred to me that I probably need to configure the internet settings specifically for O2 on the Nexus tablet (DNS, O2 Ireland APN and that stuff). After a little bit of Googling, I found a few APN tips for other types of modems and after some trial and error, this is what worked for me.

Go to Settings. Under “WIRELESS & NETWORKS” select “More…”, then select “Mobile networks”:

01-network-settings

Under “Mobile network settings” select “Access Point Names”:

02-select-access-point-names

Now create a new APN by clicking the “three dots” icon and select “New APN”:

03-new-apn

Enter the following fields:

  • Name: O2.ie (or any name you like)
  • APN: open.internet

04-o2-ie-internet

After adding the new APN and returning back to the “APNs” setting screen, I believe I had to check the radio button next to the new “O2.ie Internet” APN setting to enable it.

And that’s it! Now your O2 mobile broadband will work on your Nexus 7.

Other Android 4.2 tips:

  • To take the screenshots above on the Nexus 7, I pressed the power button and the "volume down” button simultaneously for about a second or two.
  • If you’re a developer (or even just a curious to play with the Android SDK tools), you will want to enable the Developer options.

Monday, March 11, 2013

Cargo cult unit testing

Writing unit tests is really time consuming. We strive for 100% code coverage. I often spend more time writing unit tests than I did writing the functionality itself. (And yes, we write unit tests afterwards, we don't do strict TDD, but that's another story).

Sometimes I feel like my unit testing is just cargo cult behaviour. Am I just blindly following best practices like unit testing because the experts told me so?

Then occasionally I experience that happy moment when a old unit test catches a stupid mistake I just introduced into the code, and my faith is reaffirmed.

Overall I can definitely see an improvement in code quality over the crappy code I used to write years ago, so the tests are definitely helping, but I can't help but think sometimes if there isn't another (more productive) way to go?

I'm tempted to wonder: wouldn't higher level testing (integration testing) yield the same quality but at less cost? For example, isn't it sufficient to test the acceptance criteria using BDD style tests? I've experimented with SpecFlow previously and found it a very natural way to test. I’d like to give it a try again one day…

One example of the side effects of writing testable code is that you’re forced to keep the code cohesive. You really start thinking about coding principles and clean code. If you don’t keep the code clean (cohesive, loosely coupled), you’re going to struggle to write (and worse, maintain) those unit tests. Follow the SOLID principles (e.g. Single Responsibility principle) and your code is going to get so much easier to test. When you’re testing a class that has multiple responsibilities, e.g. a ViewModel (MVVM) in WPF/Silverlight, you easily end up multiplying test cases. For example, when you split a large ViewModel with multiple responsibilities into smaller sub-ViewModels, you’ll likely end up with a smaller number of test cases at the end.

If you don’t test everything, every scenario, you’ll loose track of what functionality is actually tested, and you will make a small change to the code, run all tests, the tests pass. But does that really mean that your new change is correct or not? You’ll become complacent and assume you can rely on the unit tests when it’s convenient, but you won’t really know if your code is stable. You need to maintain 100% coverage. As they say “test coverage starts with 100%”