Python to Objective-C: Initial Reactions

Here are some of my initial thoughts and reactions coming from a scripting (Python) background on Objective-C and iOS:

  • Overwhelming API documentation. To me this is just a case of hunkering down and mugging like a good A level student.
  • Obsolete Stackoverflow answers. With every yearly release of a new iOS version, it kinda makes an entire generation of SO answers redundant. The game changes very quickly
  • There’s quite a fair bit of plugins out there in the wild. Initially, I was rolling my own image downloader and caching mechanism only to find quite a few libraries out there doing exactly that (and better) already

Some lingering questions still on my mind which I hope to be cleared up as I go along:

  1. In a segue, when to use push and when to use modal
  2. Modification of UI elements in the storyboard or in the code
  3. Passing on values from one view controller to another. Direct assignment in the prepareForSegue method or what?
  4. How do I quickly check in XCode what methods are needed to be implemented for a new delegate or data source
  5. The difference between @class and #import
  6. strong/weak references in declaration of properties
  7. Project and folder layout hierarchy
  8. Paths and inclusion of new files

Updated with answers!

  1. The way I think about when to use push or modal segues is to use a RPG example: if you’re exploring a dungeon and you go into a room, if the room leads to more rooms, use a push segue. If the room is a dead end, use a modal segue.
  2. Where possible, reduce code bloat and use storyboard modifications. This is kind of subjective
  3. Direct assignment is fine. I think I was being overly paranoid with this question
  4. cmd + click is your friend. Then look for @required methods. This should get better with experience
  5. General rule of thumb: if you need to alloc/init something, you have to import it. @class is almost always used only in header files
  6. When in doubt, use strong
  7. I’m actually still figuring this one out
  8. If you click on a file and goto the file inspector, you can see a Location drop down that allows you to set the path. The thing that threw me off initially was that your project path directory need not match your Explorer folder path directory.

A Review of PyCon SG 2013

Pycon SG 2013

PyCon SG 2013

As an Organizer

I was helping out with this year’s PyCon Singapore 2013. It’s my first time helping out in an event and I enjoyed it greatly. Here are some of my takeaways:

  1. It is better to present something simple very well than to present something hard/challenging poorly
  2. The conversations between the talks are the best parts of any conference
  3. Coffee is a must have
  4. The common mindset is to assume all the speakers to be domain experts in their fields. But it’s actually ok and acceptable for ‘newbies’ to take the stage and give it a go. It is only in ‘failing’ and feedback from the community does the person learn and grow. This ultimately also benefits the community in the long run
  5. Impostor syndrome is very real
  6. It’s the people and newly formed relationships that determines whether a conference is successful or not. As an organizer, your job is to provide “points of contact” such that there’s a good balance of talks and actual interaction.
  7. Juggling between beginner vs. expert level talks and managing the resulting expectations is probably the hardest aspect of the conference. An idea could be to run two tracks: one focused on beginner stuff an the other on more obscure/advanced stuff.

As An Attendee

I can only mention the talks I went to, so here they are:

  1. @_nishad‘s create_awesome_api(time_limit=’1 week’), talked about the tech schema at Plivo. They essentially have a proxy server using flask and gevent which in turn pings another server running Django. The Django server just serves as a provider of API endpoints via Django-tastypie. On the side, I found this cool monitoring app that shows the uptime of your API.
  2. @tsudot‘s talk on Graph everything! kinda confirmed my belief that going Graphite is the best solution for monitoring analytics. He also introduced Graphene which is a wrapper around d3.js for prettier visualizations.
  3. @rohit01 covered building a dashboard using Shinken. Shinken is essentially a Python rewrite or Nagios which is written in C. I suppose once we start hitting more servers, setting up our own service monitoring system will be the way to go.
  4. @vanzaj‘s talk was on data management for scientists and he  introduced the problem of keeping track of binary data and its resulting output for a scientist running experiments. Essentially, he is unable to reproduce his thesis results based on the experiments he ran years ago which was a WTF!? moment for me. It’s an interesting problem in academia which no one seems to have solved properly yet. His open source tool, dacets, is trying to solve this problem.
  5. @sajnikanth‘s talk on blackbox testing was very well presented. Talking from a QA perspective, he covered Selenium in a very entertaining manner — a word not frequently associated with testing. He’s also involved with Holmium.
  6. Vikram’s talk on Music beat aware interactive physics simulation. This was interesting to me as I’ve not really been exposed to the musical aspects of Python before. He demonstrated what a sine wave sounded like and went through basic modules such as the pyo library which is used to do audio stuff with python. He had a funny moment when he was demo-ing a high frequency sine wave and quipped: “No one has ever died from a Python interpreter”. lol!!
  7. @mbrochh spoke on writing reusable django apps. Surprising, this was the only django talk at PyCon SG. There’s also a django tutorial too. He has a nice template for making apps. Lessons learnt the hard way from making over 65 django apps. Generally speaking, a well written app will simply work out of the box by:
    1. pip install
    2. add to installed apps
    3. add to urls.py
    4. load template tag
  8. @wesmckinn‘s talk was obviously on data. It was a high level talk about Python and Data and where stuff is heading. It seems to be moving towards a cloud based collaboration context with pretty visualizations. Also, interesting to know that  “data warehousing as a service” is on the rise. Case in point is Amazon’s Redshift.

Also, thanks to all the startups that attended this year’s Startup Booth. They are:

It was interesting to hear how different startups were using Python in their stack. From NLP at Infotrie, to gevent-socketio at Beautiplan and even the story of a language migration from PHP to Python by Flocations. Also, this could also be the first public announcement of Billpin pivoting into the payments space. @ruiwen gave a Steve Jobs-esque vision of what Paypal might look like if they were to start today. A frighteningly ambitious idea but they certainly possess the tech and business smarts to execute it.

Thanks to all the organizers and sponsors that have made this conference possible. Also, a big thank you to Plug-In Blk 71 for letting us use their rooms for our meetings.

Lastly, a shoutout to our friends from Tokyo. Thanks for visiting! PyCon APAC will be held in Tokyo from 13 – 16 September. Ping @ryokamiya for more information.

PyCon SG 2013

Recently started a new project and ran into this error while installing pycrypto. Every single post seems to just say: install command line tools with the latest version of Xcode and your problems will magically go away!

Well, if that works for you, great, if not, let’s get down to the root of the matter.

(greedychimp)nai@nyc:~/Work/greedychimp(develop○) » python                           18 ↵
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

For some reason, my virtualenv was using Apple’s version Python which was compiled with llvm-gcc. We don’t want that, we want the clang compiled version of Python to get this to work.

(greedychimp)nai@nyc:~/Work/greedychimp(develop○) » port select --list python         1 ↵
Available versions for python:
	none (active)
	python25-apple
	python26-apple
	python27
	python27-apple

Seems like I had the clang compiled version of python already but hadn’t set it as default.

(greedychimp)nai@nyc:~/Work/greedychimp(develop○) » sudo port select --set python python27
Password:
Selecting 'python27' for 'python' succeeded. 'python27' is now active.
nai@nyc:~ » port select --list python
Available versions for python:
	none
	python25-apple
	python26-apple
	python27 (active)
	python27-apple

Great, now when I type Python in my terminal outside my virtualenv, I should see a clang compiled version of python which I do.

nai@nyc:~ » python
Python 2.7.3 (default, Oct 22 2012, 06:12:32) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

However, my virtualenvs are still using the old version of Python. So I have to recreate the virtualenv and specifically tell virtualenv which Python to use.

nai@nyc:~ » mkvirtualenv --python=/opt/local/bin/python2.7 greedychimp
Running virtualenv with interpreter /opt/local/bin/python2.7
New python executable in greedychimp/bin/python
Installing setuptools............done.
Installing pip...............done.
virtualenvwrapper.user_scripts creating /Users/nai/.virtualenvs/greedychimp/bin/predeactivate
virtualenvwrapper.user_scripts creating /Users/nai/.virtualenvs/greedychimp/bin/postdeactivate
virtualenvwrapper.user_scripts creating /Users/nai/.virtualenvs/greedychimp/bin/preactivate
virtualenvwrapper.user_scripts creating /Users/nai/.virtualenvs/greedychimp/bin/postactivate
virtualenvwrapper.user_scripts creating /Users/nai/.virtualenvs/greedychimp/bin/get_env_details
[8] 37201
/Users/nai/.virtualenvs/postactivate:disown:15: warning: job is suspended, use `kill -CONT -36852' to resume
[8]  - 37201 done       ctags -f $VIRTUAL_ENV/tags -R $VIRTUAL_ENV/lib/python2.7/site-packages ${PWD}
(greedychimp)nai@nyc:~/Work/greedychimp(develop⚡) » python
Python 2.7.3 (default, Oct 22 2012, 06:12:32) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

So running pip install pycrypto should work now.

Django Create Session Variables in Unit Test

Came across this snippet some time ago but I can’t remember the source. I’ve since used it quite extensively.

def stuff_session(client, dictionary):
    from django.conf import settings
    from django.utils.importlib import import_module
    engine = import_module(settings.SESSION_ENGINE)
    store = engine.SessionStore()
    store.save()
    client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key
    session = client.session
    session.update(dictionary)
    session.save()

To use simply

stuff_session(self.client, {'customer_session_id': '0ABAA842-7E77-2591-3B02-162716195AD6'})

Code Snippet for Django Unit Test for AJAX Responses

View

def api_get_destinations(request):
    if request.is_ajax():
        searchText = request.GET.get('searchText', '')
        maxResults = request.GET.get('maxResults', '10')
        n = int(maxResults)
        cities = ParentRegionList.city\
                .filter(region_name_long__icontains=searchText, subclass=None)\
                .values_list('pk', 'region_name_long')[:n]

        results = []
        for city in cities:
            city_dict = {'id': city[0],
                    'label': city[1],
                    'value': city[1]}
            results.append(city_dict)
        if not results:
            results.append({
                'id': -1,
                'label': 'No Results Found',
                'value': 'No Results Found'
                })
        data = simplejson.dumps(results)
    else:
        data = 'fail'
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)

Test

class TestAPIResponses(TestCase):
    def setUp(self):
        self.parent_region_list = ParentRegionListFactory()

    def test_get_destinations(self):
        kwargs = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
        url = reverse('api_get_destinations')

        get_data = {'searchText': 'Singap',}

        response = self.client.get(url, get_data, **kwargs)
        json_string = response.content
        data = json.loads(json_string)
        self.assertEqual(data[0]['id'], self.parent_region_list.pk)
        self.assertEqual(data[0]['value'],
                self.parent_region_list.region_name_long)
        self.assertEqual(data[0]['label'],
                self.parent_region_list.region_name_long)

A Naive Code Counter for your Django Project

On a whim, I wrote a short management command that counted the lines of code in only the ‘core’ files in my django project and also code count for my unit test which are mostly written to test these ‘core’ files. This excludes html, css and javascript.

from django.core.management.base import BaseCommand
from django.conf import settings

import os

class Command(BaseCommand):
    """
    This counts the code for each app in the project and displays the 
    lines of code of unit test written.
    """
    help = 'Display Project Code Count and Unit Test Code count'

    def handle(self, *args, **options):
        file_types = ['views.py', 'forms.py', 'models.py', 'utils.py', 'tests.py']
        counter = 0
        unit_test_counter = 0
        for app in settings.APPS:
            for file_type in file_types:
                file_name = app + '/' + file_type
                if os.path.exists(file_name):
                    with open(file_name) as f:
                        for row in f:
                            counter += 1
                            if file_type == 'tests.py':
                                unit_test_counter += 1
        print 'Total lines of code in bbox only apps: %s' % counter
        print 'Total lines of code in bbox excluding tests: %s' % (counter - unit_test_counter)
        print 'Total lines of code in bbox tests: %s' % unit_test_counter
        print 'For every 1 line of code written, %s lines of test code is written' \
                % (float(counter-unit_test_counter) / float(unit_test_counter))

Total lines of code in project specific apps: 20172
Total lines of code in excluding tests: 13145
Total lines of code in tests: 7027
For every 1 line of code written, 1.87064181016 lines of test code is written

Source: https://gist.github.com/3566434

What Every New Python/Django Web Developer Should Know in 3 Months

This is a collection of things I think any beginner web developer working on the Python/Django stack ought to know. This assumes zero knowledge in web development or programming to begin with.

  1. Web Related
    1. What is a GET and POST request
    2. 200/301/302/403/404/500 status codes
    3. What is a cookie and how is it used
    4. Learn how to search and read documentation
    5. Basic SEO knowledge
      1. Best book to read: The Art of SEO
  2. Frontend
    1. How a page is loaded in the browser (DOM)
    2. Working/basic knowledge of HTML/CSS/JS – You will learn this by osmosis
    3. What is AJAX
    4. What is HTML5
    5. Basic UX/UI understanding
      1. Best book to read: Don’t make me Think
  3. Python
    1. Write Fizzbuzz
    2. Read Learn Python the Hard Way then an intermediate book like Dive into Python or one of the O’Reilly series
  4. Django
    1. Do the tutorial project at djangoproject.com
    2. Read Definitive Guide to Django Development Done Right
    3. Be able to setup a new project from scratch using virtualenv locally with a skeletal folder structure and settings that caters to a production and development environment
    4. What a view function does
      1. GET/POST paradigm within a view function
    5. What a model class does
    6. What does a template do
      1. What is template inheritance
    7. Basic Regex and URLS
    8. How do urls, views, models and template relate with one another
    9. Difference between model forms and forms
      1. How does form validation occur
    10. How to write a test that tests the view functions, models and utility methods
    11. How to debug and find the source of a problem
  5. Database/Models
    1. How to model Foreignkey relations
    2. How to model M2M relations
    3. Basic data types
  6. Tools in your Employ
    1. iPython
    2. South
      1. How does a migration work
      2. How to do an initial migration
      3. How to migrate subsequent changes to a schema
      4. Trouble shoot migration conflicts
    3. Git
    4. IDE of choice, preferably VIM
    5. Firebug
    6. Fabric
  7. Processes
    1. Deployment process at your team. How it works, what git hooks are used for what purposes. What fabric scripts do what etc
    2. Git Flow
      1. How to add, commit, release, rollback, fix, merg and conflict management
  8. Soft Skills
    1. Communication with product owners
    2. Communication with colleagues
    3. Cultivating a Growth mindset
  9. Graduating Project!
    1. Create a one page Django project that will allow me to:
      1. View all the users on the project
      2. Edit the details of the users
      3. Create a new user
      4. Delete a user

A note on doing too much reading:

Oftentimes as a beginner, we’re overwhelmed by the amount of information we need to do something. The knee jerk reaction, a badge of the fine education doctrines what have been ingrained in us, is to read about the topic/subject. I find this hits a wall of diminishing returns quickly.

For the reading to be truly effective, you need a certain amount of wisdom to absorb it. This can only be done by reading backwards. What this means is that say you’re tasked to create a dashboard page from scratch. In your mind you’ll probably think something like: whoaaaa, I have on idea how to do this. I need to do some research! And then you try to do random reading at djangoproject or various books and then bite off more than you can chew. The human brain has a tendency to make things more complex than it really is. The right question you should be asking in your mind is: how do I first load a page and then present a form on this page to manipulate data? This will make your reading much more directed and effective.