Author: mattchung

  • Learning a new language

    I studied Spanish in high school for four years and 10 years later, I’m embarrassed that I can’t form a comprehensible or grammatically correct sentence.

    I traveled throughout Europe last Christmas and was impressed by the number of bilinguals. Most people fluently spoke a combination of English, French and German. My second language, Vietnamese, however, is barely conversational.

    My Vietnamese stagnated 15 years ago. In elementary school, I was immersed in an after school program where I learned how to read, write, and speak Vietnamese. The majority of my friends spoke the language too, which was conducive to learning the language. But now, I rarely practice and have forgotten the majority of it.

    I was motivated to improve my Vietnamese after traveling to Vietnam last year. I was disheartened by the inability to communicate with my 9 year old nephew; my weak vocabulary limited the dialoge. My cousins taught me new words but by the end of the trip, I couldn’t remember any of them.

    Learning French

    In order to improve my Vietnamese, I started learning French. I figured that if I could learn a lanuage from stratch, I could use the same principles and apply it to learning Vietnamese.

    I searched online for the best methods to learn a new language. I purposely avoided any articles/books that promised short term success (e.g “Perfect French in 30 days”). After reading reviews on Amazon, I ordered Fluent Forever.

    With the books help, I built my curriculum. It cosists of:
    • Learn the international phonetic alphabet (IPA)
    • Train my ears with minimal pair trainers
    • Daily practice with Anki
    • Learn grammar

    Reflecting back at the last 3 months, I’m proud of my progress. I’ve ritualized learning French into a daily habit. I failed in the past due to inconsistency – it was never a habit.

    First French Translation

    Here’s my first translation from the book “French, A grammar based approach“.

    La salle à manger is petite. Il y a quatre chaises et une table dans la salle à manger. Sur la table est une nappe. Elle est vert. Il y a aussi des assiettes, des couteux, des cuillers et des fourchettes.

    Est-ce qu’il y a une tasse sur la table? Oui, il y ya trois tasses et un verre. Les tasses sont petites.

    Qu’est-ce qu’il y a dans les tasses? Il y ya du café dans les tasses. Qu’est-ce qu’il y a sont les verres? Il y ya du vin. Le café est noir et le lait est blanc. Il y ya aussi de la viande sur une plat, et il y ya légumes sur une plat.

    Qu’est qu’il y ya des fleures? Oui, il y ya des fleures dans un vase. Comment est le vasse? Il est joli; il est vert et brun. De quelle couleur sont les fleures? Il y ya rouge et blanc.

    Change in mindset

    “You will never change your life until you change something you do daily. The secret of your success is found in your daily routine.”

    —John Maxwell

    I’ve reframed my expectations. Instead of expecting fluency – both Vietnamese and French – in a short period, I’m building up my vocabulary and grammar; I’m immersing myself with people, books, and videos.

    I look forward to learning more about the people, new and existing, especially my nephew.

  • A short thank you letter to my body

    I’ve been very sick this past week … coughing phelgm, swallowing pain, and battling headaches. Two nights in a row, an uncontrollable cough prevented me from sleeping.

    This morning, however, I awoke without a sore throat. It goes to show you how much I take you for granted when I’m healthy.

    My elation at regaining my health won’t be short lived. This I promise you.

    Ongoing health problems

    Despite converting to a plant based diet in 2014, we’re struggling with intermittent stomach pains. Sometimes, the excruciating pain paralyzes me into the fetal position for more than two hours. It’s the same sensation that sent us to the emergency room in 2005.

    Doctors can’t isolate the problem. Nutritionists suggest conflicting diets. It’s up to you and I to experiment and create a sustainable diet. I’ll continue to jot down foods that cause problems:
    • hummus (gas)
    • cold drinks (bladder incontinence)
    • honey / maple syrup (bladder incontinence)
    • raw lettuce (severe stomach pain)

    I’m fixing more than our diet. I reintroduced mindful eating. This means deliberately counting 60 chews before swallowing. This should help with digestion.

    All of this is going to take time. So thank you for being patient. Thank you for keeping me going. Thank you body.

  • Python progression path – quiz

    Python progression path – From apprentice to guru is a popular StackOverflow post. To categorize whether a person should take his beginner/intermediate course, one of the commentors posted this question:

    python progression quick

    I can better answer this question after reading Fluent Python. Example 1 and Example 2 deal with immutable and mutable data types – respectively. Let’s address each example individually.

    Example 1

    The id built in method returns the object’s memory address. We’ll use this to inspect the memory address for x and ythroughout the examples.

    x and y point to the same memory address when they are first assigned.

    >>> x = 42
    >>> y = x
    >>> id(x)
    4298172632
    >>> id(y)
    4298172632
    

    Because the value of x is immutable (e.g INT) and cannot be modified, by definition, a new memory address is allocated when x is modified. But, y‘s memory remains unmodified:

    >>> x = x + 1
    >>> id(x)
    4298172608
    >>> id(y)
    4298172632
    >>>
    

    Example 2

    Like Example 1, the memory address starts off the same:

    >>> x = [1,2,3]
    >>> y = x
    >>> id(x)
    4299948256
    >>> id(y)
    4299948256
    

    Now that we are dealing with mutable data types, x can be modified in place and the memory address does not change:

    >>> id(x)
    4299948256
    >>> id(y)
    4299948256
    

    Mutable default arguments

    This quiz seems trivial but it isn’t. Understanding this will prevent a novice mistake of using mutable default arguments.

    >>> def update(x, y=[]):
    ...     y.append(x)
    ...     return y
    ...
    >>> list1 = ['a', 'b', 'c']
    >>> list2 = [1, 2, 3]
    >>> update('d', list1)
    ['a', 'b', 'c', 'd']
    >>> update(4, list2)
    [1, 2, 3, 4]
    >>> list1
    ['a', 'b', 'c', 'd']
    >>> list2
    [1, 2, 3, 4]
    >>> update('a')
    ['a']
    >>> list3 = update('b')
    >>> list3
    ['a', 'b']
    >>> list4 = update('hello')
    >>> list4
    ['a', 'b', 'hello']
  • Relearning how to juggle

    I learned how to juggle 15 years ago. I remember relentlessly practicing in my room late into the night. Within a week, I was comfortably juggling three balls.

    Recently, I stumbled across YouTube video of someone juggling four balls and was very impressed. How much more difficult is juggling four balls than three, I thought to myself.

    So, I watched this YouTube tutorial and his pre-requisites to juggling four balls are:
    • Juggle three balls for 1 minute
    • Juggle two balls in each hand for 30 seconds

    In my mind, juggling two balls felt like a step backwards. So, I dismissed his prerequisites.

    I picked up four tennis balls and after 15 minutes of getting nowhere, I grew increasingly frustrated. My years of juggling three balls did not, in fact, make juggling four balls any easier. According to this video, it takes this much time to be able to juggle. Here’s what should be expected:

    • 3 Balls – Days to Weeks
    • 4 Balls – Weeks to Months
    • 5 Balls – Months to Years

    I decided to stop juggling four balls and go back to the fundamentals: two and three ball exercises. I’m glad I did. After spending the first week “starting over”, here’s my progress:

    early attempt of juggling four balls

    In a way, glad that juggling four balls didn’t come easy. Sometimes, you have to go back a few steps to move forward.

  • Belgium terrorist attack and the media

    Belgian was this morning. I send my thoughts and prayers to those in Belgium, but I’m worried about the media’s knee jerk accusations of Muslim terrorists. At the moment, there’s no concrete evidence. But why is the live feed incessantly hinting at ISIS and Muslims?

    I can’t stay updated without feeling the media is inculcating anti muslim propagnda.

    I question the media’s “experts”. The media ensures that expert testimtony aligns with its agenda. Sky News interviewedAnne Speckhard and she immediately concluded that the incident must be related to Salah Abdelslam. I’m not suggesting that it isn’t, but its too quick to point the finger without facts.

    “It’s probably the group that Salah Abdelslam is part of …. so I think they just accelerated their plans … so they wouldn’t get rounded up”, said Anne Speckhard.

    “So you think this is related to the arrest of Salah Abdelslam on Friday and that perhaps that the planned attacks have been brought forward as a result of that?”

    “Absolutely.”

    “One gunshot afterwards and there was one man speaking Arabic afterwords. And then I heard a boom, an enormous explosion”

    I’m disappointed.

  • AWS Lambda part 2 – packaging and deploying

    I received positive feedback on my AWS Lambda presentation in London. This post discusses how to package and deploy your lambda function.

    I’m sure there are other ways but I wanted something simple. This allows me to maintain separate enviroments (i.e “dev”, “production”).

    Makefile

    I use Make to create a package (i.e “sample-app.zip”). The dependencies are installed into a virtualenv which are appended to the package.

    Create the function

    make build-dev
    make create-dev
    

    Deploy the package

    make build-dev
    make update-dev
    
    PROJECT = sample-python-app
    FUNCTION = $(PROJECT)
    REGION = us-east-1
    .phony: clean
    clean:
    rm -f -r $(FUNCTION)*
    rm -f -r site-packages
    build-dev: clean
    aws s3 cp s3://$(FUNCTION)/settings-dev.yml settings.yml
    zip -r $(FUNCTION)-dev.zip . -x *.git* tests/*
    mkdir -p site-packages
    virtualenv $(FUNCTION)-dev
    . $(FUNCTION)-dev/bin/activate
    pip install -r requirements.txt
    cd site-packages; cp -r $$VIRTUAL_ENV/lib/python2.7/site-packages/ ./
    cd site-packages; zip -g -r ../$(FUNCTION)-dev.zip .
    create-dev:
    aws lambda create-function \
    –handler main.lambda_handler \
    –function-name $(FUNCTION)-dev \
    –region $(REGION) \
    –zip-file fileb://$(FUNCTION)-dev.zip \
    –role arn:aws:iam::XXXX:role/$(FUNCTION)-dev \
    –runtime python2.7 \
    –timeout 120 \
    –memory-size 512 \
    update-dev:
    aws lambda update-function-code \
    –function-name $(FUNCTION)-dev \
    –zip-file fileb://$(FUNCTION)-dev.zip \
    –publish \
    delete-dev:
    aws lambda delete-function –function-name $(FUNCTION)-dev

    Lambda deployment package

    Make sure you include all the dependencies in the package. You need to copy the contents of site-packages, NOT the directory itself. If you copy site-packages itself, lambda will not be able to find the modules.

    The contents will look something similar to:

    main.py
    netstorage/
    netstorage/__init__.py
    requests/
    requests/__init__.py

    Testing locally

    Instead of constantly deploying the function, I wanted to test my changes locally.

    When creating an AWS lambda function, you need to specify the handler gets executes. In the gist above, I specify it with –handler main.lambda_handler. So testing locally is simple as:

    if __name__ == "__main__":
        lambda_handler(None, None)
  • Monitoring background processes with SumoLogic

    This post discusses one way we monitor our background process – which is different than how we monitor our web services. It’s difficult when you can’t send a request/poll the service. I wanted something more than checking if the process is alive. One solution we came up with is is using syslog with a log aggregration service.

    Most log aggregration platforms (i.e “Splunk, Log Entries, Sumologic,”) can send an alert if some string (or regex) is found in the the logs. This is pretty common; what about alerting when logs are NOT found?

    Basic Setup

    Our process is managed by supervisor and it logs to stdout. Supervisor logging plugin sends logs to our centralized syslog collector, which forwards the logs to Sumologic. We then configure alerts based off of search results.

    Configuring the alert

    First, create your search (here’s a cheatsheet). Next, configure it:

    • Library -> Edit Search
    • Scheduled this Search
    • Number of results Equal to = 0

    Screenshot:

    Sumologic scheduled search equal to zero/0That’s it. You can integrate this with your Pager Duty account or just have it send directly to an e-mail address.

  • Getting older

    I was standing outside the car, wiping the dogs’s feet when I overheard a voice.

    “Are you a young lady or a man?”

    Did I hear him right? I continued wiping my dogs’s feet and responded:

    “Well, HER name is Metric. And SHE’S a German Shepherd.” I wanted to make it clear that that we were talking about the dog.

    “NO”, he responded confidently. “I’m asking YOU if you are a BOY or GIRL.”

    I turned to Jessica, my fiancée, who was sitting in the car, laughing uncontrollably. I started laughing too.

    You see, I suddenly realized that the the old man was confused by my long hair and it didn’t help that my back was turned to him.

    I couldn’t get mad at him. He spoke his mind – something I fervently believe in.

    Zero Inhibition

    Old people speak their minds. It’s the same for kids. In Master of None, there’s a scene where two kids enter an ice cream shop and start pointing people out by their skin color:

    “Black. White. Yellow. Black. Black.”

    Can you imagine an adult saying that (only person I can think of is my Viet Grandma).

    I am constantly trying to find the balance of thinking twice before saying something and being assertive. It’s an ongoing battle.

  • Putting your mentor on a pedestal

    Presenting at DevOps London ExchangeLast night, I presented (deckslide here) on AWS Lambda at DevOps London Exchange. I really enjoy public speaking, but it wasn’t always that way.

    In fact, I used to hate it – feared it.

    I vividly remember an embarassing instance in high school Spanish. My classmate and I had to do a presentation. I got up, and stood in front of the class for 20 minutes.

    That’s it. I just stood there. I didn’t say a SINGLE word the entire time.

    Fast forward to college. By this time, I really needed help with public speaking. My uncle suggested joining Toastmasters.

    I visited a few clubs and I wasn’t very impressed. But then, I discovered Sherman Oaks Toastmasters.

    I met Peter Bunce. He was very passionate about Toastmasters. He was very discplined. For 20 years, he rarely (if ever) missed the weekly meetings. His entire life was devoted developing the Toastmasters club.

    We used to get coffee and dinner. He assigned himself as my mentor. Honestly, I was hoping for someone else. He was tooeccentric. He didn’t encapsulate all the characteristics of my ideal rolemodel.

    Setting the right expectations

    I’ve always had unreal expectations from those who I looked up to. Peter was no exception. Him being a great speaker wasn’t enough for me. I had unrealistic expectations of what one mentor can offer – let alone any person.

    “If you should end up with a teacher who doesn’t seem right for you, first look inside.”

    —George Leonard

    A note to my mentor

    I sent Peter a message on Facebook this morning. But he’ll never read it.

    Peter Bunce passed away a few weeks ago. I wish that I had reached out to him sooner.

    If there’s someone who mentored you, be it informally or formally, or touched your life in some way, don’t wait to tell them that they moved you. Take a moment to reach out to them, to say thank you.

  • SpeedCurve Library: Travis CI + coverage + tox

    I’m writing a python library (speedcurve.py). At work, we’re using SpeedCurve to track our web performance. SpeedCurve’schangelog reveals can trigger a deployment (and a series of tests). I’m replacing our curl+ansible commands with this. I plan on integrating this with slack as well.

    This project is heavily influenced by github3.py. I’ve been contributing frequently (plan on continuing to) and find it elegant. You’ll notice A LOT of similarities.

    For this project, I want the following up front:
    • Proper Documentation
    • 100% test coverage and flake8 checks
    • Integration with Travis CI

    This post focuses on configuring tox to execute coverage.

    Configure tox + coverage

    Since tox does NOT play nicely with pipes (|), this simple shell scripts checks for 100% test coverage:

    #!/bin/sh
    
    coverage run --source speedcurve -m py.test
    coverage report | tail -n 1 | grep '^TOTAL.*100%$'
    

    This goes in tox.ini

    [testenv:coverage]
    commands =
        ./coverage-check.sh