How to read files from dir and generate html output

2 Comments

When creating videos, I take snapshots of keynote, upload to website, and then manually handcraft the html to include in the show notes. It’s slow, tedious, and not a lot of fun.

So today I created a ruby script to do this for me.

imageconverter.rb

date = ARGV[0] # 2013/06
alt = ARGV[1] # iteration mechanics
basedir = "/Users/jrasmusson/Desktop"
files = Dir.glob(basedir + "/*.png")
files.each do |k|   puts "<img src=\"http://xxx/" + date + "/" + File.basename(k) + "?w=500\" alt=\"" + alt + "\" /><hr>"
end

> ruby imageconverter.rb 2013/06 “iteration mechanics” | pbcopy

<img src="http://xxx/2013/06/im-analysis.png?w=500" alt="iteration mechanics" /><hr>
<img src="http://xxx/2013/06/im-check-the-work.png?w=500" alt="iteration mechanics" /><hr>
<img src="http://xxx/2013/06/im-do-the-work.png?w=500" alt="iteration mechanics" /><hr>
...

To see the output on screen, run without the pbcopy mac command at the end which copies to clip board.

The only thing I haven’t been able to do is make this ruby script globally available from any directory (like a bash script).

If anyone has any ideas on how to do that I would be very grateful.

.bash_profile and handy scripts

2 Comments

Just a copy of my .bash_profile in case I ever forget it.

Misc unix commands
> du -sh *

.bash_profile

export PATH=$PATH:~/scripts
export JAVA_HOME=/Library/Java/Home
alias nutshell='cd /Users/jrasmusson/Developer/agilenutshell'
alias reduce='sips --resampleWidth 200 a.png --out b.png'
alias ios='cd /Users/jrasmusson/Developer/iosbyexample'
alias gs='git status'
alias test='bundle exec rspec spec'

My scripts directory:

ci.sh easy git checkin

#!/bin/bash
echo "Checking in..." 

git add .

if [ -z "$1" ]
then
 git commit -a -m "cleanup"
else
 git commit -a -m "$1"
fi

git push
echo "Done!"

reset.sh resets my git repository

!/bin/bash
echo &amp;amp;quot;Reseting git repository&amp;amp;quot;
git reset --hard HEAD^
git clean -f
git merge origin/master

chmod 711 ci.sh reset.sh

Something that handles ssh

#!/bin/sh

echo "ssh mount..."
ssh -t -t root@192.168.1.107 <<EOF
mount -o remount,rw /system
exit
EOF

echo "copying..."
scp libspotify.so root@192.168.1.107:/system/chrome/plugins/libspotify.so
echo "ssh chmod"
ssh root@192.168.1.107 <<EOF
chmod 0744 /system/chrome/plugins/libspotify.so
reboot
exit
EOF

iOS Boot Camp Coming to Montreal Nov 7-8

Leave a comment

November 7-8 me and my colleagues are going to Montreal for the first time offering our iOS Bootcamp at the Apple Regional office in St-Laurent.

This course is perfect for developers looking to get into iPhone development or just have an idea for an app they’d like build to turn into reality.

If you want to get into iOS development, and you would like a distilled, tight, 2 day course to get you there this is the course for you.

Signup now

See you there.

Jonathan

History of Cocoa

Leave a comment

Some good history of Cocoa from Aaron Hillegass’s book Cocoa Programming.

The window server on Mac OS X is like the X window server on Unix. It gets events from the user, forwards them to the application, and puts data on the screen.

NeXTSTEP came up with a set of libraries to enable programmers to deal with the window manager in an elegant manner. These frameworks were originally called OpenStep, which was later renamed Cocoa.

Programmers loved OpenStep. Tim Berners-Lee developed the first Web browser and the first Web server on NeXTSTEP.

Apple selected NeXTSTEP as there next operating and bought the whole company in December 1996.

NeXTSTEP became Mac OS X. It’s Unix underneath.

Cocao Touch is built on top Cocoa (many of the classes are identical). Most importantly, the principles and design patterns are essentially unchanged.

Objective-C ternary operator

1 Comment

int velocity;
if (isCar)
   velocity = 100;
else
   velocity = 10;

Is the same as:

int velocity = isCar ? 100 : 10;

Another handy NSLog:

NSLog(@"mondaySwitch: %@", (onOff ? @"ON" :@"OFF"));

Computers and School

2 Comments

Hi all. This is a guest post by Olivia Leonardi who asked if I would post this on her behalf.

It’s a post about computers, schools, students, and the important role they play in our society. Regardless of how you feel about computers, it’s pretty clear there’s a big demand for people with computer skills and that trend seems to be ever increasing.

Happy reading.

===========================

In today’s post, Olivia Leonardi finds it hard to believe that American high school students, whose use and reliance on computers and the internet is well documented, often graduate without ever being introduced to computer science and programming languages. Although traditional schools are missing out on computer science curriculum, online programs offer everything from certificates in computer science to full-fledged, fully online degrees. As evidenced by the Agile Warrior’s blog about working with XCode, the online platform of learning allows anyone interested in computer science to learn with and from leaders and fellow students.

Because of School Oversights, Consumers See Dramatic Increase in Online Computer Science Programs

Despite stubbornly high unemployment, in February 2012 more than 5,000 cloud computing job ads were posted online in the U.S. In the past two years, demand for cloud computing skills shot up 400%. However, despite heavy demand, recruiters find that most candidates simply lack the technology skills necessary for these jobs. Even though computer skills becoming increasingly necessary both in the workplace and everyday life, most students in the U.S. can graduate with a high school diploma or even a bachelor’s degree without ever acquiring basic skills in computer programming and functions. In response to this oversight, learners of all types are utilizing online programs and applications to gain valuable computer science skills.

While the outlook for almost every career path today seems fraught with pessimism and uncertainty, computer science is still an unusually safe choice for those entering the workforce. The U.S. Bureau of Labor Statistics predicts that opportunities for computer programmers in the U.S. IT market will grow by 12%. Furthermore, in Computerworld’s Forecast survey, 61% of polled IT executives stated that they plan to hire programmers and application developers through 2012. “Web development continues to be very strong,” says John Reed, executive director of staffing firm Robert Half Technology. Reed asserts that as companies try to improve the user experience, there will also be a lot of effort to develop mobile technology to improve customer access via smart phones, leading to increased need for talented programmers and application developers.

As markets become increasingly global and internet proliferation stretches to the furthest reaches of the planet, freelance positions for computer programmers and technicians are expected to see significant growth, as well. Freelance employment site Elance predicts that more than half the workforce in the U.S. will be freelance by 2020. By that time, savvy internet users will have a marked advantage as they vie for jobs in a truly global candidate pool. Even today, there are myriad excellent resources online for those looking for education in computer sciences.

Web development sites like Webmonkey offer tutorials for various web programming languages as well as user forums that allow fellow users to communicate and aid each other through the lessons. Veteran computer technicians who received their degrees decades ago might be shocked to find the resources available through MITs OpenCourseWare. OCW offers accessible courses in computer science, including introduction to Java, Python, C++ among others from their esteemed faculty for free. Essentially, ambitious coders can experience the same education that students receive at one of the world’s most prestigious technical universities, and despite not receiving course credit, the skills learned can ultimately prove valuable.

Among online programming resources, though, Codecademy has ranked as the most popular. The site allows users to build websites, games and apps while learning alongside fellow users in an interactive and user friendly way. While challenging, Codecademy is also designed to be fully engaging and fun for the learner, offering chances to track progress on a regular basis.

As technology changes the job market, it also changes the way we learn and acquire new skills. Though traditional education has often failed to adequately prepare students with the computer skills they will need for most careers in the 21st century, the innovative online marketplace has assured that low cost resources will be available to any enterprising student willing to learn. As computers continue to connect our planet, resources for education will increasingly become available to those with the drive to learn.

How to create an Objective-C category

1 Comment

What

Categories are objective-c’s way of allowing you to add methods to an existing class without having to touch it’s source.

For example, say we wished had a method on NSString that decorated our string with some pretty output.

- (NSString *) decorate
{
    return [NSString stringWithFormat:@"=== %@ ===", self];;
}

And we wished we could call it directly on NSString like this:

NSLog(@"%@", @"Booya".decorate);

Outputs:

=== Booya ===

Categories allow us to do that. Here’s how.

How

The format of a category is the ClassName you are extending, followed by the name you want to give your category (i.e. “Utils”).

#import "ClassName.h"

@interface ClassName ( CategoryName )
// method declarations
@end

To make a new category in Xcode we basically create a new class. Go:

New File (Command + N).
Select ‘Objective-C category’.

Specify the class you want to add a category onto (i.e. NSString).

Then add your category method to your .h file.

#import <Foundation/Foundation.h>

@interface NSString (Utils)
- (NSString *) decorate;
@end

And your implementation to you .m file.

#import "NSString+Utils.h"

@implementation NSString (Utils)
- (NSString *) decorate
{
    return [NSString stringWithFormat:@"=== %@ ===", self];;
}
@end

Now you can go to the class where you want to use the extension, import your category header and make your method call.

#import "NSString+Utils.h"

- (IBAction)tapMePressed:(id)sender
{
    NSLog(@"%@", @"Booya".decorate);
}

That’s it!

Links that help

Apple documentation on category

How to UIWebView iOS

4 Comments

Here’s a simple walk through of how to display a web page in iOS.

Drag out a WebView onto your ViewController.

Create a property.

ViewController.h

@interface ViewController : UIViewController 
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end

Implement the UIWebViewDelegate

ViewController.h

@interface ViewController : UIViewController <UIWebViewDelegate>

Fix the autogenerated synthesize:

ViewController.m

@synthesize webView = _webView;

Make yourself the delegate and display your web page.

ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.webView.delegate = self;
        
    NSURL *url = [NSURL URLWithString:@"http://google.com"];
    NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:requestURL];
}

Hit Run.

Can optionally add the following delegate methods if you want to kick it up a notch.

ViewController.m

#pragma mark - Optional UIWebViewDelegate delegate methods
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

Here’s the source.

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize webView = _webView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.webView.delegate = self;
    
    NSURL *url = [NSURL URLWithString:@"http://google.com"];
    NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:requestURL];
}

- (void)viewDidUnload
{
    [self setWebView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

#pragma mark - Optional UIWebViewDelegate delegate methods
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

@end

There’s two way to do a job

7 Comments

You can do it the crappy way.
The way when you just blow through it and get it down.

And the right way.
The one you feel good about and will stand the test of time.

Doing it the crappy way is easy.
Doing something the right way is hard.

It’s a slippery slope, because you are always going to feel pressure for the crap.
Just get it done.
We are already late.
We are already behind.

Resist that urge.
You know you are going to revist that code someday.
People code by example, and if you put a shitty example in there, people are going to build on it.
You are the leader.
You set the standard.

Let your work stand for itself.
Care.
And damn whatever anyone else thinks.

Expecting failure

4 Comments

When building a system, you can either take the view that things are going to work, or that they are going to fail.

You need to be defensive when building systems, but you want to avoid overdoing it. When you get overly defensive, you get product out the door later and you raise your total cost of ownership by creating an overly complex, difficult-to-maintain system.

In this month’s column I want to tell you the story about how a team I was part of leaned too far in the defensiveness direction, and what we did to bring it back.

A Messaging System

The team had an architecture that looked something like this:

Messages would come in one end, and transformed messages for specific recipients would come out the other. Simple enough.

Not surprisingly the legacy system we were replacing had “issues” (mostly around things blowing up). So when it came to replacing it, there were strong opinions concerning error handling and logging. We started off expecting things to fail.

Well, it didn’t take long before we had so much error handling and logging that it became hard to see (and troubleshoot) what the system was actually doing. We were so afraid of failing that it felt like we forgot what we were building in the first place.

Why were we being so timid? Were we justified in our level of skepticism? Was all this support code and logic really necessary? It felt wrong and it felt strange. Yet we persisted.

Then one day, someone asked:

What if messages came in one end, and the correctly transformed message came out the other? What if we stopped expecting failure? Don’t accept any failures. Just make the bloody thing work. What would that mean to our approach to the system?

What a beautiful, simple, powerful question. Asking ourselves “What if it just worked?” got us looking at the system in a new light.

Instead of it expecting it to fail at every step, we now expected it to succeed.

We realized we could get rid of a lot of errors up front by simply not letting them into the system in the first place.

* What if we tightened up validation on messages coming in?
* What if we rejected all messages that didn’t conform and notified production operations instead of trying to handle it ourselves?

If we coded and tested the system right in the first place, we could fix a lot of the core problems that riddled the legacy system instead of expecting and handling them when they happened.

I know, it seems obvious now. It is obvious. But somehow it wasn’t so obvious at the time. Yet this simple, obvious shift in perspective profoundly changed how we looked at the system.

Instead of expecting failure, we started to expect success. This simplified and lightened our code base, while leaving just enough checking there to let us know if things went wrong.

No, not quite. Our systems are going to fail, and we need to handle those failures. All I am saying is that if we only focus on failure, we can really overengineer and overcomplicate things. That’s expensive, because then we need to carry the baggage of this overengineering around with us forever, making the system harder to maintain and to change.

It’s a balancing act. We do need to expect failure. We just don’t want to overengineer for it to the point where we lose sight of what we’re really doing. Which should be delivering valuable, working software to our customers.

Not wanting to leave you with just a story, I want to offer you two surefire ways I’ve seen teams harden their systems to ensure that they aren’t overly confident before rolling into production.

Work with Real Data

When you throw real, live production data at your system, good things start to happen.

1. You discover where the holes in your data model are.
2. You discover which of your assumptions are valid, and which are wrong.
3. You see what edge data cases you missed, and discover that French characters don’t always encode the way you’d expect them to.

There are few better things that you can do to see how your system is going to handle going live than to throw some real data at it. The other thing you can do is to get something into production.

Get Something into Production

You don’t have to flip the switch and really “go live” (though you obviously will at some point). What I am talking about is getting your system into production before it needs to be there.

This does a couple of things for you:

1. You can throw some of that data at it and see how it behaves.
2. You can work all the kinks out of your automated build and deploy scripts.
3. You can work out all the network and infrastructure issues.

But best of all, you get into the habit of releasing. The more you push to production, the less scary it is. Do it enough and it will soon be like breathing.

Context Is Everything

Take what I am saying here with a grain a salt. You still have to judge for yourself what level of error handling and defensiveness is right for your application.

But if you keeping things simple, and build things so that you expect them to work, you can keep yourself from overengineering a system that doesn’t need it, and while making your application easier and simpler to maintain.

Older Entries

%d bloggers like this: