Unit 1: Data & Objects

In this unit we will discuss various data types that assist with storage and organization of data. This will lead into Objects and an introduction to Object Oriented Programming.

1.0 - Primitive vs Abstract Data Types

Simple variables that can be stored in a byte of memory are called primitives. The typical primitive data types in a programming language are:

  • boolean

  • integer (byte, short, int, long, char)

  • float (float, double)

Note: characters (char) are actually integers

Abstract Data Types require more processing power and memory. They are a combination of the primitive types.

  • Array

  • String

1.1 - Custom Data Types in JS

Before we begin, we will need to learn how to declare something more custom than a number or boolean in JavaScript. Take a look at this simpler example of creating a variable that has a name and a boolean for on or off:

let light_switch = {

name: "Living Room",

state: "off",

change_state: function() {

this.state = (this.state == "on") ? "off" : "on";

return this.state;

}

};


That allows us to keep track of the name of the switch and the status of it, all in one. Let's head over to Replit to see more examples and test it out ourselves.

1.2 - The Stack

Arrays provide access to any element at any time. But what if we only want to provide access to the last element placed in the array?

A stack is an abstract data type that we call Last In First Out (LIFO). Similar to a stack of pancakes or plates, the only one you have direct access to is the one on top - the last one placed on the stack.

A Stack employs the following functions:

  • Push, which adds an element to the collection,

  • Pop, which removes the most recently added element that was not yet removed, and

  • Peek, which returns the most recently added element without removing it from the stack.

Here is a visual representation of push and pop.

Let's head over to Replit to take a look at coding a stack in JavaScript.

1.3 - Arrays are an Abstract Data Type!

We've been using Arrays like a magical bag of holding. Put whatever you want in there, remove things, etc... But have you given any thought as to how they work or what we would do without them?

In other languages (C++, etc) the memory is a fixed size that the developer must allocate a specific size in advance. In JavaScript, Arrays have no set size - pushing to the array increases the size for us. Memory is allocated and deallocated for us by the "garbage collector" in the background.

JavaScript's implementation of Arrays mimics an ADT called a doubly-linked list.

Let's practice some work with arrays to make sure we know how to work with them.

1.4 - 2D Arrays

What if your pencil case could hold other pencil cases?

Think of a single array like a shelf holding jars.

Now think of a bookshelf with numbered shelves, each holding jars.

Need the third jar on the top shelf? myShelf[0][2]
How about the second jar from the middle shelf? myShelf[2][1]
Need the entire middle shelf? myShelf[2]

When is this useful, you might ask? All the time! Think about games like Tetris, Pacman, Bejeweled, or Battleship.

Head over to Replit for more.

Heads up! - Arrays in JS are passed & copied by reference

What does this mean - by reference?

It means that when you try to make a copy or pass an array into a function, it does not actually duplicate every item in the array to create separate arrays. It makes a link or shortcut to the array.

let og_sheep = ['πŸ‘', 'πŸ‘'];
let sheeps2 = og_sheep;

sheeps2.push('🐺');

console.log(sheeps2);
// [ 'πŸ‘', 'πŸ‘', '🐺' ]

console.log(og_sheep);
// [ 'πŸ‘', 'πŸ‘', '🐺' ]

😱 - our original sheeps have a wolf?!

(source)

Practicing Data Manipulation & 2D Arrays

If you have not completed 1.4a and 1.4b, you should do so. If you are stumped on a particular function, ask a classmate or move on to this:

I am often asked "how do I become a better programmer?" and the simplest answer is - program! You need to practice and see patterns or repetitious problems / solutions in order to improve. It's like working construction - at first you have no idea what you're doing. After working on a few projects, you use your experiences to help inform your decisions.

Most of the problems in Code Chef involve data that is stored in a 2D array (that I named test_cases). I would like you to attempt the following practice problems on Code Chef and then branch out and try some other problems on your own.

The input loading code is below (same as in the Code Snippets project in Replit). Select NodeJS as your programming language in Code Chef and paste the input code, replacing anything already in there. You can save it as your template for future practice problems. Keep in mind that your output for any problem is through console.log(), not return, and it must match their description perfectly.

  • t: Either the number of cases or the first (and only) test case. This depends on if the challenge has multiple lines of input.

  • input: a String of the entire input. Each line is separated with the \n character. This makes working with the data a bit difficult. See test_cases below.

  • test_cases: a 2d array of the test cases where [0] is the first test case, not T. Keep in mind, this is a 2d array so reading each line requires loops.

  • current_case: a global counter starting at 0 for tracking what case you are currently testing. Completely optional.


Note: Your code should be written in the go() function. You may add as many helpers as you need. This code makes a lot of assumptions - like the first line is a single number, T, all inputs are numbers, etc.

process.stdin.resume();

process.stdin.setEncoding('utf8');


let input = '';

let test_cases = [];

let t = 0;

let current_case = 0;

process.stdin.on('data', chunk => input += chunk);

process.stdin.on('end', preprocessing);

// Convert the input array to a 2d array of ints

function preprocessing() {

input = input.split("\n"); // convert the input string to an array of strings

// Check for an empty ending (new line only)

if (input[input.length - 1].length == 0) input.pop();

t = Number(input[0]); // 't' = Number of test cases


let temp;

for (let x = 1; x < input.length; x++) {

temp = input[x].split(" ");

for (let y in temp)

temp[y] = Number(temp[y]);


test_cases.push(temp);

}

if (test_cases.length == 0) test_cases.push([t]);

go();

}

/* ------------------------------------- */

/** YOUR CODE GOES IN THE go() FUNCTION **/

function go() {


}

Recommendations

Login to Code Chef first, before clicking a link below.

Code Chef Practice Problems:

(but you can also pick your own)

1.5 - Objects (Class Definitions & "New" Keyword)

Hang in there - this lesson is a real doozy.

Recall

Recall when we made our own abstract data type for a Stack:

const stack = {

contents: [],

is_empty: function() {

return (this.contents.length == 0)

},

push: function(content) {

this.contents.push(content);

},

pop: function() {

if (this.is_empty())

return "The stack is empty";

else

return this.contents.pop();

},

peek: function() {

if (this.is_empty())

return "The stack is empty";

else

return this.contents[this.contents.length - 1];

}

};


This allowed us to store and retrieve information in that custom data structure. But what if we needed to use more than one stack? In this style, we would need to copy and paste that exact code to make a const stack2 or something silly like that. Abstract data types as defined in lessons 1.1 and 1.2 cannot be copied. They are limited to one implementation per definition.



Classes

A class is a blueprint for a data structure that describes an object. Since it is a blueprint, we can make copies of it (called "instances"). As many copies as we need!

class Stack {

// Other code goes here

}

We give the class name a capital first letter: Stack. This is a standard. Similar to String, Math, or Array.


We can give the Stack properties just like a house or your shirt have properties: colour, height, number of sleeves, etc. In code these are variables. To an object, they are descriptors or values: properties.

class Stack {

name = "";

contents = [];

max_length = 255;

// Etc...

}

Notice the lack of let, var, or const. More on this later, but essentially the let is implied.

New

Now that we have a blueprint for our object, we want to make an instance of one. This is called instantiation. We have already seen this when we ask JavaScript for a new array:

let arr = new Array(10); // get a new array of size 10

Guess what? Arrays are objects! By using the new keyword, we are asking JavaScript to create (or instantiate) an instance of an Array object - in this case of size 10. That means we can do it with our Stack!

class Stack {

name = "";

contents = [];

max_length = 255;

}


// Create two instances of a stack, completely unrelated to each other

let my_stack = new Stack();

let another_stack = new Stack();

Working with Properties

How do we get access to the "name" property in the above examples? Or how do we change it?

Once an object is instantiated you can get or set the values of object propterties using the dot-notation we've seen with the String and Math objects:

let my_stack = new Stack();

my_stack.name = "Pretty little stack";


console.log(my_stack.name); // 'Pretty little stack'

console.log(my_stack.max_length); // 255

Let's Practice

The diagram you see here is called a class diagram. More on that later but the basic pattern is:

property_name: data_type = optional_default_value

If no default value is required:

property_name: data_type

The first class you are to define is a Circle. It has two properties: name and radius. Both have default values. Notice that the Vehicle class only has one property with a default value.


Define those three classes with the given properties. Then hit "run" and play around in the console making instances of your classes and modifying properties. For example, you could run:

let rect1 = new Rectangle();

rect1.length = 10;

rect1.width = 20;

console.log("The area is:", rect1.length * rect1.width);


(Optional extra)

For a neat activity, try writing a function that takes a circle object and returns the area of that circle. Or another one that takes a rectangle object and returns the length of the diagonal:

function area_circle(circle) {

}


function rect_diagonal(rect) {

}

1.6 - Objects (The Constructor & Class Methods)

To be honest, the lessons that you see here are basically duplicated (and usually better) inside Replit. I'm not really sure why I keep posting the lesson in two different places. I suppose it's a "just in case" for students who can't get to Replit or if I fail to publish the project in Replit. This site is also public so parents and general community can see it. But I have to admit - I'm tired. So I'm going to go to bed now. ZZZzzz