Implementing Caesars Cipher in Javascript using ES6 Syntaxes

What is Caesars Cipher? The particular constraint for this exercise is ROT13 algorithm (rotate by 13 alphabets), and only use upper case letters.

Here is my quick implementation:

function rot13(str) {
  // LBH QVQ VG!
  const input = str
    .split("")
    .map(item => item.charCodeAt())
    .map(item => {
      if (item < 65 || item > 90) {
        return item;
      } else if (item < 78) {
        return item + 13;
      } else {
        return item - 13;
      }
    })
    .map(item => String.fromCharCode(item))
    .join("");
  return input;
}

// Change the inputs below to test
console.log(rot13("SERR CVMMN!"));

The numbers inside the if statements of the code above are ASCII codes that correspond to the uppercase letters of the alphabets.

How to choose the right level of life insurance cover in Australia?

Are you single? Yes or No

Do you have kids under 18 years old? Yes or No

– Two questions before you start

When we talk about life insurance in Australia. We talk about three different types of coverage: life insurance, income protection and total and permanent disability (TPD) cover. If you already have life insurance either outside or inside of your superannuation fund, your insurance policy might already include one or all three components above. Confused?

  • Life insurance is paid to your nominated beneficiaries when you die before you turn 65 years old. Life insurance policy cover for people over 65 years old is usually very expensive. The cut-off is age 65 because that is the threshold age when government aged pension kicks off in Australia. This number would probably fluctuate in the future and might end up being 70 years old or older when you can qualify for the aged pension. 
  • Income protection insurance is paid to you either as a one-off lump sum or monthly ever year until you turn 60 years old. The condition that this policy will kick off is because you cannot work in a job anymore while you are still alive. Note the 5 years gap between when your income protection insurance runs out and when the Australian aged pension would kick-off (if you qualify for one).
  • Total and permanent disability (TPD) insurance is paid to you a one-off lump sum when you become disabled for life. As a result of which, you can no longer hold any job. 

This post is part of a series of posts on personal finance skills for millennials.

How does it work?

For instance, if you get involved in a traffic accident and you become disabled; and your insurance policy cover has both an income protection component and a TPD component, you will get paid a one-off TPD lump sum for when you become incapacitated.

You will probably need this lump sum payment to do all or some of the following things:

  • Renovate your house/apartment for accessibility
  • Sell your current dwelling, and buy/rent another property with accessibility friendly facilities
  • Organise medical treatments, ongoing out-of-pocket medical cost and regular physical therapies.

Every month after that until you turn 60 years old, you will receive (usually) the equivalent of 75-85% of the regular salary of your last job (before tax). You will still need to pay your taxes by the way.

Life Insurance for a Single Person

You might not need any life insurance policy, but you will need income protection and a TPD insurance.

Why do you need life insurance if you are NOT a single person? 

“If a child, a spouse, a life partner, or a parent depends on you and your income, you need life insurance.”

― Suze Orman

If you are the primary income earner in your household and you have a mortgage, the life insurance will be used to pay off all or some of the following things you might own other people or financial institutions:

  • Mortgage (otherwise your dependents might no longer have a roof over their heads),
  • Credit card loan,
  • Other loans,
  • Living cost for those you leave behind until they can get on their feet independently. Usually, this means enough monthly living cost for your family members to a maximum of 10 years. 

What if I have no mortgage and no other loan, but my loved ones will still need some living cost support should I die unexpectedly?

  • Do you have other investment that they can live off from for the next 10 years?
  • How financially independent are your loved ones?

Depending on your answers, then you might or might not need life insurance.

How to choose the right level of life insurance cover?

The general rule of thumb is to get life insurance 10-12x your current annual salary. It will depend on how many kids you have, how big are your financial obligations (mortgage, car loans, etc.). If you don’t have that many debts and you have good investment assets, then you can probably get away with a lower insurance cover. Each individual circumstance is unique.

Use this calculator to work out how much life insurance you need. You can get a life insurance policy inside or outside of your superannuation. You can read this article to read about the pros and cons.

How to choose the right level of income protection cover?

Read this article from Moneysmart website. You would usually need to go the specific calculator of an insurance provider to get an estimate. Make sure you tick the option `cover until the age of 60 years old` and not just for 2 years.

How to choose the right level of total and permanent disability (TPD) cover?

Read this article from the Moneysmart website. Usually, you always have to get both life insurance and TPD cover. You can’t get one and not the other. Depending on the financial institutions that underwrite your insurance, the options will vary widely between each provider.

A short note about the life insurance premium cost

As you age, your life insurance premium fee will increase annually up to a point where it makes no sense to keep life insurance due to a few reasons:

  • You are still alive, and your chance of being alive past the age of 65 increases.
  • Your chance of needing life insurance decreases.
  • The cost for the insurance company to pay out the insurance if you pass away at your current age increases significantly.
  • Your premium insurance is way too expensive.
  • Your household debts are probably under control by then since you will have had a long working life and savings – which mean that you only have productive assets and zero liability (ideally!).

You will reach this tipping point at around age 50.

The next important thing to think about is to have enough savings and assets that would sustain the gap years between when you can no longer own life insurance and when you are eligible for aged pension (let’s also hope aged pension still exists when you have to retire).

Some useful links:

Micro Coding Exercise Using CSS Grid, Web API and Vanilla Javascript

This afternoon I came up with a useful coding challenge after spending some time reading about Web APIs – make a battery status using CSS grid, Web APIs and vanilla javascript. I created this small pen.

Use the slider to change the battery status

The idea is to use a grid with fours rows, each row represents a quarter of battery life. Using the slider, the user can change the battery capacity. Some div are removed from the grid when a certain threshold is reached.

See the Pen Battery Status VanillaJS by Surya S (@suryast) on CodePen.dark

Please let me know if you know of a better way to refactor the javascript component of the pen.

// Set consts
const slider = document.getElementById("batteryRange");
const output = document.getElementById("batteryPercentage");
const children = document.querySelector(".grid").children

// Get value of slider
output.innerHTML = slider.value;

// Add battery percentage status
window.onload = () => {
  output.innerHTML = "50%";
} 

// Update battery percentage
slider.oninput = function() {
  const formattedOutput = this.value.toString() + "%"
  output.innerHTML = formattedOutput;
  checkBattery();
}

function checkBattery() {
  switch(true){
    case ( slider.value == 100 ):
      setToOneHundred();
      break;
    case ( slider.value > 75 ):
      setToOneHundred();
      break;
    case ( slider.value == 75 ):
      setToSeventyFive();
      break;
    case ( slider.value > 50 && slider.value < 75):
      setToSeventyFive();
      break;
    case ( slider.value == 50 ):
      setToFifty();
      break;
    case ( slider.value > 25 && slider.value < 50 ):
      setToFifty();
      break;
    case ( slider.value > 1 && slider.value < 25 ):
      setToTwentyFive();
      break;
    case ( slider.value < 1 ):
      setToZero();
      break;
    default:
      return;
  }
}

// Setters
setToZero = () => {
  for (let i = 0; i < children.length; i++) {
    children[i].className = "hidden";
  }
}

setToTwentyFive = () => {
  for (let i = 0; i < children.length-1 ; i++) {
    children[i].className = "hidden";
  }
  children[3].className = "grid-item_darkred";
}

setToFifty = () => {
  for (let i = 0; i < children.length-1 ; i++) {
    children[i].className = "hidden";
  }
  for (let i = 2; i < children.length; i++) {
    children[i].className = "grid-item_orangered";
  }
}

setToSeventyFive = () => {  
  children[0].className = "hidden";
  for (let i = 1; i < children.length; i++) {
    children[i].className = "grid-item_green";
  }
}

setToOneHundred = () => {
  for (let i = 0; i < children.length; i++) {
    children[i].className = "grid-item_darkgreen";
  }
}
// Set consts
const slider = document.getElementById("batteryRange");
const output = document.getElementById("batteryPercentage");
const children = document.querySelector(".grid").children;
const childrenArray = Array.from(children);

// Get value of slider
output.innerHTML = slider.value;

// Add battery percentage status
window.onload = () => {
  output.innerHTML = "50%";
};

// Update battery percentage
slider.oninput = function() {
  const formattedOutput = this.value.toString() + "%";
  output.innerHTML = formattedOutput;
  checkBattery();
};

function checkBattery() {
  switch (true) {
    case slider.value > 75:
      childrenArray.map(item => (item.className = "grid-item_darkgreen"));
      break;
    case slider.value > 50 && slider.value <= 75:
      children[0].className = "hidden";

      childrenArray
        .filter(item => childrenArray.indexOf(item) > 0)
        .map(item => {
          item.className = "grid-item_green";
        });
      break;
    case slider.value > 25 && slider.value <= 50:
      childrenArray
        .filter(item => childrenArray.indexOf(item) < 2)
        .map(item => {
          item.className = "hidden";
        });

      childrenArray
        .filter(item => childrenArray.indexOf(item) > 1)
        .map(item => {
          item.className = "grid-item_orangered";
        });
      break;
    case slider.value >= 1 && slider.value < 25:
      childrenArray
        .filter(item => childrenArray.indexOf(item) < 3)
        .map(item => {
          item.className = "hidden";
        });
      children[3].className = "grid-item_darkred";
      break;
    case slider.value < 1:
      childrenArray.map(item => (item.className = "hidden"));
      break;
    default:
      return;
  }
}

Check If a Phrase is Palindromic in Javascript

I completed this exercise from Free Code Camp today. In essence, it’s palindrome checker that will return TRUE if a word or a phrase is a palindrome (minus all numbers and special characters), or FALSE if it’s not a palindrome.

I applied all the recent Javascript lessons I have revisited recently to check if a phrase is palindromic in Javascript while trying to keep the solution as short as possible.

Here is one solution:

function palindrome(str) {
  str = str.replace(/[^a-zA-Z0-9]+/g, "")
    .toLowerCase();   // strip to only lower case alphabets 

  const reversed = str
    .split("") // make into an array of characters
    .reverse() // reverse the array
    .join(""); // create a new string from the reversed array

  return str == reversed ? true : false; // compare the two
}

Firstly, the function receives a string that gets stripped of non-alphabet characters and transformed into an all lower case string with no space.

The new string is then broken down into an array of chars that will undergo an array reversal before being reformed into a new string, called reversed.

The final piece of the code is to compare the original parameter str (stripped) against reversed, which will return either TRUE or FALSE.

I also wrote some unit tests using Jest. Here is the test file:

const palindrome = require("./palindrome");

test("eye", () => {
  expect(palindrome("eye")).toBe(true);
});

test("_eye", () => {
  expect(palindrome("_eye")).toBe(true);
});

test("race car", () => {
  expect(palindrome("race car")).toBe(true);
});

test("not a palindrome", () => {
  expect(palindrome("not a palindrome")).toBe(false);
});

test("A man, a plan, a canal. Panama", () => {
  expect(palindrome("A man, a plan, a canal. Panama")).toBe(true);
});

test("ever odd or even", () => {
  expect(palindrome("ever odd or even")).toBe(false);
});

test("nope", () => {
  expect(palindrome("nope")).toBe(false);
});

test("almostomla", () => {
  expect(palindrome("almostomla")).toBe(false);
});

test("My age is 0, 0 si ega ym.", () => {
  expect(palindrome("My age is 0, 0 si ega ym.")).toBe(true);
});

test("0_0 (: /- :) 0-0", () => {
  expect(palindrome("0_0 (: /- :) 0-0")).toBe(true);
});

test("five|_/|four", () => {
  expect(palindrome("five|_/|four")).toBe(false);
});

Mapping Nav Components into a Navbar Implementing React Router

I was tinkering with a way to map Nav Components into a navigation bar in React by utilising map() function. The original code looks like the following:

import React from 'react';
import Navbar from './components/Navbar';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import Report from './components/Report';
import Contact from './components/Contact';
import About from './components/About';
import Post from './components/Post';

function App() {
  return (
    <BrowserRouter>
      <div className="App">
      <Navbar />
          <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/report" component={Report} />
            <Route path="/about" component={About} />
            <Route path="/contact" component={Contact} />
            <Route path="/posts/:post_id" component={Post} />
          </Switch>
      </div>
    </BrowserRouter>
  );
}

We can do an abstraction for the following lines of code:

<Route exact path="/" component={Home} />
<Route path="/report" component={Report} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />

To do so, we can create an array of objects with properties of name and path. Let’s call it m

const menuItems = [
  { name: `Home`, path: `/` },
  { name: `Report`, path: `/report` },
  { name: `About`, path: `/about` },
  { name: `Contact`, path: `/contact` },
  { name: `Post`, path: `/posts/:post_id` }
];

Inside <Switch> we can map each item inside menuItems to create multiple <Route> components. We can do it this way.

<Switch>
  {menuItems.map(item =>
    item.name == `Home` ? (
      <Route exact path={item.path} component={item.name} />
    ) : (
      <Route path={item.path} component={item.name} />
    )
  )}
</Switch>;

We get a bug though. Our assignment component = {item.name} returns undefined because the component needs to be a componentName and not a String. How do we solve this? Following a suggestion for this thread on StackOverflow, one way to solve this problem is to create a new object with properties looks like the following.

const COMPONENT_MAP = {
  Home: Home,
  Report: Report,
  About: About,
  Contact: Contact,
  Post: Post
};

It’s almost like an identity function (I think?). Although, I’m unsure if that is what an identity function should be. We can then modify our function to get the correct output

<Switch>
  {menuItems.map(item =>
    item.name == `Home` ? (
      <Route exact path={item.path} component={COMPONENT_MAP[item.name]} /> //COMPONENT_MAP[item.name] returns componentName
    ) : (
      <Route path={item.path} component={COMPONENT_MAP[item.name]} />
    )
  )}
</Switch>;

Here is the final refactored code:

import React from "react";
import Navbar from "./components/Navbar";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "./components/Home";
import Report from "./components/Report";
import Contact from "./components/Contact";
import About from "./components/About";
import Post from "./components/Post";

const menuItems = [
  { name: `Home`, path: `/` },
  { name: `Report`, path: `/report` },
  { name: `About`, path: `/about` },
  { name: `Contact`, path: `/contact` },
  { name: `Post`, path: `/posts/:post_id` }
];

const COMPONENT_MAP = {
  Home: Home,
  Report: Report,
  About: About,
  Contact: Contact,
  Post: Post
};

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Navbar />
        <Switch>
          {menuItems.map(item =>
            item.name == `Home` ? (
              <Route
                exact
                path={item.path}
                component={COMPONENT_MAP[item.name]}
              />
            ) : (
              <Route path={item.path} component={COMPONENT_MAP[item.name]} />
            )
          )}
        </Switch>
      </div>
    </BrowserRouter>
  );
}

Let me know if there is a better way to do this.

Create a New Javascript Object by Destructuring Existing Objects

I learned some new Javascript methods this week which I think are very useful.

const object = {
  name: `Eva`,
  breed: `Labrador`
};
console.log(object);

// Object to arrays of properties
const objectToEntries = Object.entries(object); 
console.log(objectToEntries);

// Arrays back to properties of an object
const entriesBackToObject = Object.fromEntries(objectToEntries); 
console.log(entriesBackToObject);
Edit zealous-meadow-4tqy0

Imagine a scenario where you have an object of customer and object of a shopping item, in the example below, an Adidas T-shirt. You can deconstruct the properties from the two objects and combine them to create an order object.

const customer = {
  id: `173463`,
  name: `Steve`
};

const item = {
  category: `shirt`,
  name: `Black Hoodie`,
  brandN: `Adidas`,
  price: 10000
};

let customerEntries = Object.entries(customer);

let itemEntries = Object.entries(item);

let order = [];
order.push(...customerEntries, ...itemEntries);

let orderObject = Object.fromEntries(order);
console.log(orderObject); 

// Output: Object {id: "173463", name: "Black Hoodie", category: "shirt", brandN: "Adidas", price: 10000}

The code above is not quite right though since both customer and item objects have a property called name. The name property of ...itemEntries overwrites the name property of ...customerEntries. You can read more about spread operator here.

There are a few other ways to combine customerEntries and itemEntries without having to use the spread operator. I find this explanation here useful to read. There also seems to be quite a popular old discussion on Stack Overflow on how to achieve the same goal.

Now how do you make sure that the property name will not be overwritten by the second array? There must be an elegant way of achieving this, but here is what I have in mind.

let customerEntries = Object.entries(customer);
let [, customerName] = customerEntries;
customerName[customerName.indexOf(`name`)] = `customerName`;

let itemEntries = Object.entries(item);
let [, itemName, ...restOfItemEntries] = itemEntries;
itemName[itemName.indexOf(`name`)] = `itemName`;

The final solution looks like this:

const customer = {
  id: `173463`,
  name: `Steve`
};

const item = {
  category: `shirt`,
  name: `Black Hoodie`,
  brand: `Adidas`,
  price: 10000
};

let customerEntries = Object.entries(customer);
let [, customerName] = customerEntries;
customerName[customerName.indexOf(`name`)] = `customerName`;

let itemEntries = Object.entries(item);
let [, itemName, ...restOfItemEntries] = itemEntries;
itemName[itemName.indexOf(`name`)] = `itemName`;

let order = [];
order.push(...customerEntries, customerName, ...itemEntries);

let orderObject = Object.fromEntries(order);
console.log(orderObject); 
//Object {id: "173463", customerName: "Steve", category: "shirt", itemName: "Black Hoodie", brand: "Adidas"…}
Edit romantic-haslett-dymwf

In summary, you can create a new object by deconstructing other objects. What you need to keep in mind is to prevent overwriting object properties whose names are shared between two different objects.

Australian Shares Portfolio – September 2019

The portfolio has grown by almost 4% since March. The modest growth is mostly due to the overall ASX market going up after RBA announced two interest rate cuts. Most holdings in the ASX is probably overpriced at this stage – not a good time to buy unless there is a good dividend on offer.

I added two new companies to the portfolio. The first one is the undervalued PACT Group, and the second one is a well-known Australian LIC called AFIC (Australian Foundation Investment Company). AFIC purchase was boring, but it was a reasonable purchase due to many companies I am keen on are overpriced at the moment. To date, I still haven’t managed to reduce my portfolio’s Australian market exposure by much.

Asset allocation:

Australia:16%
International:12%
REIT:9%
Fixed Interest + Gold:6%
Cash + Property:57%

Saver App – Experimental App Using React + CSS Grid

Last week, I read this post, and I got inspired. The idea is to have a printed collection of coupons with 52 entry coupons; each coupon has a dollar amount attached. You can cross out a coupon each time you manage to save that amount. If you cross out one coupon each week for one year, you will end up with $10,000 in savings – simple and effective in theory.

The calendar was perfect for a small React project, so I went about to implement a web app. You can see the app in action here, and the repo lives here. The app randomly generates the dollar on each coupon. You can also can change the amount you want to save and or the minimum weekly saving amount you want to commit to.

Give it a go! For now, you need to print the page if you want to start saving using this method.