A Milestone in Language Fluency, and Myself

Published on Sunday 11 August 2019 | 8 minute read

Today I wrote my "Hello world" of the Twitter API - a simple GET request to my profile so could print out my number of followers. What I didn't realise before starting though was that it would become a milestone not only in my development as a professional coder.

The "Hello world"

Using the Twitter API was made pretty simple thanks the package j7mbo/twitter-api-php. As StackOverflow user joren points out, "Twitter's documentation is a disorganized mess" (I should write another time about how messy companies can still become billion dollar companies...), so I was grateful that j7mob had tackled the hard part for us. After installation...

    $ composer require j7mbo/twitter-api-php

... I was then able to do a simple request like this:

    $settings = array(
        'oauth_access_token' => env('TWITTER_OAUTH_ACCESS_TOKEN'),
        'oauth_access_token_secret' => env('TWITTER_OAUTH_ACCESS_TOKEN_SECRET'),
        'consumer_key' => env('TWITTER_CONSUMER_KEY'),
    'consumer_secret' => env('TWITTER_CONSUMER_SECRET')
    );

    $url = 'https://api.twitter.com/1.1/users/show.json';
    $getfield = '?screen_name=forrestedw_';
    $requestMethod = 'GET';

    $twitter = new TwitterAPIExchange($settings);
    $myProfile = $twitter->setGetfield($getfield)
             ->buildOauth($url, $requestMethod)
             ->performRequest();  

    echo $myProfile->followers_count

Cool! I have my number of followers! (For my dashboard.) That's great and all, but having all this in our controller is a real mess. After some tidying up, I reduced the above to:

    \\ use App\TwitterAPI;

    $myProfile = TwitterAPI::me();

Much better. All the extra stuff pulled out into a separate class, which looks like this:

<?php

namespace App;

class TwitterAPI
{
    /**
     * Settings to access the API
     * @return array
     */
    public static function settings()
    {
        return [
            'oauth_access_token' => env('TWITTER_OAUTH_ACCESS_TOKEN'),
            'oauth_access_token_secret' => env('TWITTER_OAUTH_ACCESS_TOKEN_SECRET'),
            'consumer_key' => env('TWITTER_CONSUMER_KEY'),
            'consumer_secret' => env('TWITTER_CONSUMER_SECRET')
        ];
    }

    /**
     * Constructs the API url to visit
     * @param $url
     * @return string
     */
    public static function url(string $url)
    {
        return "https://api.twitter.com/1.1/{$url}";
    }

    /**
     * Build an url string from an array
     * @param array $array
     * @return string
     */
    public static function getField(array $array)
    {
        return "?" . http_build_query($array);
    }

    /**
     * Make a get request to the API
     * @param string $url
     * @param array $fields
     * @return string
     * @throws \Exception
     */
    public static function get(string $url, array $fields)
    {
        $exchange = new \TwitterAPIExchange(self::settings());

        $results = $exchange
                        ->setGetfield(self::getField($fields))
                        ->buildOauth(self::url($url), 'GET')
                        ->performRequest();

        return \json_decode($results);
    }

    /**
     * Get the user object by username
     *
     * @param $user
     * @return string
     * @throws \Exception
     */
    public static function user(string $user_handle) {

        return self::get('users/show.json', ['screen_name' => $user_handle ]);
    }

    /**
     * Get my user object
     *
     * @param $user
     * @return string
     * @throws \Exception
     */
    public static function me() {

        return self::user('forrestedw_');
    }
}

I'm pleased with this class. It has a bunch of granular methods in it, making it all really reusable. For example, the method me() just calls user($user_handle), so I can use the latter to get the profile of any public profile.

A learning resource that really helped me break down my classes into these granular methods was the Laracasts video Testing Email With Custom Assertions. In it, we learn how to create a custom solution for testing email. What we end up with is a custom trait which is build up of lots of little methods that all build off one another. It's great because we end up keeping the code super DRY, which is what makes it so reusable.

I didn't realise that doing this simple coding - it took about 40 minutes to find the j7mbo's package and get it all set up - would show to me how far I've come as a developer.

The milestone

I feel proud. I had a bad burnout from my job as a director of a small charity in November 2017. In January 2018, unemployed and suffering from some pretty full on mental health issues, I started playing with code as a way to have something to focus on. I'd done some coding before, making basic websites and the like, but my knowledge what pretty simple to say the least. I didn't have the foggiest of the differences between php and ruby, for example, and looking back in my notes from around that time I see an entry where I explain to myself the difference between class, function, and method.

On 3 March last year, I discovered Laravel. Around the same time I decided I would have a go at skilling up my coding. I wanted then, as now, to see if anything cool would come up from interfacing my earlier experience as director of a small non profit with the tech world. Maybe use it to take some of the effort out of collecting and organising impact data - it was something my organisation always put a lot of resource into but we never fully got a solution that I feel was robust or easy enough. Since then and talking with lots of people, it turns out that this is the situation in almost every charity. There are way too many organisations out there that full depend on very fragile excel documents - perhaps something to write about in another post. Back to the coding, since then I've become pretty comfortable with a lot of the Laravel framework, and feel I'm developing a really tidy test driven style.

This simple class today however, my own DRY class for extending the functionality of a package with custom methods, feels like a levelling up in my skillset. I felt really comfortable doing it and understood it intrinsically. It's one thing to be able to hack together a working code with copy and pastes. With this, I was writing fluently.

Writing fluently

I've been lucky enough to become fluent in a couple of foreign languages over the years. Hindi first, followed by French. For both, at their peak when I was living in each's respective country of origin, I have at times been taken for a native speaker. Creating the above class today was super reminiscent of one of the milestones of learning a new language:

In the beginning, when you hear a foreign language, there is just noise. A constant stream of noise with no way to discern words. One day, for me after several weeks, your ear picks out a word from the noise. And then the next day or maybe a few days later, comes the second. And then comes the third: The brain is picking up on the syntactic patterns and beginning to discern some simple elements. It's a great moment. At this point, you may be getting the gist of what someone says - "noise ... train ... noise ... tomorrow ... noise ... London", someone is going to or coming from London on a train tomorrow? - but there is no nuance.

More time passes. Separate words start connecting into sentences, and you can start to pick apart the grammar: "Oh! So this word-ending means in the past! That word-ending tells me they are speaking about the future!" etc. At this point, you are also speaking a fair bit, hopefully, but you are taking loads of pauses, your grammar is off most of the time, you are still pronouncing words with your mother accent, and when you do speak you are translating in your head to and from your mother language. But one day, and this is the point I've been working toward, you speak and hear without translating. You're still getting loads wrong, though much less, but the key thing is you spoke without translating. You didn't think what to say, you felt what to say. It was automatic.

It is a milestone, and it is a seriously cool moment. It's as cool as the first time you crack a joke in a foreign language, cultural nuances and all. In that moment, you feel not only the language, but your achievement. It is massively hard, learning a foreign language as an adult. You spend a lot of time lost in conversation, feeling left out, or confused. You don't get jokes until way in. You get stuff wrong. You say the wrong stuff. You have this massive barrier and resistance to getting even the basic things in life done (I remember this time in Paris when I rushed out of a bakery, my eyes flush with tears and face red, because I'd tried a few times to ask for a loaf of bread and the person behind the counter just wasn't getting it. I'd been in Paris for about six months at that time, and just felt so stupid and embarrassed that I couldn't even order a loaf of bread).

The learning never stops

Today, in a small yet beautiful way,I reached that milestone for me in my most recent foreign languages, php. I know the hard work that it's taken to get to this level, and I am proud of it. I know that I have a lot more to learn to get really fluent, and it's cool because I know I will do it because I've already done it with French and Hindi. That sense of anticipation and enjoyment of the learning is wonderful.

I also know that the learning never stops. This is one milestone of many. But with it I have a new comfort in my development skills, I have easy access to the Twitter API that I will continue to extend in my custom class, and I have a great building block for my goal of making impact data more impactful in the social sector - integrating social media and fundraising streams into impact measuring and reporting would be a great why to pull together a lot of important fundraising and communications resources.

It's more than that though. It's also me reclaiming myself. Recovering from the burnout has been tough, to say the least. A lot of my self worth was eroded, and I lost all belief in myself to do well. Today however, I'm a huge way along the road to being back to my best and brightest. I have a health approach to life and career development again, and I am enjoying both again. Immensely. Creating and building a school in India (as I did before) was a massive success, as is its ongoing success, and I'm super looking forward to creating again. I already am.

--

Day 15 of #100DaysOfCode. 40 minutes coding, 1.5 hours writing. Tomorrow: write unit tests to TwitterAPI.

Made by Ed in Somerset. 2019.