All posts by Gerard L. Petersen

LearnWith: Concept to Implementation – Docker Development Environment

In this installment of the LearnWith series I create a standalone development environment using Docker and invite you along on the journey of working through the process outlined here. I go from having a vague idea of what I need with very little prior Docker experience, to a working solution. Rather than be a tutorial on Docker, the focus of this article is on the method and reasoning behind getting to a solution. I do present a solution at the end containing all the notes and explanations gained from following the process. So if you’re here for that, this article is not all theory, I’ve got you covered too. Come LearnWith me.

NOTE: If you are here just for the solution, skip to The Implementation section.

Defining the Problem: The Why

I’ve been working on Project ︎◼︎◼︎◼︎◼︎◼︎’◼︎ ◼︎◼︎◼︎◼︎◼︎ for a while now. So far, it has a Front End which is a little baby skeleton of a website and a browser extension; both of which are supported by a data API. The website is a web server running NodeJS, while the API is made up of Elastic Search and another web server running Java.

For the next part of Project ◼︎◼︎◼︎◼︎◼︎’◼︎ ◼︎◼︎◼︎◼︎◼︎, I’m creating an Editing Suite to manage the source data the Front End needs to work. To support the Editing Suite I’ll need a web server, a queue, queue processors and an a second API composed of a web server and a database.

Getting to the problem… Imagine running the full system on your local machine; the Front End and the Editing Suite. A minimum of 8 processes would need to be running on the same machine. That’s a lot of starting and stopping of services and a lot of port management. I currently need half of that and I’ve already started losing track which exact processes are needed for specific parts to work.

This very close to an actual conversation I’ve had when doing an impromptu demo: “… and after the extension is installed you see a list…? Where’s the list?! Ahh, I forgot to start the web server. Refresh and…. hold on, forgot to start elastic search…? Refresh and …Ngggggllff!! I changed the port earlier… Restart and refresh… What’s wrong now…? I’ll show you another time….”.

As any system grows, there comes a point when you need spend time on managing the complexity to continue being efficient.

Fortunately that demo scenario I described was to an understanding fellow dev friend, so not a big deal. So far I’ve not had any significant problems dealing with the complexity. Doubling the number of processes, doubles the complexity of the system, which also doubles the points of failure. As any system grows, there comes a point when you need spend time on managing the complexity to continue being efficient.

Side note: For Devs that don’t have any love for project managers, managing complexity is a part of what they do. They manage the complexity of coordinating different types of people doing different things that are all part of something larger. It’s not easy by any means. Shout out to my PM friends!

To summarise and to state concisely why we’re fixing this problem and what the proposed solution should be working to fix:

  1. Working in the development environment of the app is becoming complex.
  2. Multiple services all use the same port sometimes causing clashes.
  3. Getting a service running is tedious and error prone.
  4. Managing different versions of software for each service is difficult on the local machine.
  5. Versions of software installed on the local machine may clash with software needed for other projects.

Additionally this is going to be used for development, so ideally the solution should not fundamentally change the development process too much.

Defining the Problem: The What

We just described what we don’t want. Let’s describe it in the positive, let’s describe what we do want:

  1. Different parts of the app (the Front End and the Editing Suite) can be run independently.
  2. Simplify the starting and stopping of services.
  3. Every process needed will start up if it’s needed for a service to function correctly.
  4. Each process can have it’s own software version.
  5. Changing a file locally must still change the file represented in the output.

We’ve described what an outline of the solution should look like. This where come up with different technologies and evaluate them based off of these criteria. In an ideal world you’d go with one that has the most merit. In the real world, your situation (money, time, politics, available skills) often guides your choice. I’ve done this before using Vagrant. This time, as the title suggests, I use Docker. For the sake of brevity, and because this isn’t an article on the pros and cons of Docker vs Vagrant, let’s assume an analysis has happened and we’ve verified Docker fills all 5 of the requirements above.

Service Architecture. (If I had a child they’d have drawn it like this. I don’t have a child, so I had to draw it like this myself.)

Referencing the diagram above, we’re getting to the details of the setup we need. A successful implementation would mean we need all the following running in docker containers:

  1. An instance of the Java Application
  2. An instance of MySQL
  3. An instance of RabbitMQ
  4. An instance of the Python Worker Application

Additionally the following constraints would need to be satisfied.

  1. The Java application must able to communicate with RabbitMQ.
  2. The Python application must be able to communicate with RabbitMQ.
  3. The Java Application must be able to communicate with MySQL.
  4. Altering the Java code on the local machine must alter the code running in the container.
  5. Altering the Python code on the local machine must alter the code running in the container.

Note on technologies chosen: The choice of technology to build your project in, is in some cases arbitrary. I chose MySQL because amongst other things, it’s free, open source, stable, and a relational database that matches the requirements of my data. I’ve worked with it before and it’s more than good enough to get the job done. There may be better a database but does it really matter? Everyone has a bias. A few of the biases/reasons I’ve heard are “I know how to do it this way”, “It just feels right”, “Google does it this way”, “We’ve always done it this way”, “I don’t trust other people’s code”, “It’s cheaper and easier to find developers”, “I was here first”. Some of those are valid, others not. The process should be: have some options, build consensus around one or more of the options, choose one, implement it.

I chose Java and Vertx because I wanted to broaden my skillset. I could have used PHP or NodeJS and the result would have be the same. If any juniors are reading this, if someone is telling you your programming language is inferior, they’re likely gate keeping. If you press those people, you’ll generally find in most cases they’ve barely used the technology they’re criticising. Some of the criticisms might be valid, take what they’re saying with a pinch of salt, get a second opinion and take that with a pinch of salt too.

I chose RabbitMQ quite frivolously. I’ve heard it mentioned and it’s the name I’m most familiar with when it comes to queues and queue processing – even though I’ve never used it. That and it’s also open source and free. I might find it can’t do what I need, I doubt it, but if that happens I’ll just swap out the message transfer part for something else.

As an aside: If you find value in using open source software, make an effort to support those communities. Where would the world be without them?

Python arguably has the best support for Natural Language Processing so I chose that for this specific worker. There may be other workers that work better in other languages. Though it might make sense to keep your stack as small as possible.

Ultimately everyone has a bias, I’m showing mine because this is meant to be an honest peak behind the curtains of software development. As I mentioned, your situation can dictate your solution. If I make a mistake on this project, no one will die. With that in mind, my approach is: give something some thought, do that something, maybe make a mistake, learn from it, improve, update the implementation.

Preparing for Implementation

We know what we need to do, but we know nothing about Docker. For us mortals that mostly deal with common problems, we’re usually not the first person to try and solve a problem. And even if we are, chances are someone has done some work on the subject before us and we can build on what they’ve done. Maybe someone has written about it, maybe there are some tutorials, some online courses. All of these things can help us get to where we need to be.

Think of learning the terminology of a technology in the same way you’d ask for directions in a country where you don’t speak the language. You will probably get there, but various misunderstandings might mean there will be a few wrong turns along the way.

The first thing with any new technology is to read it’s introduction. This will give us a brief understanding of what we’re dealing with and the terminology we need to speak about our solution. The terminology is important because it gives us a way of speaking to the wider community allowing them to be able to understand and help us. Think of learning the terminology of a technology in the same way you’d ask for directions in a country where you don’t speak the language. You will probably get there, but various misunderstandings might mean there will be a few wrong turns along the way.

Docker’s overview page seems the perfect place to get this good initial understanding. Get started with Docker looks like a good next step. And a quick browse of the menu shows a Develop With Docker section. This looks promising! The official website looks like it has all the information we need to get to a solution. I can’t stress how happy this makes me: All or most of the knowledge will come straight from the source; The methods used will be officially supported known ways of doing things; And people already versed in the technology will be more likely to follow the implementation. All good things!

Now to read through the links and run the tutorials posted above. Depending on the time I have available, it’s likely a few weeks will have passed before I get to the next section.

Completed the Readings

I’ve been trying to read during my lunch break and after work. 2 weeks have passed. It would have taken me longer but I’d already gone through 60% of the readings before starting this write up. Most of it was a refresh.

I’ve got lucky with some very good documentation. I’ve read the overview and completed the getting started tutorials. I have enough information to start! I’ve not read the develop with docker section. I’m probably missing a key piece of knowledge to solve the problem completely. So… enough information to start but not enough to finish. I prefer starting as soon as I can. Others may prefer to do more reading. In this case, I don’t to have worry about the piece of string issue because I have already defined the problem. As long as I have that goal in mind, the work I do will generally get me closer to a solution. I also know from the readings, that anything I’ll need to change won’t need significant effort or have significant repercussions.

As I mentioned previously, this isn’t meant to replace the well written tutorials on the web, rather an exploration of the method of reaching the solution. With that in mind, onto the implementation.

Onto the implementation!

The Implementation

Note: If you want to see a step by step evolution of how I got to the solution, take a look a the source code on github. Look through branches ‘Part 1’ through to ‘Part 7’ to see the incremental steps needed to arrive at this solution.

You’ll need to add two files to your project to get it to. A Dockerfile file to tell docker how to package up the code and how to prepare the environment the code needs to run in. And a docker-compose.yml file to tell docker what other services are needed for the app to run and how to run them.

The Dockerfile:

FROM openjdk:8u212-jdk
WORKDIR /app
COPY . /app
RUN ["./gradlew", "clean"]
EXPOSE 8888
CMD ["./gradlew", "run"]

Lets look at this line by line:

FROM openjdk:8u212-jdk
This tells Docker to base my image off of the official openjdk image. This means I will have a specific version of the Java OpenJDK installed before I even begin. Docker will try to find this image on the local machine. If it can’t it will try download it from the docker hub. There are loads of official images on the docker hub you can use in your app.

WORKDIR /app
This tell Docker that the commands following this one will be run in the container from the directory /app.

COPY . /app
This tell Docker to copy everything in the current directory (denoted by the dot) to the folder /app on the container.

RUN [“./gradlew”, “clean”]
This will tell Docker to run the java specific command ‘./gradlew clean‘ (from the previously set WORKDIR) – I run this to make sure the gradle wrapper is available on the container before packaging it.

EXPOSE 8888
The Java application runs on port 8888 and this tells Docker to allow access to the application from via this port.

CMD [“./gradlew”, “run”]
CMD is the command Docker uses to start up your application. In this case to start my Java application Docker will run “./gradlew run” from the WORKDIR

Docker will now know how to build your code into an image and have it be able to run on it’s own.

Next docker-compose.yml:

version: "3"
networks:
  java_to_db:
  java_to_queue:
services:
  java_app:
    build: .
    volumes:
      - './:/app'
    ports:
      - "4000:8888"
    depends_on:
      - mysql
    networks:
      - java_to_db
      - java_to_queue
  mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    networks:
      - java_to_db

If you’ve not seen yaml before, it’s a text file format where the number of space before the text has meaning. If something has more spaces than the line before it, that means it is relating to the line before it. So in the example java_app and mysql are sections that belong to services. Let’s continue line by line:

version: “3”
Tells docker what version of the docker file structure we are using. Different versions have different sections and capabilities.

networks:
This section defines the list of networks and lets Docker know how to set up these networks. A network is used to allow communication between services and the outside world. The lines below network ‘java_to_db:‘ and ‘java_to_queue:‘ tell Docker to set up two networks with the respective names.

services:
Under this section we put all the process we need to run. MySQL, python, Java, RabbitMQ would all be defined under this section.

java_app:
This is a name for the service. The name itself can be anything and has no specific meaning. However you may need to refer to it in your application so make it something meaningful.

build: .
This is tabbed into the java_app section meaning it’s a command for the java_app. This tells Docker to build run all the instruction in the Dockerfile in the current directory. (the one we defined above).

volumes:
We’ll do volumes and – ‘./:/app’ together. Volumes is part of java_app and volume usually means refers to data storage such as files. – ‘./:/app’ falls under volumes. So, with these two lines we’re defining the file storage for the java app. You might remember ./ and /app from the COPY command in the Dockerfile. The copy command copied the all the code at the time the command was run. If any changes have been made since the code is now out of date. – ‘./:/app’ is called a bind-mount and tells Docker that we want to have the current directory in place of the /app directory on the container. This means changes made in the local directory linked in the Docker container too.

ports:
Also part of java_app. This and the line below, – “4000:8888”, map port 4000 to port 8888. What this means is that by visiting port 4000 on the (virtual) hardware it runs on, Docker will make sure all data that transfers through 4000 to port 8888 on the container.

depends_on:
This section is used to determine the order in which to start the services. The line below depends_on tells us that the java_app should wait for the mysql service to be ready before it starts.

networks:
Sitting under ‘java_app‘ this tells Docker java_app needs to talk to everything in the java_to_db and everything in the java_to_queue networks. ‘java_app‘ won’t be able to communicate with anything anything else.

mysql:
This is the start of a new MySQL service. The service has the name mysql but could have been anything. I mentioned earlier has is important. In this case when trying to connect to MySQL from the Java App, we need use the service name, ‘mysql’, as the hostname.

image: mysql
This is tells docker to create a service using the official MySQL image.

Other than ‘networks‘, the rest of the commands in the mysql section setup mysql to run in a specific way, you can find more details on the official MySQL Docker image page.

And that’s it. We’re finished! That’s everything needed to a development environment running in Docker.

Reflecting on the Goal

Are we finished? Let’s look back at what we set out to do. Let’s look at what we have:

  • An instance of the Java Application
  • An instance of MySQL
  • The Java Application must be able to communicate with MySQL.
  • Altering the Java code on the local machine must alter the code running in the container.

And what we we still need:

  • An instance of RabbitMQ
  • An instance of the Python Worker Application
  • The Java application must able to communicate with RabbitMQ.
  • The Python application must be able to communicate with RabbitMQ.
  • Altering the Python code on the local machine must alter the code running in the container.

That looks like more than half of the original plan is still missing. How in any way is this finished?

The Business Answer: Priorities change constantly when working on a project. Things outside of your control often affect what you’re doing on the project. Perhaps something your boss asked for, perhaps something a competitor has done now means something very important yesterday, has had to be moved out of the way to make place for something else today. I purposefully put in an extra bit to show how a modular iterative approach to solving a problem can mean that even though we’ve only done a piece of the work, the solution in it’s current state still helps us move forward. If we come back to the solution later, we can pick up where we left off.

The Truth: I’m currently the only developer building the proof of concept for Project ◼︎◼︎◼︎◼︎◼︎’◼︎ ◼︎◼︎◼︎◼︎◼︎. It’s taken a long time for me to write this article. I’m doing all this while still having a full time job, so it’s taken maybe a month or more. On top of that, I’ve not allowing myself to continue with the code until I finish this documenting the solution. Having the solution means I am unblocked and I’m REALLY excited to get back to writing code again! Having said that, I feel like I have solved the whole problem conceptually. All the core concepts needed to add Python and RabbitMQ are already included in the solution. Adding them in will a copy and paste job with a little bit of reading to get the specifics of RabbitMQ. If there was another developer waiting on the full solution, I’d definitely have made sure it was complete.

Finally…

Don’t be discouraged if you get stuck. Take a break and come back to it later. While writing I had two moments where I got stuck and despondent. My internal thoughts were: “The solution isn’t doing what I want! I should quit!”, “Is Project ◼︎◼︎◼︎◼︎◼︎’◼︎ ◼︎◼︎◼︎◼︎◼︎ even worth doing?”, “If I can’t even do this small, how dare I write an article and to give others advice?”. Most people I’ve worked with think I’m a good software engineer. To be honest, I am happy with my skills and I do have my moments but I’ve never ever felt like “one of the best developers I’ve worked with“. If that person is right and I am a good developer, I say this to let you know if you’re feeling discouraged, just remember, we all feel that way sometimes, just keep at it.

That’s it! Thank you for reading. I hope you learned something with me and had fun doing it.

LearnWith: Practical Problem Solving

Practical problem solving (Illustration by myself)

In this first LearnWith in the series, I outline my general approach to practical problem solving. In it I detail how I go from knowing nothing to knowing what needs to be done. You might notice I didn’t say “go from knowing nothing to knowing everything”. Knowing everything, although rewarding, almost always isn’t the goal. The goal is to solve the problem.

If you’re trying to know everything about a vast knowledge base before making an attempt at solving a problem, you may be falling into what is called analysis paralysis. We’re getting ahead of ourselves though. Analysis paralysis is usually an issue for someone who has somewhat of an idea of what they’re dealing with.

Define the Problem

If you find yourself worrying and doing nothing or not knowing where to start, you probably haven’t defined the problem or defined the problem well enough. Defining the problem is the first step to solving it. It’s important to define what success looks like right at the beginning. It’s how we know we have finished and we can celebrate a job well done.

The BBC Horizon documentary “How Long is a Piece of String?” can be used as an example why we need to define success. For a seemingly simple task such as measuring a piece of string, we might end up doing measurements in imperial when it might have been needed in metric. Alternatively the measurement might not have been accurate enough, it was measured to the nearest centimetre instead of millimetre. Perhaps nanometres or smaller is the level of accuracy needed. We then need to keep in mind that at a higher levels of accuracy, the room temperature has a big effect on the result of the measurement. What temperature should it be measured at? 0 degrees? Celsius, Fahrenheit or Kelvin?

As you can see, there are MANY possible results to be gotten from measuring a string. When finding a solution, it’s important to be practical. Measuring the length of the string to the nearest cm is much less effort than measuring to the nearest nanometre. The first needs a tape measure and the other needs a laboratory with expensive machinery. Should we do both? If you need the more accurate measurement, the first example is wrong; if the coarse measurement is good enough, the second example would have wasted a lot of money. Both ways measure the length of the string, both provide a correct answer, but is either answer useful?

To define The What of success in a practical way, you need to understand The Why. Understanding why you’re trying to solve a problem gives you the context needed to understand which solutions bring you closer to the result you want. In the string example, let’s say we’ve found out that we’re trying to provide a friend of a friend with a new shoelace. This means we won’t need the expensive laboratory equipment; the tape measure method should suffice. Understanding how the string’s length was part of a bigger goal, we got enough context to rule out the expensive method.

So far so good. However, the problems we deal with are never as one dimensional as measuring a piece of string. What about more complex problems?

Breaking it down

Achieving a complex goal can mean the implementation will need a non-trivial solution, one that requires multiple complex moving parts working together in a harmonious way. If you’re struggling to understand the problem or keeping the whole problem in your head all at once, it’s a often a sign you need to break the problem into smaller discrete problems. Even if the problem you’re working on is not that complex it’s usually a good idea to break your problem into smaller pieces. Breaking your problem up allows you to focus implementation on one aspect at a time with the knowledge that all other aspects of the problem will be done later or, if you’re working in a team, by a different team member.

Once you’ve broken each problem into smaller chunks, you can start solving each smaller problem, keeping in mind the context of the larger problem. This should see you ultimately solve the bigger problem altogether.

Tips

Things don’t always go as planned. You often won’t be able to do things the way you’d intended. This will force you into finding a creative solution that might modify how that solution fits into the larger context. If and when you get new information, revise how it affects the overall goal.

Let’s assume a goal of baking a lemon cake. The ingredients are 1 cup flour, 1tsp baking powder, 1 egg, 10ml lemon juice, … etc. You’ve started putting the ingredients together but you realise you’ve bought baking soda instead of baking powder. The shops are closed so you can no longer buy the baking powder, how will you get the cake to rise correctly?! Fortunately, you’ve remembered something from baking school, you remember baking soda and lemon juice can be substituted for baking powder. Crisis averted, but will extra lemon juice make the cake too sour?

In the example, we came up with a creative solution that solved one problem by being able to get the cake to rise but potentially causes another by changing the flavour. You now need to decide if this affect the overall outcome and what further steps need to be taken if any. Maybe add less lemon juice so the flavour stays the same or maybe you prefer a slightly tangier cake.

Try and solve the ‘difficult’ parts first. If your solution hinges on a something that you aren’t sure is possible, get an answer to that first. Do this by breaking down that part into the smallest piece possible, make a prototype or a proof of concept, and get the answer you need. This way you’ll know early on if what you’re planning is viable. Take your learnings and build from there.

Although it’s good practice, you don’t need to understand the full solution upfront. If you’ve broken the problem down in a discrete and self-contained way, you shouldn’t need to understand the solution to all parts of the problem before starting. Often times working on different areas can inform how to approach related but separate parts of the problem. Other times taking a step back by doing something else can give you insight you didn’t have before.

Next in the LearnWith series, I will take specific problems I am dealing with and apply what I have outlined here. By the end of that of that hopefully we will have learned something together and you will have seen how I got to that point.

LearnWiths

Twitter is a weird place. I see so many people sharing things and appearing to be amazing. By the way, I choose the word “appearing” not to detract from their achievements but because appearances are not always what they seem. I have dealt with that topic and my feelings around them before.

My feelings now, are around wanting to share and wanting to help but of not being sure if what I have is share worthy. I’m probably selling myself short but I feel like I don’t have much specialised knowledge to share. After 13 years in the industry doing everything I don’t see how this can be case but it feels like whatever I can say has been said before and probably much more succinctly.

Having said that, I believe you should focus on your strengths when trying to do the best you can. The one thing I have been told and has been implied at me on many occasion, is that I excel at is picking things up quickly.

This is, I think, is what I can share. I can share with you the journey of how I learn these things and the findings and conclusions I come to along the way. I can share with you my my process and my reasoning while trying to solve a problem. Apparently one learns better when one is trying to explain something to others, so this process will help me too. Over the next few years while I bring my project to life, I will be tackling many things I have no idea about and I will be writing about them here. We’ll be learning together. I invite you to come Learn With me.

Down time

I’ve haven’t been feeling good for a while. Earlier on in the year from about June to November things were tough. Things are better now by the way. So don’t worry about me too much. This is not a cry for help. Just some therapeutic writing.

I blame a lot of things for me not doing to well… or I want to blame a lot of things.

As an aside, as part of me doing better, I’m trying to use more positive internal language and blame is often a negative word. “Don’t point the blame” or “They’re playing the blame game”. So blame has (I believe) a negative connotation in some environments… sigh… let me get out of this tangent quickly. My thoughts want to dictionarise the word blame for this article, which is not the point of this. My intent is with the use of the word blame; I want to use the word in the factual sense without the attached emotion, if that’s possible. As in the cause of something…. I guess by definition blame is negative in a sense. Blame is only used if something is a problem. The word blame is never used earnestly when you’re accusing someone of doing you a good turn. “I blame you for me winning the lottery!”

Time to move on.

So… as I said, I want to attribute blame to a lot of things: Work, my diet, my sleeping pattern, lack of exercise and of course myself.

I am doing a lot of work on my the myself part… which is why things are starting to feel better. Drinking less, eating less, some exercise (my knees are fucked so I have to take it easy there) meditation (which I should be doing now instead of writing this) and maybe some other things I can’t think of right now. The last step is to now form those habits so that it’s not a Please-Jesus-I’ll-go-to-church-if-you-let-me-pass-this-test-I-didn’t-study-for!!! level of desperation when I use these techniques. My goal is to take care of myself on a daily basis. Marathon-not-a-sprint type mindset.

Meditation is amazing by the way. It really fucking works. It helps me with sleep. It helps me with will power. It helps me with mood. It helps me with clarity. It’s like giving a little bit of time back to yourself. It allows me to feel emotion. The unfortunate thing is that I feel anxiety 10x stronger but it also allows for me to feel happiness. I’d much rather feel anxiety than nothing at all. Meditation also allowed me to win more of the internal motivational battles I have with myself. So that means more exercise and better diet… most… a lot of the… some of the time. And you know what? Some of the time is ok. It’s better than the none of the time I was doing before.

Anyway. I was hoping to talk about work as I don’t quite have that bit figured out yet. But I really need to go meditate. I have not done it in 2 weeks now. And like and still want to get some reading in before bed. I am reading the Robert Jordan’s the Wheel of time. It’s great, I am hooked. I am on the 7th…?… book now?

Good night.

I really hope you’re well. I miss you all.

Thank you. You are too kind

So. Here I sit. On the train. Typing on my traveltop; that’s my netbook, I call it that because I normally only use it when I am away on holiday. I am not on holiday today. Today I just wanted to write. I’ve been wanting to write for some time but just haven’t sat down to do it, until now.

There’s quite a lot I wanted to write about. One of the topics being my adequacy as a developer and the adequacy of myself in general. But… I mostly forgot what it was I wanted to say. I know when I originally thought it, it was stunningly profound.

Something else I wanted to write about was the duality of self, of my self. I read in Stephen King’s book, On Writing, that you should not use language that does not “fit” you. I believe I follow his advice in most cases when I write. What I’ve noticed that the words that “fit” when I write are different to the words that “fit” when I speak. I would never verbally use the word vocation but when writing, talking about my vocation feels natural. It’s interesting that my vocabulary should change depending on the medium of communication. Then again, the more I think about it, considering the little I’ve learned about brain function, it seems perfectly normal that your vocabulary should change when medium of communication changes.

I remember now what it was I wanted to say. I constantly battle with myself and my self, trying to figure out if I am good at what I do or just above average.

I have always thought of myself as being bad at things or at least not good enough. And when I do get complements, I frequently brush it off because “they don’t know what they are talking about as they are laymen” or if they do know what they are talking about, “they don’t have enough specific knowledge on the niche area of the subject that they are somehow misinformed” or even simply “just mistaken”. Take an example, being a developer, Dev Leads, Tech Leads, peers, even a few Technical Directors have told me that my skills are valuable. And the vast majority of every company I have worked for has asked me to come back and work for them again, stay on longer or asked me to come on full time. Some of those companies are even well known for having a really strict hiring policy. Somehow even after all that positive affirmation, I still don’t think I am worth my weight in salt (I wonder what I would do with 80kg [£69.34] of salt).

Anyway, I realised something the other day. I’ve always compared myself to people better than me. I’m not sure if all people do this, but with me, I only compare myself to people better than me, or at least people who I think are better than me or have a skill I want or am envious of. If someone isn’t better, they won’t feature on my personal scale of comparison. I am generalising but do you realise what that means? On my scale, I’m always worse than everyone else. If the scale was based on 1 – 10, I’m always a 1. How crazy is that shit?

I think it’s sad that this is how I choose to define myself. Now that I know about it, I think I can change this. I don’t know if this is normal. Is this normal? I don’t think it can good for the self-esteem. It does explain some aspects about myself though. For a start, it explains is how I am unable to accept a compliment: If in the past I received a complement, in my head I appreciated your kindness anyway and thanked you, almost always in an awkward way.

How do I fix this? How do you change a mindset? Is actively knowing about it and being aware enough?

Update: I saw this online today, looks like it’s a part of the human condition.

aBqoY

 

The dreams

I had the smoking dream again. I was smoking like a chimney. I usually only have the smoking dreams if I have been drinking. I think this time it’s stress related. The new job is … it’s not kicking my ass… but nobody is listening to me. Or it feels that way… but yeah… I am not here to complain about the job… I am gonna do the best damn job I can do with what I am given. So yeah… I think I am having smoking dreams because I am stressed.

Another dream that happened right after the smoking dream was a continuation of another dream. This was the 3rd instalment of that dream. In the first part, I was synthesising something amazing. A formula that, when ingested, would provide the user with increased strength, increased agility and invulnerability. The penultimate step in the creating the formula is to actually drink the solution and use the body’s natural chemical processes to actually produce the compound. The final step is the filtration and distillation of the urine you get from the ingestion. I know the formula works because you can feel the effects on the first ingestion but they are very short. Ingesting it the second time, increases the effects with respect to how long it lasts and intensity.  Unfortunately it’s still temporary. However if you ingest very large quantities, the effects can be permanent.

In the 2nd instalment of the dream. I went back to the clothes cupboard that I was keeping the formula in… because that is where you keep it… obviously. I took a half-swig of the luminous yellow liquid in the test tube only to find it was mostly urine with little to none of the active ingredient in. What’s worse is that, something you’d expect to be able to tell from just looking at it is, it had shit loads of broken glass in it. I’d say a seemingly endless amount of broken glass, because I spent most of the rest of the dream pulling medium sized shards of glass out my mouth trying not to swallow. It seemed as though as soon as I got to half way empty, my mouth would somehow actually still be full with glass. When I finally did get 97% of it out… the dream faded out…or faded in…I am not sure… what ever happened, it faded.

Urine, don't drink! Also... broken fucking glass!

The 3rd instalment found me in front of the clothes cupboard with a test tube of yellow liquid. I realised this was a continuation of the Formula Dream, so I took a swig of the yellow liquid. It had no effect, and it tasted like it was all pretty much urine. And to my surprise because I couldn’t tell by just looking at it, there was fucking glass in it. This was the point where I realised, “That’s right…I have fucking done this before!”… I spent the next long unit of dream time trying to get the glass out my mouth. When I got enough of the glass out, my brother came up and asked me where the blood came from and why there is broken glass in my mouth. At which point I thought I’d tell him the truth. But, how do you tell someone, even your own brother, your mouth is bleeding because you have been drinking your own urine with some broken glass mixed in? That is where the dream faded out with me not yet telling him, but making the decision to tell him about the formula. And at the same time realising “Where was the other test tube? The one with the actual concentrated formula in? Because I know I did some proper distilling in part 1… and this yellow stuff was just being kept to run the filtration again to ensure I have extracted all the active ingredient out”.

Where did it go? Did someone take it? Who could have known about my experiments? Are my dreams being watched? There wasn’t enough to make it permanent why steal it? Who could have taken it?

Job Interviews of 2011

I’ve been getting kicked in the teeth a lot recently. A while ago I went for a few job interviews. I even thought about going permanent for a while. In fact I even applied for a few permanent jobs. I applied for 3 places. One of them, www.playfire.com, a gaming social network) I really wanted to work at. Another, Assanka, I thought would have been good for me as it would have been able to shift my career path slightly. And also a 3rd company, Webgains, a good place with a focus on improvement.

Webgains said:~ “No thank you”. They were very nice and respectful, which was nice. Originally I thought that I interviewed really badly that day and would have done better another day. But when started being honest with myself, I played the interview back to myself in my head and realised that I have a surface level knowledge of enough of things to enable me to find the answer rapidly when the technical requirements exceed my current level. So in short, with the knowledge I had then, I probably would have never interviewed well. There is an argument against that level of questioning and that my strategy of “knowledge + Google” should be enough. I would have to disagree, the role was for a senior position where I would be mentoring other. Einstein once said, “If you can’t explain something simply, you don’t understand it well enough”. If that’s the case, I was in no position to be teaching others. Looking back in it now it not getting the job has only been a blessing, it showed me how I can improve and I think had I gotten the job I think I would have been really by the content and industry.

Assanka was plain shit shit (double shit). When I made the application, I got this automated response:

Thank you for your application to join Assanka. You have now passed the CV review stage and we would like to invite you to complete our online skills assessment.  The test takes at least 2 hours for a strong candidate so, not wishing to waste anybody’s time, we have only extended this invitation to you because we feel you have a good chance of being the right person for the job.

Once you submit the test, it will be scored and you will receive a response within 7 days. If successful, we will invite you to an interview.”

I thought the email rude. I decided I wouldn’t take the job. In my head imagined them offering me the job and me telling them “No, I don’t like the elitist attitude portrayed in your communications. I don’t care how big you are or how many awards you have won, you are dealing with people and I want to work in an environment with decent friendly people and if this email is representative of your culture, NO”. So to make my visions come true I decided to do the test.

The test was terrible. They showed blank boxes you clicked on to view questions. The questions ranged from easy to difficult with headings for multiple disciplines. You choose your own subset of questions to answer. Once you clicked a question, you HAD to answer it, you couldn’t read it and leave it for later. ANSWER NOW or FORFEIT were the options. If I want to show that I have SOME knowledge in other fields so I could be useful in more than one place, no luck. You can’t read a question and say: “Ok too easy, everyone knows this, I will be proving nothing by answering, move to the next” or “Too difficult, answering this now is going to waste time I could use proving I am competent elsewhere”. Forfeit is forfeit. I had 0 human interaction, so I had no idea what skills they valued in their programmers. Did they use this same test for everyone or just programmers? Do they expect me to have knowledge in all the disciplines? So my strategy was to spread myself thinly across all the disciplines. Most of the questions were worded confusingly forcing you to make assumptions about what they were actually asking.

A week or so later, I got an email. (I can’t find the email so I’m paraphrasing slightly):

“Dear human,

Your test results indicate you would be good at: MOLESTING GOATS.

Unfortunately we don’t currently have a position for: MOLESTING GOATS.

Thank you”

They told me no!? I WAS GOING TO TELL THEM NO! Hmmm… I should have said no before I took the test. No helpful feedback wrapped in a healthy dose of snark for them. It’s no wonder they have the word ass in their name.

Playfire, I’d been eyeing for months and months. The first time I saw they had an opening I wanted it so badly I talked myself out of applying for fear of not getting it – weird logic, I know. Playfire are a cool startup, doing interesting things. If I got the job not only would I would be programming, but also surrounded by content I love. I foresaw much potential and have no doubt (with the correct guidance) they’ll do really well. I talked myself into applying.

I was nervous sending them my CV, nervous doing the tests and nervous waiting feedback. I always found nervosity to be a good thing. It gets me to perform better. That made me confident… or less worried. (Nervosity is ACTUALLY a word!? Here I thought I was being funny by making up words).

I know you can be very thinly spread when running a start-up. So I was surprised and humbled when one of the Co-Founders took time to get into an email conversation with me.

I got sent the test. There was a strong emphasis on performance, something that doesn’t always take precedence in agency work. Even the test questions were mathematically worded. I was never an algorithmic byte jockey, so the test challenging and new to me. It was great.

They very next day after completing the test, I got a reply. Here’s part of it: “you’re clearly a strong developer, but unfortunately not quite what we’re looking for in this role”. I suspect the co-fo was just trying to not hurt my feelings. All-in-all dealing with playfire was most pleasant. I really do hope they do well.

That’s it… I haven’t written in a while… I wanted to write and this came out. The you have it, go about your business.

Argos are not ripping you off

LOL. I wrote this whole article originally thinking that Argos was ripping customer off. My maths was wrong and I thought it was a bum deal. Yes, blindingly simple maths I know, I should be ashamed. I think my only saving quality in this case that I am sceptical enough to check it is what they say it is.

I was just on my way to the store to get Rage. I don’t have a Game near enough to me so my options are Argos or Sainsbury’s. I have bought a few games from Argos and I have seen this deal before. “Get 800 Xbox LIVE points for just £4.99 with selected Xbox 360 games”. Sounds like a good idea. If I’m buying the game anyway I might as well get some cheap points. With all the amazing Xbox live arcade games coming out, you can never have enough points.

Is this a deal? Yes, as in deal with it bitch, I am not ripping you off.

I nearly took the offer on two occasions. On both occasions something said: “Wait, don’t do it, check first”. But I could never remember the actual price for Xbox points. So today I was at home saw the deal and I decided to check if the offer was actually in my favour. On Xbox itself, points cost £8.50 for a 1000. That works out to something like 0.0085 cents per point. With the offer, it works out to 0.0062 cents per point. So as you can see, you are throwing away saving a whole 0.0022 cents per point. That is throwing away saving a whole 1.81 for the 800 points.

Anyways. Off to get Rage I go, and maybe some cheap points too, if Sainsbury’s can’t beat £48.17 (£49.98 minus the saving).  :)

The present is pretty decent too

The world we live in is an amazing place. A lot of the time it’s a really shit place but it’s also an amazing place.

When I was younger, I watched, read and heard about these Ancient civilisations that had these amazing technologies. I speak in general terms but the civilisation the captured my imagination the most was the Ancient Egyptians. I loved those mutherfuckers. I had a pretty decent sceptical mind as a kid so when I was told something along the lines of “We have no idea how the Pyramids were built” or I even think I was told “even with the technology today we would be unable to build the pyramids” I didn’t really know if I should believe it but there may be some truth to it so that added to the mysticism.

An amazing ancient race with amazing technology, so many uncovered secrets and awe-inspiring Gods. Even the Gods’ names are awesome (awesome in the true sense of the word): Ra, Amon-Ra, Anubis, Isis – All names fit for a God. Anubis has the head of a jackal. No offence to Jesus or anything but Jesus has a normal boring persony shaped head with, now that I think about it in my later life, stupid looking hair. (If you have hair like that in the depiction of Jesus, you look stupid – I’m not dissing Jesus, I am dissing you. So Christians with a persecutory complex can vent elsewhere). And Ra, Ra had the head of a falcon. Pretty sweet.

Anyway, in my imagination Ancient Egypt was when I wanted to live. This era of Ancient Egypt had mummies and curses, and untold treasure, and hidden traps and sweet Gods, which I mentioned, and loads of other cool stuff. I don’t think I am conveying the idea that well… but Ancient Egypt to me was Tintin and Indiana Jones and Jewel of the Nile and many other things all mixed into one… and all of these ideas were captured in a single symbol, the Pyramids.

The Pyramids symbolised… oh and lets not forget about how the pyramids line up with the stars, so like, mysticism AND science…. I forgot what I was going to say about what the Pyramids symbolised.

Anyway, in my mind that was it. Nothing the human race could ever do architecturally would ever or should ever be considered at the same level as that of Ancient Egypt. In my mind if we died out and a future civilisation discovered the buildings of our era, they would think them ugly and unimpressive.

I no longer believe that to be the case. Look at these fucking amazing pictures. I came across these the other day. Some of which I would consider to be architectural wonders. Now I believe if we all died tomorrow and another civilisation inherited the earth, they would be fucking impressed.

I'm speechless by it's beauty

So yeah, I guess I just wanted to tell you how I came to the conclusion that the world is an amazing place. It’s mostly really shit, but it’s amazing too.

//Image Source