Background Tasks in ASP.Net with HostingEnvironment.QueueBackgroundWorkItem

.Net 4.5.2 was released on May 5th, you can read all about it on the .Net Framework Blog or MSDN Library release notes. It includes HostingEnvironment.QueueBackgroundWorkItem, which lets you queue background threads from within an ASP.Net web application. This is useful for long running tasks that don’t need to complete before returning a response to the user.

Virgin Mary statue

Mary and Me

Every Sunday a few thousand Chileans and I pay our respect to the Virgin Mary. But we’re not in a Church. There’s actually thousands of cyclists, runners and walkers that go up Cerro San Cristóbal (cerro means hill in Spanish). Everyone starts at the Pedro de Valdivia Norte entrance to the hill and goes up the road. There’s hardly and cars, and most corners are divided to reduce collisions.

It’s really an impressive display of public sport and health. You certainly see lots of people on the bike paths in Toronto on a summer day, but it’s neat the way it’s been institutionalized here.

[map address="-33.417831,-70.616941" zoom="13" ]

Entrance to the park

The first time I ran this route on a Sunday I thought I was going to have to turn around because there was a race going on. Turns out this happens ever week.

view of the city

It can get a little smoggy, but it’s a good vantage point to see the city from.

shot of people walking up

It can get unreasonably steep at times, it’s certainly not an easy run, but I honestly think walking would be even worse.

mechanic station

About half-way up the hill there’s a mechanic with tools for anyone that might have an issue.

road division

The road is usually divided at corners to stop the cyclists that are descending much faster than the runners going up the hill.

aerobics area

They have a mass public aerobics class every Sunday. I got there just before they started.

spin class

This is where things start to get truly weird. There’s a spin class half way up the hill.I have no idea what they do with the bikes the rest of the week.

Lots of runners and cyclists

It’s pretty much this busy the whole way.

parking lot

The parking lot at the top of the hill.

Virgin Mary statue

At the top of the mountain is a Statue of the Virgin Mary. The run isn’t over until you’ve climbed the stairs all the way to the top.

 

prayer notes

There’s a spot by the statue to leave a prayer and a candle.

nice trees

I really look forward to my Sunday runs. It really feels like you’re outside the city.

June in a mist fan

Summer on the Santiago Metro

At the risk of annoying my friends dealing with the snow back home, I have to mention how hot it is here. You sit outside without shade for 15 minutes, you’ll get a sun burn. When the water cuts out (which it has twice in the last month) you begin bartering with the devil for a single bottle. There’s been times I’ve considered shorts and t-shirt entirely too much clothing for an office.

They use an interesting method of cooling down the metro system, mist fans. This photo was actually taken a few months ago, June would now spontaneously combust if she wore pants. I guess it’s so dry here that airborn water isn’t really a concern for long term maintenance. I’m not sure people in downtown Toronto would be okay with this, but it’s welcome here.June in a mist fan

argoposter

ASP.Net MVC SelectList, SelectedValue, and DropDownListFor

Unintuitive framework features usually end up as highly rated questions on StackOverflow because everyone is running into the same problem with a commonly used feature. This question on about drop-down lists in ASP.Net MVC with  59 votes, 38 favourites and numerous partially correct answers should prove that the lowly drop-down list is one of the most baffling features in ASP.Net MVC. This article will be an overview of how to use drop-down lists, setting a selected item, and issues you’ll run into on a strongly typed view. The following code applies to the Razor view engine and have been written for MVC 4.

Sample Model

For the sake of this article, assume we have two classes, Movie and Director. In our application we want to add new movies, and select directors from a drop-down list. The classes are structured as follows.


    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public virtual Director Director { get; set; }
        public virtual int DirectorId { get; set; }
    }
    public class Director
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

Html.DropDownList vs Html.DropDownListFor

To add the drop-down markup to your .cshtml page you could of course simply write out a select element by hand, but then you lose out on validation. MVC provides HTML helpers for generating common HTML elements. For an HTML select element you have two choices: Html.DropDownList and Html.DropDownListFor. The difference is the way they reference the name attribute of the resulting HTML element. DropDownList takes as it’s first argument a string that will be turned into the form field. So the call

@Html.DropDownList("director", directorList) //assume directorList is an IEnumerable of SelectListItem to create options from

Will result in an html element that looks like this.

<select id="director" name="director">...</select>

The problem with this approach is if you change the name of the property on your model from ‘director’ to ‘auteur’ you won’t get compile time checking and your form will no longer work with model binding. Html.DropDownListFor was introduced in MVC 2 and allows binding to strongly typed views. The first argument should be a lambda function that returns the model property you want the control to bind to. So in our case if the view-model includes a property DirectorId we can create a drop-down list with the code

@Html.DropDownListFor(viewModel => viewModel.DirectorId, directorList)

Which generates the following html

<select id="DirectorId" name="DirectorId">
...
</select>

Now if we change the name of the Director property our build will break because the lambda expression will be invalid.Note that we’re using DirectorId instead of a Director object because we likely want to store the id in a foreign key.

Populating Drop-Down List Options

To populate a drop-down we need to pass the HTML helper an IEnumerable. This is easily created by making a SelectList object in your controller, and passing it in via a view-model.

        public ActionResult Index()
        {
            var directors = new Collection
                {
                    new Director {Id = 1, Name = "David O. Russell"},
                    new Director {Id = 2, Name = "Steven Spielberg"},
                    new Director {Id = 3, Name = "Ben Affleck"}
                };
            var selectList = new SelectList(directors, "Id", "Name");
            var vm = new ViewModel {DirectorSelectList = selectList};
            return View(vm);
        }

I’ve created a collection of directors and passed it into the SelectList constructor. This collection could have been queried from a database, this sample was simply for demonstration. I’ve also supplied which fields should be the drop-down value (Id) and display text (Name). If I omitted those additional parameters the ToString method would be called on the each object to generate the item.
My drop-down list now looks like this.
Populated drop-down list.
If you don’t like passing in a SelectList as part of your model you could pass in the IEnumerable and construct the SelectList in the view, but I prefer putting as little code in the view as possible.

Setting a Default Value of the Drop-Down

And here is where things start falling apart. The aforementioned StackOverflow question highlighted how hard it is to set a default value on a drop-down. The problem stems from poor documentation for DropDownListFor. There is an overload that takes a fourth parameter called selectedValue which is an object to set the value. Theoretically I should be able to have the following the default to the option with an id of 3

var selectList = new SelectList(directors, "Id", "Name", new {id = 3});

However the first value, David O. Russell, is still selected in the view. And as good a job as he did in Silver Linings Playbook, I want to default to Ben Affleck. The problem is by using a strongly typed view, MVC is trying to bind my DirectorId field to the DirectorId property of my model. And because I didn’t populate the DirectorId field of my view-model, MVC is defaulting the drop-down to the first value.

My solution is to set the DirectorId property of the viewmodel to the value I want defaulted as follows.

var vm = new ViewModel {DirectorSelectList = selectList, DirectorId = 3};

Then when my view is templated the correct option is selected.
Default value selected in a drop-down

calvin hobbes new years resolutions 620x469_medium

Goals for 2013

2013 is going to be an interesting year. I’ll be transition from Santiago back home to Toronto, at which point I’ll be offered something of a reset. I’ll be returning to the city and communities I grew up in, but with very little necessarily the same as it was the four years I was there after graduating university. While on my run this morning I was thinking about what I want to get done this year, with a specific focus on where I wanted to be two or three years from now.

I may be a little late on New Year’s Resolutions, but hey, I’m on Chile time. Here are my goals in roughly chronological order, to give me some deadlines on when things need to be accomplished.

  • Release My Elephant Brain. By February 28 MEB should be in closed beta, I want it generally available by the end of April 30.
  • Put out a first version of Pushlr. Pushlr was the app a friend and I built at AngelHack Santiago. It lets you push content from your computer to your phone with a focus on immediate consumption. Since then there’s been a few times I really wish I had it (20 character WPA codes) so. I want to release this app. I want to use it personally, but it’s also a good chance to try mobile development. The first release should be by the end of March 31.
  • Read a children’s book in Spanish. If I return to Toronto with zero Spanish proficiency I’ll have only experienced a fraction of Chile. By April 30 I want to make it cover to cover in a Spanish language children’s book without consulting a dictionary.
  • Complete the Second City improv course. Before I got word I was moving to Santiago I signed up for the into to improv course at Second City in Toronto. I had to take a rain check on the course when I moved here. When I get back to Toronto, I’ll be taking the class over the summer, finishing sometime before August 30.
  • Run a sub-2:45 marathon. This will likely be in the fall after a solid summer of training. I really want to get back to Boston and that time would guarantee me a spot at the starting line, and I’d be exempt from the New York Marathon lottery. That gives me until about October 20th (Scotiabank Toronto Waterfront Marathon) to check this off.
  • Enter a Kaggle competition. Kaggle is a website that runs machine learning competitions. Their tagline is “making data science a sport”, which may be a little lofty, but you get the idea. Data Science is a really interesting toppic and I’d like to see if it’s something I could pursue long term. I have no hope of winning any of the competitions, but I’d like to put together a decent entry by November 15.
  • Finish all the books on my Kindle. I have 5 or 6 books on my kindle that I’ve started then forgot about. I’m not buying another book this year until everything on the Kinde is finished. I’ve got some pretty serious technical writing on there, so this will probably take until next Christmas.
elmah

ELMAH on MVC

ELMAH is a library you can drop into any ASP.Net WebForms or MVC applicaiton and automatically capture and record every unhandled exception in your application. User get a 404 looking for a page that doesn’t exist? Recorded. Try to access a member of a null object? Recorded. Database query throw an error caused by gremlins? Recorded.

There are other sources to tout how great ELMAH is (Scott Hansleman’s initial piece and again when NuGet was released) so I won’t go into that here. This post is about the minimum steps to getting ELMAH running on ASP.Net MVC.

ELMAH is pretty well documented, in fact it was initially just supposed to be sample code demonstrating ASP.Net features for an MSDN Article, however, however integration with MVC is sorely lacking in the official docs. In tradational ASP.Net you would set customErrors off in web.config to show a custom page after an error instead of the Yellow Screen of Death.

<?xml version="1.0"?>
<configuration>
    <system.web>
        <customErrors mode="Off"/>
    </system.web>
</configuration>

The crux of the problem is MVC uses a global action filter named HandleErrorAttribute for the same purpose. But because HandleErrorAttribute takes care of the error and never passes it along to ELMAH. Oddly, the “official” solution to this is a question on StackOverflow. Essentially the suggested solution from the author of ELMAH is to inherit HandleErrorAttribute and override the OnException member so that the exception is passed to ELMAH.

But it seems odd that this wouldn’t be a core part of the ELMAH package given how many people want to use it on MVC. Shouldn’t this be turned into a DLL that can be dropped into a project like ELMAH? It should. And it has.

The ELMAH.MVC NuGet package by Alexander Beletsky takes care of the HandleErrorAttribute and even adds some configurable authorization to the ELMAH controller. It’s all nicely documented on the projects GitHub page. Simply install the NuGet package, delete any existing HandleError filter you have and you’ve got ELMAH working in MVC.

(One quick note about authorization in ELMAH.MVC. If you look at the source code you’ll see an [Authorize] attribute on the controller. This isn’t the core ASP.Net attribute, it’s a custom ELMAH.MVC attribute that works with the web.config settings.)

However there was one configuration I missed the first time around. I had ELMAH deployed to a test environment and hit an error. Thinking I was so smart for having taken the 90 seconds to install ELMAH I went to https://myapp/ELMAH only to receive a 403 authentication error. I hadn’t configured the ELMAH.MVC authorization yet so I wasn’t sure what was going on. Only after a little googling did I find my missing configuration, allowing remote access.

<elmah>
    <security allowRemoteAccess="1" />
</elmah>

If you do allow remote access, make sure you also turn on the authorization.

security

Securing My Elephant Brain: Passwords

“There are only two types of companies, those that have been hacked and those that will be.”

Those are the words of Robert Mueller, the head of the FBI, from the keynote address at an international computer security and cryptography conference, RSA Conference 2012. With that in mind, the security of My Elephant Brain has been a major focus of the last few weeks. While the project is still in it’s infancy it’s important to build a stable, secure foundation. This is the first in a series of posts about security considerations developers need to take into account, and how users can recognize when their security isn’t being taken seriously.

Customers will be trusting My Elephant Brain with two sets of content that need to be protected. One is the content they add in the shape of flash cards to be memorized. Photos with names and faces have a privacy value that needs to be protected to the utmost. But it’s the other set of content they give us, or any web application, that’s arguably more valuable. Their account information, including usernames and passwords.

Because users often reuse username/password combinations on multiple sites breaking into one system and uncovering passwords could be a treasure trove of personal data. It’s up to system developers to make sure that even if user data falls into the wrong hands, it’s unusable. To understand how to do that, it’s best to start at the most insecure end of the spectrum, plaintext passwords.

Plaintext Passwords

Most lay users will simply assume that when they enter their username and password into a login form, the website is simply looking up the stored password associated with the username and comparing it with the one submitted in the form. This is hopefully not exactly what is happening. The problem in the previous process is that the password was stored in the database in ‘plaintext’ exactly as I had originally written it. If that database is ever to fall into the wrong hands my password is free to be misused without any effort on the attacker’s part. How can the average user tell if their password is being stored in plaintext? One surefire way to tell is if a website emails you your original password when you ask to recover you password. A third party should never be able to recover the original password you gave them. But if the website itself can’t recover your password, how do they log you in?

Hashed Passwords

We need some means of making an original password unrecoverable, but still allowing legitimate users to login. To do this we arrive at the second level of password securing, hashing. “Hashing” means running known text though an algorithm that garbles the text, but is reproducible ever time.

hashing illustration

When a user registers for a service their password is hashed and stored in the database. The next time a user gives a website their username and password to login the same hashing function is used, and the result of the hash is compared with the original value. If an attacker gains access to the passwords database they’ll be met with a series of gibberish that can’t be used against a user on other sites where the username/password combination has been reused.

However, because hash functions will always result in the same value given the same input it is possible to pre-compute a sequence of possible passwords then compare this to the database of stolen passwords. If this set of pre-computed passwords is based on existing words this process is known as a ‘dictionary attack’ because it assumes your password comes from known dictionary words. If attackers take the time to generate every possible combination of letters and numbers up to a 16, 64, 124 character word the set of hashes is known as a rainbow table because the resulting hashes cover the entire spectrum of passwords, much like a rainbow covers the spectrum of visible light. On occasion, this can be valuable and used for legitimate purposes. If you’ve ever forgotten your Windows password there are ways to run a rainbow table against the hashed password and discover a match. However, this technique could also be used for nefarious purposes.  Indeed, this was a primary criticism of LinkedIn when their password database was compromised this year. They had encrypted the passwords with a popular hashing algorithm function known as SHA1 (Secure Hash Algorithm), but even the laziest attacker could download an existing rainbow table and be able to recover the original passwords. To guard against this, we need to add an extra level of randomness.

You Want Salt with That

We could ask users to make their passwords 128 characters long, but they’d probably balk at that. Instead, developers can add that extra complexity without any additional demands on the user. This extra random complexity is known as a salt. Simply add an extra randomly generated string to the user submitted password, then hash the result.

salt and hash illustration

The salt is then saved alongside the user password in the database, and the next time a user tries to sign in the salting and hashing process is repeated and the result is compared. Because every user gets a unique salt the number of possible hashes is astronomical and pre-computing a rainbow table for an entire database is indefeasible.

At least, it used to be.

The Current Art

Computers just keep getting faster. It’s a great feature of technology that we can generally rely on this years crop of silicon to be faster than last year. However, that brings with it problems for security. The history of encryption is littered with hashing algorithms that were secure at their time, but became obsolete when hardware fast enough to ‘brute force’ them became available. Brute forcing simply means trying every conceivable input until you end up with the desired result. This is in contrast to an ‘elegant’ solution that finds the solution much more directly. Graphics cards are actually specially suited to crunching numbers really fast, and high end cards have been shown to crunch upwards of 700 million hashes per second. So the current crop of password storing techniques rely on algorithms with names like PBKDF2 (out of the above-mentioned RSA), bcrypt, and script. They essentially repeat the salting and hashing function enough times that there’s a slight delay, say half to a full second, for a single password. This might not seem like much, but it makes brute-forcing passwords impossible, while being tolerable for systems to log users in. The official PBKDF2 specification suggests 2000 iterations, but iOS 4+ devices go through 10,000 iterations before settling on a password.

What you Should do as a Developer

The above is a gross oversimplification of the process. The truths are much more complex and even slight mistakes can open vulnerabilities. Fortunately most decent frameworks come with modules built by people that are passionate and well trained in security. Use those modules and don’t try to reinvent the wheel. My framework of choice ASP.Net MVC uses PBKDF2 by default to store passwords.

What you Should do as a User

No one will care about your security as much as you will. Use strong passwords (the longer the better) and stop repeating them. I was guilty of this until recently but now I autogenerate my passwords in KeePass and use ChromePass to automatically fill in passwords on webpages. Not only do I have a secure password for each site, but I never forget a password anymore because the password never exists without being first generated in KeePass.

New Balance 860

Buying Shoes in the Land of the Undersized

If the Wikipedia article about average human height is to be trusted Canadian men average about 175cm (5’9″) whereas Chilean men hit a mean of about 170cm (5’7″). When I arrived it was fun to be the tallest man in a room. Everything feels slightly too small. Subway cars are slightly downsized versions of Toronto, and elevator manufactures must asume people are stackable because they never fit more than three people shoulder to shoulder. But it’s not a staggering difference so after a while I stopped noticing it. Until I had to buy shoes.

I’ve been running a lot since I arrived in Santiago. There’s a race almost every weekend and lots of paths in the city. I even did okay in a local trail race a few weeks ago, which make me want to do better.

282110_449697821764238_1786575663_n

Boxing Day morning I went for a run up San Cristobal. I missed a cutoff for the trail and took the looooooong way up on the road. I’m glad I got to see it, but by the time I got home I was feeling it. My feet had taken quite a beating and upon closer inspection, my shoes were the culprit. I’ve been running in them for about 8 months, so it was time for a replacement.

‘No problem’, I thought, ‘I’ll go to the Costanera Centre (one of the nicer malls I’ve been in). They have shoes stores.’ Costanera is a mall on par with Yorkdale from Toronto, and sometimes it’s nice to go there if only to feel like you’re in North America again. And they certainly have shoe stores, but the shoes they had were a different story.

Size 10.5. If you want anything larger you’re out of luck. And with my size 12.5s that means I was stuck. I don’t know if it’s because it’s the end of the 2012 calendar, but they were just fresh out. Nike, Adidas, Brooks, and (my favourite) New Balance all carrying wide varieties of running shoes sized 10.5 and under. One brand did seem to be available in larger sizes, but it was Asics and I’m haven’t been pleased with the GT-2170s I’m retiring so I wanted something new.

And I also realized pretty quickly that while I didn’t have much problem pointing at the model on the shelf and sputtering out ‘do-ce punt-o cinc-o’ (twelve point five), getting any extra advice across the language gap wasn’t going to happen. I had to know what I wanted and what I was looking for.

I’ve been through a lot of pairs of shoes over the years, especially since I started doing marathons in 2010. I’ve experimented a lot with footwear brands but I keep coming back to New Balance. They’re robust, supportive, and just feel right. So to ease my pain I decided I’d just look for the 1190s (high performance, mild stability) or 860s (everyday trainer, moderate stability). I looked for New Balance retailers in the area and lo and behold they had a store all to themselves! Only problem is it was out in Las Condes, which is a bit of a hike East of downtown.

[map address="Avda Vitacura 5656, Santiago, Chile" ]

For those playing at home, try to find the Santa Isabel metro station. That’s where I live.

But it was a part of the city I hadn’t been to so why not take a trip out there. Las Condes is a richer neighbourhood and always nice to look around. Looking at the Google Maps I saw there was also a mall that made Costanera look like a flea market so I figured I’d drop in there as well.

Holy cow Parque Arauco (the malls name) is nice.

Parque Arauco

Lots of outdoor restaurants. Cool boulevard style storefronts. High end stores. Las Condes and Santiago Centro are literally worlds apart. It’s like a different universe every time I’m out there.

In the end the mall didn’t have any shoes for me. Again, only up to 11, except for Asics. Seriously, nobody wants those shoes.

But the New Balance store had my 860s! In a size 13 none-the-less.

New Balance 860

They’re not the flashiest in the world, in fact they’re oddly similar looking to my old shoes, albeit a little cleaner.

Shoe Comparison

New Balance 860 and Asics GT2170 side by side.

I took them out for a light run tonight and they feel great. Great support and reasonably responsive. Happy to be reunited with an old friend.

My Elephant Brain Web Dev Agile Board JIRA Google Chrome_2012 12 27_21 12 33

No battle plan survives contact with the enemy

Today I was listening to an episode of the .Net Rocks podcast featuring Venkat Subramaniam. Venkat is a developer and a professor who advocates for an Agile approach to software development . Around 20 minutes into the podcast Venkat said something that really struck a chord with me.

I definitely value the word plan as a verb, but the plan as a noun becomes obsolete as soon as we create it.

Anyone that’s written software in an enterprise environment before knows the pain of an evolving specification. As the joke goes, walking on water and writing software from spec are easy, so long as both are frozen.

But to expect all requirements and details of a system to be flushed out ahead of time is unrealistic and unfair to the subject matter experts defining the spec. Agile methodologies recognize this and embrace the evolving nature of a project. You want a new feature? Great, tell me where it falls in with other priorities.

But that doesn’t mean it’s a good idea to start every day without any sense of direction. The process of planning helps us uncover issues with features that might not have been apparent at first glance. At My Elephant Brain we’re using Atlassian‘s bugtracker Jira with the Greenhopper agile extension. It’s a great tool to organize remaining work and plan for development sprints.

My Elephant Brain Web Dev Agile Board JIRA Google Chrome_2012 12 27_21 12 33

Importantly, it tells us when our goals for development sprints are falling off-track. See those red and yellow indicators? That means there’s work we had planned on completing in a previous sprint but it’s not done yet. As a noun, the plan is now broken. But at a verb, we’re free, in-fact beholden, to do something about it.

Which brings me to the title of this post. After Venkat’s comment, co-host Richard Campbell  pulled out this quote from 19th century German Field Marshall Helmuth von Moltke the Elder:

No battle plan survives contact with the enemy.

Now I’m certainly not suggesting any customer should be treated as an enemy, but be prepared for your users to use your system in ways you never could of imagined and don’t hold onto your well crafted plan in the presence of contradicting evidence.

single elephant with name

From Fit with Friends to My Elephant Brain

In my previous post I went over the events right up until Start-Up Chile actually began. We’ve come quite a ways since then, both as a business and getting settled in Chile.

June and I arrived in Chile on Monday October 22nd after 15 hours worth of air travel and layovers. Atlanta is an enormous airport by the way. We checked into a two bedroom apartment I found on AirBnb. Decent little two bedroom with two bathrooms as well.

[map address="Gorbea 1953, Santiago, Chile" ]

After a brief nap we decided to take a little tour of the new city. We wandered the city for a bit but we were both too tired and too confused to reasonably absorb anything.

The following day we spent most of our time looking at apartments. Renting in Chile is pretty painful without being a local so most SUPers go with one of the placement agencies. At first it may seem annoying to have to pay a commission, but there’s so much paperwork, and Start-Up Chile is such a stickler for documents that unless you’re very lucky, it’s probably worth it. I was one of those lucky ones. I messaged everyone on AirBnB that had a one bedroom available (June and I wanted separated places to escape to) and ended up in a finding a fantastic little place not too far away from the offices and in a decent neighbourhood. My land lady Celia has been absolutely fantastic and I would strongly reccomend anyone coming to town for Start-Up Chile should look her up at CozyApartments.

[map address="Argomedo 65, Santiago, Chile" ]

While were in the East end (Providencia) of town looking at apartments, June pulled out her guidebook to find a place for dinner. We ended up at Le Flaubert, a little French place on a side street, and had one of the best meals I’ve ever enjoyed. At first we thought the prices were a little steep, then we realized it was $6000CLP (about $12CDN) for a bottle of wine, not a glass. The wine here is fantastic, btw.

Enough Play, Time for Some Work

On October 24th we had our first official days of Start-Up Chile. 5.2 (the second half of wave 5. The first started October 4th) loaded into a presentation room in a building owned by CORFO, the government agency in charge of economic development in Chile that runs Start-Up Chile.

We were given an overview of the program and how we could expect things to play out for the next month. We were told about demo days and community involvement. We learned about reimbursements and whatever it is Chileans speak (it’s not Spanish). And we also pitched.

These were really informal pitches. Usually no more than one or two sentences describing what problem we were solving. At the time we were still Fit with Friends, a social fitness app meant to encourage workplace activity. Mostly it was a chance to hear where everyone was from. Lots of Latin Americans, but also a heap of Brits, a few from Asia and even one from Australia.

I say ‘at the time’ because even when June and I arrived were weren’t completely happy with Fit with Friends. It wasn’t clear how it would make money, and we didn’t have enough expertise in the fitness industry. We also hadn’t been able to settle on a name because we had heard Zynga was issuing cease and desist orders to any company using “-with Friends” to protect their ‘Words with
Friends’ game. They probably didn’t have a case, but they’d bury a small company in legal bills and we just weren’t willing to fight for an idea we didn’t love.

So over the weekend between introductions and our first real pitch June and I brainstormed possible ideas. In the middle of a list June had been building for some time was an online tool to help people remember people’s names. It was inspired by a story from the early days of the online retailer Zappos when they built an internal tool to learn the name of everyone in the company. Something about it just leapt off the page to me. I had been fascinated by tools that optimized how we learn and remember since reading an article in Wired about SuperMemo, software that uses a technique called ‘Spaced Repetition’ that schedules memory tests as to not overwhelm the user. Before that, I had read a book by a memory champion (they exist) that described all the tricks to learning faces, or memorizing a deck of cards. I still recall memorizing the top 10 banks in Europe using the Roman Room system.

Certainly software existed that took advantage of some of these techniques, but it was usually klunky desktop software that took no pride in it’s usability. Furthermore, nothing was using those tools specifically remember faces, let alone targeted at the enterprise. June and I were meeting dozens of new people every day, and this was the perfect way to validate our ideas and test with a captive audience.

So we bought MyElephantBrain.com and got to work preparing a pitch deck for the following Monday. In startup terms, changing an idea that isn’t working is known as a ‘pivot’. But in the words of one of our colleagues down here, ‘to pivot you need to leave one foot on the ground.’ Our change of product was a complete departure from what we had applied with, so this was more of what David Cohen of Tech Stars calls a ‘leap.’

Start-Up Chile introduction demo pitch order.

The presentation order from the introduction pitch day. I changed the name as soon as we took the stage.

The pitches were incredibly interesting. There were teams  that were tackling hard medical issues like diabetes and pacemaker reuse. Other teams were looking at big data analytics to encourage environmentally conscious purchasing. Others still were creating companies to sell unmanned aerial drones to take pictures from literally a birds eye view. All of this was taking place in what we could call our home, away from home, away from home, the Centro Movistar Innova. The co-working space most Start-Up Chile teams are based out of.
The greenhouse room and incredible roof screen of the Centro Movistar Innova

Yes, that’s a giant video screen for a roof.

When it was My Elephant Brain’s turn to pitch June and I took the stage and presented our idea as a team. Clearly everyone else was struggling to learn all the new faces and names because as we described our product the nodding induced whiplash in a few cases. We were still brand new as a company and idea, so just assembling the slide deck had clarified the product in our minds. It was great to get in front of such a receptive audience and commit to delivering a product to potential customers.

Since then, Santiago has been a whirlwind of paperwork, networking and coding. We’re currently getting ready to give a proper internal pitch on Monday December 3rd.