≡ Menu

Home on the Range

I’ve been reacquainting myself with Objective-C by getting up every day at 5 a.m. starting two weeks ago and going through Big Nerd Ranch‘s Objective-C Programming chapter by chapter. It’s been an nice refresher.

71OV1De7mnL

BoldrDash

My 6th 5K Race (1:52:31 – 4 miles instead of 3.1)

Grit N Wit

My 5th 5k obstacle race (1:04)

GritNWit

Samurai Sprint

My 4th 5k obstacle race (1:07:12)

10519189_432414380231325_4377948800529479188_o

Reviver Challenge

My 3rd 5k obstacle race (with Katie)

DSCN7018

Parsing with Python

I’ve been given a list of contacts in vCard format of people interested in interactive storytelling. Here’s one of them.

BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//Mac OS X 10.9.1//EN
N:Maya;Bill;;;
FN:Bill Maya
EMAIL;type=INTERNET;type=WORK;type=pref:bill.maya@gmail.com
CATEGORIES:Phrontisterion,Team
UID:bcbea367-d59d-493c-8f28-5f3a524a28b2
X-ABUID:E2B6D1B2-EF7C-4C24-926A-01973C141240:ABPerson
END:VCARD

I want to send out an email to everyone in this list to tell them the Phrontisterion Online blog has been rebooted. There’s somewhere between 30-40 email address so I probably could have cut and pasted each one into a text file but why go the brute force route when when it might possible to automate it. I’ve been thinking about learning Python for a side project so I thought I’d try to use it to parse the file’s contents.

Here’s the code that opens the file and prints out every line.

fyle = open('C:\Users\billm_000\Desktop\Phrontisterion_1.txt')

for lyne in fyle:
    print lyne

fyle.close

But I’m only interested in the name and the email address. These lines are prefaced with “FN” and EMAIL” respectively. So lets just find those lines.

fyle = open('C:\Users\billm_000\Desktop\Phrontisterion_1.txt')

for lyne in fyle:
    nameId = "FN"
    if nameId in lyne:
        print lyne #2

<pre><code>emailId = &amp;quot;EMAIL&amp;quot;
if emailId in lyne:
    print lyne #2
</code></pre>

fyle.close

Here’s the result.

FN:Bill Maya
EMAIL;type=INTERNET;type=WORK;type=pref:bill.maya@gmail.com

So now I just need to parse out the name and the email address from the individual lines and write those lines to a text file.

fyle = open('C:&#92;Users&#92;billm_000&#92;Desktop&#92;Phrontisterion_1.txt')
output = open('C:&#92;Users&#92;billm_000&#92;Desktop&#92;Phrontisterion_Output.txt', 'w') #4

for lyne in fyle:

<pre><code>nameId = &amp;quot;FN&amp;quot;
if nameId in lyne:
    print lyne[3:]
    output.write(lyne[3:]) 

emailId = &amp;quot;EMAIL&amp;quot;
if emailId in lyne:
    colonPosition = lyne.find(':')
    print lyne[colonPosition + 1:]
    output.write(lyne[colonPosition + 1:] + '\n')
</code></pre>

fyle.close
output.close

Mission accomplished.

Bill Maya
bill.maya@gmail.com

It took me about 15-20 minutes to do this (less time than it took me to write this post). Of course Google was invaluable (what did developers ever do before the internet?). Here are some of the pages I used.

I definitely think Python is going to be the next new language I learn when I get the time and the right project.

Most-Popular-Coding-Languages-2014

Phrontisterion Online

This past weekend I officially took over the administration of a new blog dedicated to interactive storytelling – Phrontisterion Online.

I originally created the blog to support Chris Crawford’s Phrontisterion webinars but when those petered out the group decided to use the blog as our main method of discussion. I spent some time this weekend getting it in shape and writing a couple of posts. Hopefully others will start contributing and we’ll get something going.

 

Tuff Scramblers

My 2nd 5k obstacle race – 1:15:05

TuffScrambler_051714_1 TuffScrambler_051714_2

Web Services for Where’s George

The basic architecture of Where’s George will consist of two components – the iOS/Android clients and the web services that the clients call to receive updates on George’s status.

I decided to work on the web services piece first since that’s the area where I have the least experience (I’ve connected to web services from mobile apps in the past but never created one on my own from scratch). Given my C# .NET background I took a look at Microsoft’s ASP.NET Web API.

One of the examples on the site, Getting Started with ASP.NET Web API 2, walks you through the creation of two simple web services to display a list of products and allow you to query the product repository by product ID. Interaction with the web services is done through JQuery in the browser (another technology I’ve had little experience with up till now).

The Product class is a simple Plain Old C# Object (POCO).

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; }
}

This POCO is used to create an array of Products in the ProductsController (which inherits from ApiController instead of the usual MVC Controller class).

public class ProductsController : ApiController
{
    Product[] products = new Product[]
    {
        new Product() { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
        new Product() { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M},
        new Product() { Id = 3, Name = "Hammer", Category ="Hardware", Price = 16.99M }
    };
}

And two methods are also created in the ProductsController, one to get all products and another to get a specific product by product ID.

public class ProductsController : ApiController
{
    Product[] products = new Product[]
    {
        new Product() { Id = 1, Name = &quot;Tomato Soup&quot;, Category = &quot;Groceries&quot;, Price = 1 },
        new Product() { Id = 2, Name = &quot;Yo-yo&quot;, Category = &quot;Toys&quot;, Price = 3.75M},
        new Product() { Id = 3, Name = &quot;Hammer&quot;, Category =&quot;Hardware&quot;, Price = 16.99M }
    };

<pre><code>public IEnumerable&amp;lt;Product&amp;gt; GetAllProducts()
{
    return products;
}

public IHttpActionResult GetProduct(int id)
{
    var product = products.FirstOrDefault((p) =&amp;gt; p.Id == id);
    if (product == null) { return NotFound(); }

    return Ok(product);
}
</code></pre>

}

There’s an index.html page which contains HTML markup to setup the structure of the page – there’s a section at the top where all the products will be displayed in an unordered “products” list followed by a “product” search section where you can type a product’s ID and click a Search button to display it.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Product App</title>
</head>
<body>
    <div>
        <h2>All Products</h2>
        <ul id="products" />
    </div>
    <div>
        <h2>Search by ID</h2>
        <input type="text" id="prodId" size="5" />
        <input type="button" value="Search" onclick="find();" />
        <p id="product" />
    </div>
</body>
</html>

The Web API is called using Javascript and JQuery. The first script tag gets the JQuery library from the Microsoft Ajax Content Delivery Network. The second script tag contains the Javascript code which uses JQuery to make the actual Ajax calls.

&lt;script src=&amp;quot;http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js&amp;quot;&gt;&lt;/script&gt;
&lt;script&gt;
    var uri = 'api/products';

<pre><code>$(document).ready(function () {
    // Send an AJAX request
    $.getJSON(uri)
        .done(function (data) {
            $.each(data, function (key, item) {
                $('&amp;lt;li&amp;gt;', { text: formatItem(item) }).appendTo($('#products'));
            });
        });
});

function formatItem(item) {
    return item.Name + ': $' + item.Price;
}

function find() {
    var id = $('#prodId').val();
    $.getJSON(uri + '/' + id)
        .done(function (data) {
            $('#product').text(formatItem(data));
        })
        .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
        });
}
</code></pre>

&lt;/script&gt;

$(document).ready() detects the document’s state of readiness and runs the Ajax request code once the Document Object Model (DOM) is ready for Javascript code to execute (JQuery uses “$” as shorthand for “JQuery”).

The Ajax request is done using $.getJSON(), which loads JSON data from the server using a GET request to a specific URL. On success, data contains a list of products which a used to create list items for the unordered list.

$(document).ready(function () {
    $.getJSON(uri)
        .done(function (data) {
            $.each(data, function (key, item) {
                $('&lt;li&gt;', { text: formatItem(item) }).appendTo($('#products'));
            });
        });

<pre><code>function formatItem(item) {
    return item.Name + ': $' + item.Price;
}
</code></pre>

});

Which looks like this.

ASP.NET Web Services Products 2

The product search by ID is handled by a find() function that’s mapped to the Search button’s onclick event.

<div>
    <h2>Search by ID</h2>
    <input type="text" id="prodId" size="5" />
    <input type="button" value="Search" onclick="find();" />
    <p id="product" />
</div>

The product ID entered into the text box is concatenated with the uri and is used as as the parameter in another Ajax request with $.getJSON.

function find() {
    var id = $('#prodId').val();
    $.getJSON(uri + '/' + id)
        .done(function (data) {
            $('#product').text(formatItem(data));
        })
        .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
        });
}

If the product ID exists, its name and price are displayed.

ASP.NET Web Services Products 3

Otherwise we display an error message.

ASP.NET Web Services Products 4

The big question in my mind was XYZ

Where’s George

This is George.

George

George is a house cat but when it’s nice he likes to spend time in outside in the yard. Since five people live in the house and there are several ways George can be let out into the yard, the question “Is George in or out!” is frequently shouted between floors, especially when it’s getting dark or the weather changes for the worse.

Where’s George is an iOS/Android app.

WheresGeorgeAppMockup

When someone in the house lets George out they slide the slider from left to right, from the Home icon to the World icon. Everyone who has the app and is connected to George’s social network is instantly notified of his status. When someone lets George in they slide the slider in the opposite direction and everybody instantly knows “Where’s George.”