Notes on JSON at Work

The book “JSON at Work” by Tom Marrs, it is a great introduction on how to create and use JSON.

It covers topics on how to quickly set up a test server in various languages. A quick introduction to the JSON Format.

Then covers how to use JSON with various common languages like JavaScript (a quick intro to Rest and a setup with json-server), Ruby and Java.

I really liked the part that goes really in detail into JSON-Schema

In the last part of the book it goes into JSON in the Enterprise, that part I mostly skiped as it was not very relevant for me.

I can recommend this book if you have had little or no experience working with JSON it is a great introduction to the subject.

What is good code?

This is one of the biggest questions in programming. Everybody has an subjective answer to the question, as everybody develops their own style of programming over time.

For me good code has to fulfill these 5 criteria:

  1. Correct
  2. Efficient
  3. Simple
  4. Readable
  5. Maintainable

Now lets take a closer look at every criteria and what it means for your programming project

Correct

Code should have one key feature: It should work. Not functioning code is useless code.

Code has a very specific task it should do and it only should do that task. It should not do anything in addition that you do not expect.

Correct code also implies that it was built to specification . If you have a specification, you also can ensure that your code is correct by writing tests that verify that the code is doing exactly that what was specified.

Simple

If you have the choice between a complex expression and a simple expression that solves the same problem. then use the simple expression.

The complex expression is always a big door for unintended bugs. Additionally it makes it much harder to explain what is going on with your code.

Efficient

Efficiency, strongly depends on the values / non-functional requirements of your project.

It means if you can avoid costly operations, duplicate operations or unneeded operations. then you should optimize your code to avoid these kind of structures.

If possible you also should optimize for performance, however for most algorithms you need to decide a trade-off if your code will use a lot of memory or a lot of CPU. Before optimizing you always have to define for what you are optimizing.

Readable

Code is written for humans. Another human should be able to read your code.

If you use complex structures it just makes it harder for someone else to figure out what is going on in your project.

The compiler does not care if the variable is called “f” or “isActive” in both cases the compiler produces the same bitcode. Naming things is very important.

And never forget in most cases you are going to be the one that will revisit the piece of code and you will not know anymore what “f” is, but will immediately understand what “isActive” means.

Maintainable

Code is never done. There are a lot of things that causes that code needs to be adjusted in the future:

  • Additional Requirements
  • New Features
  • Dependency Upgrades

Now you can say, screw the maintainer of the project, you are only concerned about today. – However in most cases the guy that needs to fix something is the guy that created the code in the first place. – So do yourself a favor and write maintainable code.

What does it mean to write maintainable code? Have documentation, encapsulate functionality in a way

Conclusion

In the end good code is whatever you want it to be. If you are working with embedded systems and you want to create the most efficient algorithm, you will probably have other values as when you are working on a Web-Project.

You can define whichever values you want. The important thing is that these values must be clearly communicated to your team. Ideally by you leading as an example the others can follow.

In the end the goal of good code is that your project should deliver on time, suffer from less bugs, new team members can be easily onboarded, the team writes better tests and overall better communication (the specifications have to be more precise) etc.

Sources:

ImageDesigned by Freepik

Visual Studio Code Extensions (September 2018)

Lets take a look at a couple of very useful Visual Studio Code Extensions.

General

Settings Sync

The tool allows you to synchronize your settings on multiple computers and/or operating systems. You need to have a github account and it will create a secret gist in order to sync your settings. Read More

Settings Sync

Code Runner

Basically it adds a small play button at the top of every file and lets you immediately execute it.

Code Runner

Git Lens

Git Lens dramatically enhances the GIT experience in VSCode. Inline display of code authorship, easy comparison with previous versions of the file and many more features.

Git Lens

Code Quality

TODO Highlighter

It highlights your comments that start with \\ TODO: or \\ FIXME:. Additionally it adds a command to list all Todos in your source code so you can identify and complete / fix the code.

If you use a different convention in your codebase you can configure the plugin to fit your use case.

TODO Highlighter

Spell Checker

Basically this complains when you start creating variable names that have no meaning. While ensuring that your documentation does not contain any spelling mistakes.

You can add words to a project dictionary And it is easily expandable to support additional languages.

Spell Checker

TSLint

It uses the local tslint.json and integrates the information into VSCode. You can enable ‘tslint.autoFixOnSave’ that automatically applies the defined rules (that can be autofixed).

TSLint

Theme

Cobalt2

A great dark theme with high contrast color choices. Personally I do not follow the official documentation on how to set up the theme. (Too many steps and it requires the font Operator Mono that costs 200USD )

Cobalt2 Theme Official

VS Code Great Icons

Well better Icons for VS Code

Great Icons

Image: Designed by Freepik

Gayle McDowell – Cracking the Coding Interview

The book “Cracking the Coding Interview” helps you to survive the famous ‘technical interview’. Major tech companies like Google, Amazon etc. use these types of interviews to figure out if you can program.

Overall even with the book your chances are slim of passing the interview. – In any case most of the questions are the usual university preparation questions for the most broadest subjects in the field of computer science. So a lot of theoretical stuff and low-level programming skills. – The questions are in a way stupid – but what do you expect? they are questions that an HR person can ask you that have no merit or value in your day to day work.

Basically prepare yourself for this:

You probably should use additional resources if you really want to pass this type of interview. Mostly things like hackerrank or codewars.

The book however is a really good starting point And it is nice that for every topic there is a short introduction about what is important and how to approch questions from that topic.

Interview Process

The HR person will look for four things:

  • Analytical Skills
  • Coding Skills
  • Technical Knowledge
  • Culture Fit / Communication

“Prior experience” – is not needed, you put that already on your CV.

Of course the entire process is riddled with tons of mistakes and false negatives – simply because the process does not figure out if you can actually do the job. However the few people that survive the process – are probably candidates you can position anywhere in your large corporation.

Whiteboards are used to focus on ‘what is really important’ – translation: it is easier and quicker to set up an whiteboard than an actual IDE. Get ready to get maybe judged for making minor typos even though ‘the interviewer does not care’ – subconsciously he is judging you.

Before the Interview

Get the right experience

  • Try to take classes with big programming projects
  • Internships: Try to get some work experience
  • Build something in your spare time (=> Github)

Write a great resume

Keep your resume to 1-2 pages, HR People spend very little time reading it. But it needs to be perfect so they dont throw it out due to small things.

Write strong bullet points

Use the formula: “Accomplished X by implementing Y which led to Z”

Leave out stuff

You are applying for a programming job, you probably know how to use Office etc. be conservative which programs you list Same is true for all the programming languages, list those that are relevant and are widely used.

Be aware of the stigmas that are associated with languages. Some languages like Visual Basic while they are used and even if you know the language on an expert level it is mostly seen as that you have less experience than a language like Java/Python etc.

Certifications – Usually a waste of paper and most people do not see it as relevant. (in the field of computer science)

Behavioral Questions

Prepare your past projects ask yourself for each project

  • What where the Challenges?
  • What went wrong?
  • What did you enjoy?
  • Who lead the project? Did you lead the project?
  • How did you resolve conflicts?
  • What would you do differently?

During this phase of the interview try to create a dialog about how your new employer deals with certain issues. You need to interview the company if the company would fit to you or not.

Focus on you not your project, however you still need to show that you can work well with others.

When you are talking about your past projects you should use the SAR principle

  • Situation
  • Action
  • Result

Ensure that during your stories you can show

  • Initiative
  • Empathy
  • Compassion
  • Humility
  • Teamwork

And of course sprinkle in shows how you succeeded.

Technical Questions

Well you need to get the book for all the questions, but about 90% of the book are questions on various topics with well written answers.

Conclusion

The book is really useful when you are applying for big US-Tech companies. However for German-Tech companies the advice in the book is rather limited as they do not use the ‘technical-interview’ in the hiring process. (It produces too many false negatives and developers are rare)

It only helps you if you are attempting to pass the “technical-interview” and you basically need about 1 year of training prior to your actual interview to pass the interview. Basically the ‘technical-interview’ is a skill only needed to get into a couple of companies.

If that is not your goal your time is much better spent contributing to open source and creating your own projects as you will learn more ‘day-to-day’-skills.

Despite all of that it is a very interesting overview of questions you may encounter in an interview. Get the book at Amazon

Image: Gayle McDowell – Cracking the Coding Book Cover

CodeWars: Weekly Newsletter

8kyu – positiveSum

The first question is to sum up all the positive integers in an array. Basically two things need to be done:

  • Filter out Values that should not be added to the sum
  • Sum up every item in the array

Basically you can write the solution like this:

export function positiveSum(arr: number[]): number {
  return arr
          .filter(val => val > 0)
          .reduce((total, current) => total + current, 0)
}

It is important to note that the initial value of 0 must be set, as if you pass in an empty array it would return NaN

7kyu – next Prime

Basically you need to check every number if it isPrime. Then you need to select an algorithm that can check if it is a prime number.

In this case I just took the code from the npm package is-number-prime. Which is a brute force way of figuring out if the number is prime or not. (There is probably something more mathematically elegant out there)

function isNumberPrime(n) {
  if (n === 2 || n === 3){
    return true;
  }
  
  if (n < 2 || n % 1 || n % 2 === 0 || n % 3 === 0) {
    return false;
  }
  let foo = Math.floor(Math.sqrt(n));
  for (let i = 5; i <= foo; i += 6) {
    if (n % i === 0 || n % (i + 2) == 0) {
      return false;
    }
  }
  return true;
}

function nextPrime(n){
  while (true){
    n++;
    if (isNumberPrime(n)){
      return n;
    }
  }
}

CodeWars: Weekly Newsletter 02

8kyu – Logic Drills: Traffic light

You need a function to handle each change from green, to yellow, to red, and then to green again.

Based on how the question is formulated it is suggested that you should always return the next item in an array. If it is the last item it should return the first item.

/**
 * 
 * @param {'green'| 'yellow'| 'red'} current 
 * @returns {string}
 */
function updateLight(current) {
  let lights = ['green', 'yellow', 'red'];
  let nextIndex = (lights.indexOf(current) + 1) % lights.length;
  return lights[nextIndex];
}

However as alternative you also could say: We always already know the next state, we do not need to calculate the next state. For traffic lights this system also probably will never change. Thus you can use an object to save the next states.

/**
 * 
 * @param {'green'| 'yellow'| 'red'} current 
 * @returns {string}
 */
function updateLight2(current) {
    return {
    'green': 'red',
    'yellow': 'green',
    'red': 'yellow'
  }[current];
}

7kyu – Sum of numerous arguments

The idea of this problem is mostly to make aware of that you can pass in an arbitrary amount of arguments into a js function.

In ES5 you would be using the arguments object and iterate over the array. in ES6 however we can use the cleaner spread-syntax:

/**
 * 
 * @param {number[]} args 
 * @returns {number}
 */
function findSum(...args){
  if (args.find(val => val < 0)){
    return -1;
  } else {
    return [...arguments].reduce((total, current) => total + current);
  }
}

CodeWars: 7kyu – The Highest Profit wins

I am exercising to get back into Python. Even though the solution to this exercise is quite straightforward, you could tweak the code a little bit so that it runs a little faster.

Basically, with min() and max(), the list would need to be iterated over 2 times. You could rewrite the code so that you only iterate once over the array. Overall I choose to stick with my initial solution as it is better readable, thus making it easier to maintain in the long run.

def min_max(lst):
    '''
    Exercise: https://www.codewars.com/kata/the-highest-profit-wins/train/python
    Example:
        min_max([1, 2, 3, 4, 5]) => [1, 5]
    Args:
        lst: A list of numbers
    
    Returns:
        A list with two entries of the min and the max value of the list
    '''
    return [min(lst), max(lst)]

CodeWars: 6kyu – Counting Bits

You got numbers, you want to know how many bits are flipped to a 1

Sourcehttps://www.codewars.com/kata/bit-counting/train/python

Approach:

Well, first we need to convert our number from an integer to a binary number.

There are two ways to do this:

Variant 1: String Formatting

"{:b}.format(number)"

Variant 2: Build In a binary converter “bin(number)”

Then well now we just have to count the occurrences of ones.

def count_bits:
   return bin(number).count(str(1))

Note: It is important to count the instances of ones as strings of “1” instead of integers of 1. This is the case because we converted the int to a string and are now looking for strings instead of numbers.

Codewars: Sum Of Pairs

Given a list of integers and a single sum value, return the first two values (parse from the left please) in order of appearance that add up to form the sum.

Source: https://www.codewars.com/kata/sum-of-pairs

The initial problem does seem quite simple:

  1. Iterate over the array
  2. Check for every item if there is a corresponding pair
  3. Return the pair that has the lowest right index
var sum_pairs = function (arr, sum) {
    let pairs = []
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length; j++) {
            if (arr[i] + arr[j] === sum && i != j && j > i) {
                results.push(j);
            }
        }
    }
    if (results.length) {
        let value = arr[Math.min(...results)];
        return [sum - value, value];
    } else {
        return undefined;
    }
}

All Tests pass. You think to yourself, well that was quite straightforward. No big deal. Let’s attempt the solution.

‘Attempt timed out’ solution must finish before 12s pass.

Then let’s optimize the algorithm. what all can we do?

  1. We can replace the second loop with the internal array.indexOf Function
  2. If we found a match we can stop looking for matches past the matches index
  3. We can avoid the pairs array, as we are only interested in a specific pair
var sum_pairs = function (arr, sum) {
    let rightIndex = arr.length;
    let match = false;
    for (let i = 0; i < rightIndex; i++) {
        let pairIndex = arr.indexOf(sum - arr[i]);

        if (pairIndex != -1 && pairIndex < rightIndex && pairIndex !== i) {
            rightIndex = pairIndex;
            match = true;
        }
    }
    if (match) {
        let value = arr[rightIndex];
        return [sum - value, value];
    }
    return undefined;
}

At this point, we only optimized for a couple of edge cases. We did not really reduce the complexity of the algorithm in the worst case every item in the array would need to be compared with every item in the array O(n*n). As even when we are using the internal functions we are still iterating over all items.

Next round of optimizations:

  • Instead of iterating and forgetting what we did let’s save our result.

Initially, I had a solution to map all values to an array and then iterate and find the pairs so it would have been O(2*n). But I had difficulties implementing that solution as the array of values could contain duplicates. Then I thought about it and said, hey if I simply compare the current value with the previous values then If I find a match, then I can stop and it would always be the right value. and as a bonus, the complexity is now 0(n), as if the pair is the last two elements of the array we would have needed to visit all elements before that.

var sum_pairs = function (arr, sum) {
    let viewedValues = []
    for (let i = 0; i & lt; arr.length; i++) {
        let currentValue = arr[i];
        let difference = sum - currentValue;
        if (viewedValues[difference]) {
            let result = [difference, currentValue];
            return result;
        }
        viewedValues[currentValue] = true;
    }
    return undefined;
}

comparing the first and the last solution there is a tradeoff between the two solutions.

  1. In the 0(n*n) solution it takes longer to get to the result. However, we do not need so much memory.
  2. With the O(n) solution, we get the result quicker, but we need a lot more memory.