Monday, December 31, 2018

Python - Using virtualenv

Step1: Create a virtual environment:

/opt3$ virtualenv runs02
Running virtualenv with interpreter /usr/bin/python2
New python executable in /opt3/runs02/bin/python2
Also creating executable in /opt3/runs02/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
/opt3$

Step 2: Activate the environment:

$ cd runs02
/opt3/runs02$ ls -l
total 0
drwxr-xr-x 2 mhc mhc 320 Dec 31 12:51 bin
drwxr-xr-x 2 mhc mhc  60 Dec 31 12:51 include
drwxr-xr-x 3 mhc mhc  60 Dec 31 12:51 lib
drwxr-xr-x 2 mhc mhc 100 Dec 31 12:51 local
drwxr-xr-x 3 mhc mhc  60 Dec 31 12:51 share
/opt3/runs02$ which source
opt3/runs02$ $ source bin/activate
(runs02) /opt3/runs02$

Step 3: Now install the needed packages using pip.

Installing pandas:

(runs02) /opt3/runs02$ pip install pandas
Collecting pandas
  Downloading https://files.pythonhosted.org/packages/b7/e3/f52d484244105fa3d558ce8217a5190cd3d40536076bef66d92d01566325/pandas-0.23.4-cp27-cp27mu-manylinux1_x86_64.whl (8.9MB)
    100% |████████████████████████████████| 8.9MB 2.2MB/s 
Collecting pytz>=2011k (from pandas)
  Downloading https://files.pythonhosted.org/packages/f8/0e/2365ddc010afb3d79147f1dd544e5ee24bf4ece58ab99b16fbb465ce6dc0/pytz-2018.7-py2.py3-none-any.whl (506kB)
    100% |████████████████████████████████| 512kB 10.7MB/s 
Collecting numpy>=1.9.0 (from pandas)
  Downloading https://files.pythonhosted.org/packages/de/37/fe7db552f4507f379d81dcb78e58e05030a8941757b1f664517d581b5553/numpy-1.15.4-cp27-cp27mu-manylinux1_x86_64.whl (13.8MB)
    100% |████████████████████████████████| 13.8MB 1.4MB/s 
Requirement already satisfied: python-dateutil>=2.5.0 in ./lib/python2.7/site-packages (from pandas) (2.7.5)
Requirement already satisfied: six>=1.5 in ./lib/python2.7/site-packages (from python-dateutil>=2.5.0->pandas) (1.12.0)
Installing collected packages: pytz, numpy, pandas
Successfully installed numpy-1.15.4 pandas-0.23.4 pytz-2018.7
(runs02) /opt3/runs02$



Reference:

Monday, December 17, 2018

VueJS - tools - vue.js dev tools



Step 1: In our chrome browser let us visit the site: https://chrome.google.com/webstore/category/extensions

Step 2: Search for Vue.js devtools:

Step 3: Click on Add to Chrome



Step 4: Click on Add extension:



Now Vue.js devtools has been added to our chrome browser. 

Sunday, December 2, 2018

curl - fetch headers of URL

To fetch only the headers of a HTTP URL, we can use the curl with the -I switch. Consider the following command line:


HTTP/2 200 
server: nginx
date: Sun, 02 Dec 2018 10:09:19 GMT
content-type: text/html; charset=UTF-8
set-cookie: wordpress_google_apps_login=3612792336cb3b1361acd56bb0addf07; path=/; secure
link: <https://www.stanford.edu/wp-json/>; rel="https://api.w.org/"
link: <https://www.stanford.edu/>; rel=shortlink
x-frame-options: SAMEORIGIN
vary: Accept-Encoding
wpe-backend: apache
x-wpe-loopback-upstream-addr: 127.0.0.1:6783
x-cacheable: NO:Set Known Cookie
cache-control: max-age=0, must-revalidate, private
x-cache: MISS
x-pass-why: 
x-cache-group: normal
x-type: default



In this we fetch the headers sent from the URL of the stanford university. 

Friday, November 16, 2018

TypeScript - Namespaces - drawbacks of namespaces

In our examples of Namespaces - the number of files and namespaces were limited. Consider a case, where the number of files and namespaces are huge in number. In such case managing the dependencies become very difficult.

Hence, in TypeScript we have another feature to better tackle dependency management  - modules.

Reference:

TypeScript - Namespaces - nested namespaces and import alias

In TypeScript, it is possible to include a namespace inside another namespace. This is called nesting of namespaces. Consider the file:

circleArea.ts
namespace myArea {
const PI = Math.PI;
export function circleArea(radius: number){
return PI*radius*radius;
}
}

We can rewrite it to include a circleStuff namespace inside it. 

namespace myArea {
namespace circleStuff {
const PI = Math.PI;
export function circleArea(radius: number){
return PI*radius*radius;
}
}
}

To be able the circleStuff namespace, we must export it - or else, it will be private. Hence, we have to rewrite it again as follows:

namespace myArea {
export namespace circleStuff {
const PI = Math.PI;
export function circleArea(radius: number){
return PI*radius*radius;
}
}
}

To make this work, we must visit our app.ts file and include the nested namespace - circleStuff:
///<reference path="circleArea.ts"/>
///<reference path="squareArea.ts"/>
console.log(myArea.circleStuff.circleArea(5));
console.log(myArea.squareArea(5));

Now, let us compile and reload the browser:

$ tsc app.ts --outFile app.js
$ python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...
127.0.0.1 - - [16/Nov/2018 08:04:34] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [16/Nov/2018 08:04:34] "GET /app.js HTTP/1.1" 200 -

Console Output:
78.53981633974483
25

Also, instead if multiple chains of access, we can also create an alias for the nested namespace and then use it in the console.log to access the function using the alias. 

app.ts - rewritten
///<reference path="circleArea.ts"/>
///<reference path="squareArea.ts"/>

// aliasing for circleStuff
import circleStuffImport = myArea.circleStuff;

console.log(circleStuffImport.circleArea(5));
console.log(myArea.squareArea(5));


Now, if we compile and re-run:

$ tsc app.ts --outFile app.js
$ python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...
127.0.0.1 - - [16/Nov/2018 08:09:32] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [16/Nov/2018 08:09:32] "GET /app.js HTTP/1.1" 200 -


We observe the same Console Output:
78.53981633974483
25

These are the various ways in which we can use namespaces in TypeScript. 

TypeScript - Namespaces - multiple files using reference path

In our previous blogpost:  https://sashankexpresstech.blogspot.com/2018/11/typescript-namespaces-multiple-files.html ... we have explored how to split a namespace into multiple files and compile them. In both the techniques mentioned, work done to use the files becomes tedious. TypeScript has one more technique to address this issue using reference path

Technique 03:

In our app.ts file, let us include the first two lines mentioned below:
///<reference path="circleArea.ts"/>
///<reference path="squareArea.ts"/>
console.log(myArea.circleArea(5));
console.log(myArea.squareArea(5));

The triple slash mentioned above is a comment. The contents of the comment are used as a compiler directives. They can only be contained in the top of the containing file. For more information, let us refer the following link:
https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html

Now, after we save our app.ts file - let us compile the file by using the following command:
$ tsc app.ts --outFile app.js

Let us start the webserver and then open the address: localhost:3000 in our web browser.

$ python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...
127.0.0.1 - - [16/Nov/2018 06:08:47] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [16/Nov/2018 06:08:48] "GET /app.js HTTP/1.1" 200 -

Output in browser console:
78.53981633974483
25

This technique appears to be the most convenient way to include the namespace in multiple files and compiling them for usage.

Reference:

Thursday, November 15, 2018

TypeScript - Namespaces - multiple files

We have introduced usage of namespace with an example in our previous blog post:
https://sashankexpresstech.blogspot.com/2018/11/typescript-namespaces-introductory.html

Consider a scenario, whereby the namespace is really huge and we would like to better organize it splitting into multiple files. In such a case, TypeScript provides us a facility by which we can hold the same namespace in multiple files.

In the previous example, we were calculating the areas of circle and square and we grouped them in one namespace: myArea.

Let us now split the namespace information of myArea in to two files:

circleArea.ts
namespace myArea {
const PI = Math.PI;
export function circleArea(radius: number){
return PI*radius*radius;
}
}

squareArea.ts
namespace myArea {

export function squareArea(sideLength:number){
return sideLength*sideLength;
}
}


the code that remains in app.ts is:
console.log(myArea.circleArea(5));
console.log(myArea.squareArea(5));

Now, if we compile:

$ tsc
$ ls -l *.js
-rw-r--r-- 1 ubuntu ubuntu  84 Nov 15 15:03 app.js
-rw-r--r-- 1 ubuntu ubuntu 211 Nov 15 15:03 circleArea.js
-rw-r--r-- 1 ubuntu ubuntu 196 Nov 15 15:03 squareArea.js

Now, if we open the browser on localhost and check the console:
Uncaught ReferenceError: myArea is not defined
    at app.js:2

We have received the above error. This is because, myArea is not defined in app.js file - which is the file included in our index.html page. To solve this problem there are two techniques:

Technique 01:
First technique involves, including all the JavaScript files inside the index.html file. We will include them in the body of our index.html file as follows:

<body>
<script src="./circleArea.js"></script>
<script src="./squareArea.js"></script>
<script src="./app.js"></script>
</body>

Please note that the order of the JavaScript file placement matters. This is because, the definitions of the namespace should come before its usage. Hence, we have placed the app.js file at the bottom.

Now, if we check the console output:
78.53981633974483
25


Technique 02:
We also have another technique in which we can combine the multiple JavaScript files into a single file using the --outFile compiler option provided with tsc. Let us use this technique as mentioned in the link:
https://www.typescriptlang.org/docs/handbook/namespaces.html#splitting-across-files

For this let us first edit our index.html file to include only the app.js file:
<body>
<script src="./app.js"></script>
</body>

Now, we will combine the TypeScript files to a single JavaScript file using the --outFile compiler option:

$ tsc --outFile app.js circleArea.ts squareArea.ts app.ts 

This will combine the 3 .ts files into a single JavaScript file:

$ ls -l *.js
-rw-r--r-- 1 ubuntu ubuntu 449 Nov 15 15:36 app.js

Now, let us start the web server:
$ python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...
127.0.0.1 - - [15/Nov/2018 15:44:24] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [15/Nov/2018 15:44:24] "GET /app.js HTTP/1.1" 200 -

Check the console in the browser on localhost:3000. The console output is:

78.53981633974483
25

This covers the techniques for splitting a namespace into multiple files and then using them.


Reference:

TypeScript - Namespaces - Introductory Example

Consider the following code snippet which includes functions to calculate the area of:

  • Circle
  • Square

app.ts:  -- does not include namespace
function circleArea(radius: number){
return Math.PI*radius*radius;
}

function squareArea(sideLength:number){
return sideLength*sideLength;
}

console.log(circleArea(5));
console.log(squareArea(5));

Now, when we write code like this. There are too many functions in the global scope. There are scenarios where we would like to group related functions. For example, in this scenario both these functions are calculating the area. Hence, we can combine them both into a single module. This facility provided by TypeScript to group similar code stuff is namespace.

Consider the following code snippet - which just the above code rewritten:

app.ts - includes namespace
namespace myArea {
const PI = Math.PI;
export function circleArea(radius: number){
return PI*radius*radius;
}
export function squareArea(sideLength:number){
return sideLength*sideLength;
}
}
console.log(myArea.circleArea(5));
console.log(myArea.squareArea(5));

In this, we are grouping the functions into a bigger umbrella and terming it as myArea namespace. Please note that the individual functions and variables need to be exported - so that we can use it outside the namespace. In the above code snippet, exported properties are:

##
object-type
object-name

1 variable
PI
not exported
2 function
circleArea
exported
3 function squareArea
exported



Below is console output:

78.53981633974483
25


Reference:

TypeScript - Namespaces and modules - Introduction

Manytimes, our JavaScript project grows very big, such that it becomes difficult to manage it. To manage it, we need to split it into multiple files and group related stuffs. This is called modularization. TypeScript offers us two concepts to help us with manage our project:

  1. Namespaces
  2. Modules

Reference:

Wednesday, November 14, 2018

TypeScript - Classes - Singleton pattern - read-only variables

In our previous blogpost, we saw the usage of private constructors:
https://sashankexpresstech.blogspot.com/2018/11/typescript-classes-singleton-pattern.html

To make a variable readonly, we assign the modifier readonly before it. By this the variable can be only read externally. But it cannot be assigned a value to. Consider the following example:

// Demo - readonly variables
class mySingleton {
private static instance: mySingleton;
public readonly name:string;

private constructor( name:string) {
this.name = name;
}

static getInstance() {
if (!mySingleton.instance) {
mySingleton.instance = new mySingleton("The Singleton Input");
}

return mySingleton.instance;
}
}

// Only One instance
let mySingletonInstance = mySingleton.getInstance();
console.log(mySingletonInstance.name);


In this example, we have assigned the readonly modifier to the variable name. Hence, we can only read the value in this variable. If we try to change the value in this variable, then we will receive a TypeScript error:

[ts] Cannot assign to 'name' because it is a constant or a read-only property.


Reference:

TypeScript - Classes - Singleton pattern and private constructors

Singleton Pattern means that you should be able to able to create only one instance of the class.  Consider the below example in which we create a SIngleton class.

// Demo - private constructors - Singleton class
class mySingleton {
private static instance: mySingleton;

private constructor(public name:string) {

}

static getInstance() {
if (!mySingleton.instance) {
mySingleton.instance = new mySingleton("The Singleton Input");
}

return mySingleton.instance;
}
}

// Only One instance
let mySingletonInstance = mySingleton.getInstance();

In this example, we ensure that it is a singleton class by:

  • making the constructor private - hence, the instance cannot be created outside the class
  • Since, the instance of the class is created within the class itself. We can place a check within the class - for creating the Singleton instance only when it is not already created.

Reference:

TypeScript - Classes - abstract classes

Abstract classes are classes which cannot be instantiated. They serve as base class from which other classes may be derived.

Consider that we want to create an abstract class for Fighter Planes:

// Abstract Classes
abstract class FighterPlanes {
manufacturerName: string = "Dassault Aviation";
budget: number = 30000;

abstract changeName(name:string) : void;
calcBudget(){
return this.budget *2;
}
}

Now, if we want to extend this class to a specific plane. The above abstract class will be a default template for all the future Fighter Planes.

class B2Spirit extends FighterPlanes {
changeName(name:string): void {
this.manufacturerName = name;
}
}

Let us instantiate this child class and save the file.

let newProject = new B2Spirit ();
console.log(newProject);
console.log(newProject.changeName("Northrop Grumman"));
console.log(newProject);


Compiling the project:

$ tsc
$

Start the Local Server:

$ python -m SimpleHTTPServer 3000
$

Check the console in the Web Browser:

B2Spirit {manufacturerName: "Dassault Aviation", budget: 30000}
city-App.ts:196 undefined
city-App.ts:197 B2Spirit {manufacturerName: "Northrop Grumman", budget: 30000}


Reference:

TypeScript - Classes - static properties and methods

When we create a class, we cannot use its properties and methods without instantiating the class.

// Static Properties and Methods
class miscItems {
E: number = 2.718;
calcMultipleE(inputMultiple:number) : number{
return this.E * inputMultiple;
}
}

But, TypeScript provides a facility to access the methods and properties without instantiating it by using the static keyword. Observe how we convert the above class to be able to hold static properties and methods and then access it directly. Consider the below rewritten code:

// Static Properties and Methods
class miscItems {
static E: number = 2.718;
static calcMultipleE(inputMultiple:number) : number{
return this.E * inputMultiple;
}
}

console.log(2*miscItems.E);
console.log(miscItems.calcMultipleE(8));

Let us now, compile the code

$ tsc
$

check the console output:

5.436
21.744

We are able to access static properties and methods  defined in a class without instantiating it.

Reference:

TypeScript - Classes - Getters and Setters

In TypeScript there is a away to set a private variables using the getters and setters. You can refer the following link for its implementation:
https://www.typescriptlang.org/docs/handbook/classes.html#accessors

Below is a sample implemenation of accessing and modifying private variables in a class using the get and set keywords. Do notice that the private variable (_brand) is prefixed with a single underscore.

// Getters and Setters

class Motorbike {
private _brand : string = "TVS";

get brand(){
return this._brand;
}

set brand(value:string){
if (value.length > 3) {
this._brand = value;
} else {
this._brand = "TVS";
}
} // end set
}

let myBike = new Motorbike();
console.log(myBike.brand);


Let us now compile the file:

$ tsc
$

To check the console:

$ python -m SimpleHTTPServer 3000

Checking the console output:

TVS


Reference:

Tuesday, November 13, 2018

TypeScript - Classes - this keyword - constructors

Now, in the below example, elevation is a protected variable.

class Visakhapatnam extends City{
name = "Visakhapatnam";
protected elevation = 45;

constructor(){
super("Visakhapatnam");
}
}

We can also modify it inside the constructor by using this keyword. 

class Visakhapatnam extends City{
name = "Visakhapatnam";
constructor(){
super("Visakhapatnam");
this.elevation = 45;
}
}

const cityVisakha = new Visakhapatnam();
console.log(cityVisakha);
console.log(cityVisakha.name);
cityVisakha.setType("Town");
console.log(cityVisakha.printType());
console.log(cityVisakha.getElevation());
console.log(cityVisakha);

Now, if i compile:

$ tsc
$

and .. check in the console.  

Console Output:

Visakhapatnam elevation: 45name: "Visakhapatnam"type: "Town"__proto__: City
city-App.ts:138 Visakhapatnam
city-App.ts:109 new type = Town
city-App.ts:113 Town
city-App.ts:140 undefined
city-App.ts:104 45
city-App.ts:141 undefined
city-App.ts:142 Visakhapatnam

We can see, that using the this keyword - the elevation was updated. Note that we cannot update the type using the this keyword. This is because, private properties are not accessible using the this keyword in the child classes.


TypeScript - Classes - Inheritance and constructors

Now, in my Inherited class I can create its own constructor overriding the constructor in the parent class:

class City {
public name:string;
private type: string;
protected elevation: number;

constructor(name:string) {
this.name = name;
this.type = "city";
this.elevation = 505;
}

setElevation(elevation:number){
this.elevation = elevation;
console.log("new elevation = "+this.elevation);
}

getElevation(){
console.log(this.elevation);
}

setType(type:string){
this.type = type;
console.log("new type = "+this.type);
}

printType(){
console.log(this.type);
}

}

const city = new City("Hyderabad");
console.log(city);
city.getElevation();
city.setElevation(506);
city.printType();
city.setType("Metro");
city.printType();


class Visakhapatnam extends City{
name = "Visakhapatnam";
protected elevation = 45;

constructor(){
super("Visakhapatnam");
}
}

const cityVisakha = new Visakhapatnam();
console.log(cityVisakha);
console.log(cityVisakha.name);
cityVisakha.setType("Town");
console.log(cityVisakha.printType());
console.log(cityVisakha.getElevation());
console.log(cityVisakha);


As you observe, in the constructor of the inherited class - i call the super() function. The super function indicates that I am calling the constructor of the parent class. Since, the constructor of the parent class expects a input. Hence, we pass an input to the super("Visakhapatnam") function.

But, while instantiating the child class - we do not pass in any arguments. This is because, the constructor in the child class does not expect any input arguments. 


Ubuntu - Mount a ephemeral storage on AWS EC2 machine.

Consider a AWS EC2 machine which is accompanied by an ephemeral storage. Many times, this ephemeral storage is not visible to us. In such a situation, we have search for it and set it up manually. Following are the steps taken by me to identify and mount ephemeral storage on a EC2 machine.


Step 1: Identify the disk which needs mounting . For this we run the fdisk command:
ubuntu@ip-XXX-XXX-XXX-XXX:~$ sudo fdisk -l
Disk /dev/loop0: 87.9 MiB, 92164096 bytes, 180008 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop1: 12.7 MiB, 13324288 bytes, 26024 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/nvme0n1: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9f3e4931

Device         Boot Start      End  Sectors Size Id Type
/dev/nvme0n1p1 *     2048 16777182 16775135   8G 83 Linux


Disk /dev/nvme1n1: 46.6 GiB, 50000000000 bytes, 97656250 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
ubuntu@ip-XXX-XXX-XXX-XXX:~$

Step 2: Once we have identfied our ephemeral storage which we want to mount. Next we identify the folder on which we want to mount it on. Since,we have decided to mount it on /opt . Now we will proceed with the following steps:

ubuntu@ip-XXX-XXX-XXX-XXX:/$ sudo mkdir opt

Step 3: Create filesystem on your volume (make sure you choose the correct volume because this creates a new file system on the volume):

ubuntu@ip-XXX-XXX-XXX-XXX:/$ sudo mkfs.ext4 /dev/nvme1n1
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done                            
Creating filesystem with 12207031 4k blocks and 3055616 inodes
Filesystem UUID: 1e7f28c2-19b3-4a94-8689-4d9b75496eff
Superblock backups stored on blocks: 
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done   

Step 4: Let us now, mount our volume:
ubuntu@ip-XXX-XXX-XXX-XXX:/$ sudo mount -t ext4 /dev/nvme1n1 /opt
ubuntu@ip-XXX-XXX-XXX-XXX:/$ mount -a
mount: only root can use "--all" option
ubuntu@ip-XXX-XXX-XXX-XXX:/$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.8G     0  1.8G   0% /dev
tmpfs           371M  716K  370M   1% /run
/dev/nvme0n1p1  7.7G  1.1G  6.7G  14% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/loop0       88M   88M     0 100% /snap/core/5328
/dev/loop1       13M   13M     0 100% /snap/amazon-ssm-agent/495
tmpfs           371M     0  371M   0% /run/user/1000
/dev/nvme1n1     46G   53M   44G   1% /opt
ubuntu@ip-XXX-XXX-XXX-XXX:/$ 


Step 5: If you want to preserve the mount after e.g. a restart, open /etc/fstab and add the mount to it

ubuntu@ip-XXX-XXX-XXX-XXX:/$ echo "/dev/nvme1n1 /opt auto noatime 0 0" | sudo tee -a /etc/fstab
/dev/nvme1n1 /opt auto noatime 0 0
ubuntu@ip-XXX-XXX-XXX-XXX:/$ 

Step 6: Make sure nothing is wrong with fstab by mounting all
ubuntu@ip-XXX-XXX-XXX-XXX:/$ sudo mount -a
ubuntu@ip-XXX-XXX-XXX-XXX:/$ 

Step 7: Check for the available disk size:
ubuntu@ip-XXX-XXX-XXX-XXX:/opt$ df -h .
Filesystem Size Used Avail Use% Mounted on
/dev/nvme1n1 46G 53M 44G 1% /opt
ubuntu@ip-XXX-XXX-XXX-XXX:/opt$ ls
lost+found
ubuntu@ip-XXX-XXX-XXX-XXX:/opt$ ls -l
total 16
drwx------ 2 root root 16384 Nov 13 08:45 lost+found
ubuntu@ip-XXX-XXX-XXX-XXX:/opt$ 





Reference:

Saturday, November 10, 2018

TypeScript - Classes - Inheritance

The main advantage of inheritance is to the developer. This is because, it enables code reuse. To inherit, we use the extends keyword. The following example the class Visakhapatnam extends the City class. Refer to it in the following link:
https://sashankexpresstech.blogspot.com/2018/11/typescript-classes-public-methods-and.html


class Visakhapatnam extends City{
name = "Visakhapatnam";
protected elevation = 45;

}

const cityVisakha = new Visakhapatnam("Visakhapatnam");
console.log(cityVisakha);
console.log(cityVisakha.name);
cityVisakha.setType("Town");
console.log(cityVisakha.printType());
console.log(cityVisakha.getElevation());
console.log(cityVisakha);


All the members of the City class got inherited by Visakhapatnam class. The constructor is also inherited by the child class. To modify the private and protected properties of the object. We need to use the set methods defined to modify them.


Reference:

  • https://www.typescriptlang.org/docs/handbook/classes.html


TypeScript - Classes - public methods and access modifiers

Now the question arises, If i have declared private and protected properties in a class. How can we modify them? The answer is, we modify them using public methods of the class.

In the below example, we have a class City in which, we have 2 private properties:
  • type
  • elevation
Okay, elevation here is protected. But, remember, protected property is a private property. It has an additional feature that it can get inherited by a child class.

class City {
public name:string;
private type: string;
protected elevation: number;

constructor(name:string) {
this.name = name;
this.type = "city";
this.elevation = 505;
}

setElevation(elevation:number){
this.elevation = elevation;
console.log("new elevation = "+this.elevation);
}

getElevation(){
console.log(this.elevation);
}

setType(type:string){
this.type = type;
console.log("new type = "+this.type);
}

printType(){
console.log(this.type);
}

}

const city = new City("Hyderabad");
console.log(city);
city.getElevation();
city.setElevation(506);
city.printType();
city.setType("Metro");
city.printType();


To access these two private properties, we have created 4 public methods.
  • 2 methods for setting value
  • 2 methods for getting the value of these properties
The public methods created here are:
  • getElevation
  • setElevation
  • printType
  • setType
The set methods accept one argument here - which modifies the corresponding private properties.
The get methods enable us to retrieve the values contained in the private properties.

Let us compile the class:

$ tsc
$

Console Output:

City {name: "Hyderabad", type: "city", elevation: 505}
city-App.ts:104 505
city-App.ts:100 new elevation = 506
city-App.ts:113 city
city-App.ts:109 new type = Metro
city-App.ts:113 Metro

We can observe here - how the properties are affected using the set methods. Also, the output from the get methods are also visible in the Console.