6. Data Types And Operators

Welcome back, programmer! Programming is all about data. It’s about inputting information (your username, your birthday, your next upload on Instagram), and then writing a program that will manipulate the received data (validating a username and password, computing a delivery date, applying a filter to a photo etc). Ultimately, your programs will return the modified data to us, the users.

To write programs that can do something with data, we must first understand different types of data and the tools (logic and operators) that allow us to manipulate data.

Let’s get started.

Giving The Computer Some Context

Remember that time you pretended to be a computer? We, the programmers, asked you to go to the coffee machine. But because you were a computer, you didn’t really know how to get to the coffee machine. Walk or run?

Let’s not forget that computers can’t think! They don’t understand context. So what’s a programmer’s job? To give the computer detailed and specific instructions. This job is especially true for data. When you see something like 10/13/2007 you automatically know it’s a date. When you see 3, you know it’s a number and that I like ice cream is a sentence. A computer does not. It’s your job to tell it.

To help you do your job, each programming language defines a set of basic data types that you can use to talk data to your computer. When we start learning about object-oriented programming, we’ll find that we can also create our own data types.

Common Data Types

Let’s take a look at the common data types that most programming languages already define for us.

Numbers

Numbers can come in various flavors. Integers and floats are the most common ones.

Integers

Integers represent numbers without any decimals. For example, 1131024 are integers. 3.42.0 and 4/3 are not. 0 and negative numbers such as -10 are also integers. To tell the computer we want to use an integer value, we just use the literal value, without any need to prefix it with anything or enclose it in a special tag. When the computer sees 3, it assumes that we mean the integer value 3. Easy!

Floats

When we need a fractional component, we use floats. For example, 7.8 and 100.0 are floats. Like integers, they can also be negative numbers, such as -12.786. Note that to separate the integer part from the decimals, we use a dot . and not a comma. This is a standard implemented by most programming languages, if not all. Thus, 17,34 would not be interpreted by the computer as a valid float.

To make sure the computer knows we want to use a float and not an integer, we simply write its value with a dot, even if it doesn’t have a decimal. So 3 would be interpreted as an integer value while 3.0 would be interpreted as a float value.

Text

Say you need to output a message to your users (“You’re awesome!” or “Thank you for visiting!”), or to take an input from them (“What’s your name?” or “How many hot dogs can you eat?”). You’ll need to work with text!

Characters

The most basic text format you’ll find when writing code is the single character. To instruct the computer that we’re using a character, we enclose it within single quotes. These are valid characters: 'a''G''$'. This wouldn’t be a valid character: 'ab' as a character can only be a single letter (or digit) and not a combination of several.

Following this logic, what would a computer think of '5'? Integer or character? It would see it as a character value and treat it as such because of the single quotes surrounding the number.

Strings

If you need to group characters together in order to create words and sentences, you’ll need to use the string data type. A string is just that: a string of characters. To differentiate characters and strings, we enclose strings within double quotes. Here are some strings: "Hello!""I'm learning how to program""H". Yes, even a single character can be a string. Even though we know it’s a single character, if it’s enclosed in double quotes, the computer will see it as a string.

It’s by marking strings with double quotes that the computer knows that we mean a literal string and not a statement. Here’s an example:

myString = "Display hello on the screen"
Display myString on the screen

This would output the text Display hello on the screen, not just hello, to your users. All text between double quotes is treated as literal text; never as a statement.

Special Types

Booleans

Most languages also define a special type of value called a boolean. A boolean can only be one of two possible values: true or false. This is the data type we use in combination with the previously seen if keyword, to add some conditional logic to our programs. To tell the computer that we want to use a boolean value, we just type true or false in our source code. Here’s an example:

areYouHungry = true

if areYouHungry equals true {
  Display "Eat an apple" on the screen
}

if areYouHungry equals false {
  Display "Maybe you want something to drink?" on the screen
}

Above, we set a variable named areYouHungry and then used conditional logic to display the appropriate message.

The Null Value

Sometimes, it’s useful to specify the absence of a value. In later lessons we’ll explain why this is so, but for now, let’s just explore how we do so. We tell the computer that we want to use the null data type by just typing nil into our source code. No need for quotes or special characters. nil is not equal to 00 is an integer value that represents zero. On the other hand, nil is not even zero. It is nothing. Don’t worry if this is mind boggling at the moment, we’ll come back to it soon.

Custom Data Types

Say we want to represent something other than text or numbers in our code. A photo of your cat? A car? A plane? A ninja? This is when we need to create our own data types. First, we have to tell the computer what these data types are before we can use them. Custom data types are not the subject of this lesson, though. We’ll learn about them soon, but for now, just remember that they exist!

Explicit Typing And Type Inference

Do you remember how variables work? If not, read the lesson on variables again! We’ve seen that variables are like small boxes stored in memory (the RAM) containing values you store in them for future use.

When you create a new variable, what size should the computer reserve in its memory? Well, the technical answer is: it depends on the data type you want to store within the variable! If we need to pack 20 books in a box, we first need to get an empty box of the appropriate size. This is exactly what we are doing when we instruct the computer to reserve memory.

A certain amount of memory is made available for an integer variable. A different amount of memory is reserved for strings or floats. The exact amount reserved for each type depends on the system, but this isn’t relevant for now. What is relevant, though, is that there are two ways to inform a computer what data type you’re going to use for a variable: type annotations and inferred types.

Some programming languages are said to be untyped. It means that whatever the data type you want to store in a variable, the computer will always reserve the same amount of memory. JavaScript is an example of an untyped language. It is one of the reasons we don’t recommend JavaScript as a first language if you’ve never programmed before.

Type Annotations

When we say that a language must annotate its data types, we mean that before we can assign something to a variable, we must explicitly inform the computer which data type the variable can contain. Using pseudocode, let’s try this with the keyword as followed by the relevant data type:

numberOfApples as Integer = 7
mySecretMessage as String = "Hello. This is a random piece of text."
pi as Float = 3.1415

Note that we only need to explicitly set the variable type before we assign something to it for the first time. Once a data type has been set for a variable, it can’t be changed and the variable is expected to always store a value belonging to that data type:

numberOfApples as Integer = 10
numberOfApples = 20
Display numberOfApples on the screen

In this example, we declared (the correct term for creating a variable) a variable named numberOfApples of type Integer and assigned it the value 10. Then, we called the same same variable and changed the value inside it with another integer. Note that we didn’t have to set its data type again. Finally, we made use of our variable to display its content on the screen. Again, we didn’t have to specify the data type used by the variable. The computer already knew its type, since we set it when we first created it.

The following code would make the computer crash. Can you figure out why?

numberOfApples = "About 21 apples"
// BOOM! Here the program will crash!

This code makes the program crash because we tried to place a string value inside the Integer variable we declared earlier. The amount of memory necessary for an integer is smaller than the amount the computer needs for a string.

Type annotations are not only used for memory management, they also enforce type safety, a mechanism that prevents us from assigning an unexpected value to a variable. See it as a safety net for the careless (or tired!) programmer.

Type Inference

Many modern languages can deduce which data type you mean to store in a variable just by looking at its value. This is called type inference. Swift and Scala, for example, can be written both with type annotations and type inference. If you want to store 48 in a variable named age, you don’t need to explicitly declare it as integer. By looking at the number 48, the computer sees it’s not a float and not surrounded with single or double quotes, and it can intelligently deduce that 48 is an integer:

numberOfBananas = 1
numberOfMinions = 2500
someMessage = "This is some text. Hello!"
oneLetter = 't'

But Which Type Should I Choose?

If the language supports type inference, it really comes down to the programmer to choose whether to utilize it or not. Being explicit helps readability, but inferring data types allows one to code faster and to be more concise.

Nevertheless, sometimes there are cases when type annotation is extremely useful. This is especially true when mixing data types in a single statement. Check this out:

result = 3 + 2.5

The literal value 3 is an integer, the literal value 2.5 is a float. If we use type inference, what data type will the result be? In most programming languages, it’ll always be of the data type offering the most precision. In this case, result would be of type float. If the integer type was inferred, we would be at risk of losing data, in this example, the .5 because an integer can’t store decimals. This is a typical example where being explicit is useful and offers more clarity as to what your intent is:

result as Float = 3 + 2.5

A little bit more typing can save you (or your team members!) hours of searching for the cause of an issue at a later time!

Operators

At the start of this lesson, we mentioned that we would soon learn how to treat and manipulate data. For example, adding integers together in a function to return a sum. This is a simple example of operators coming to the rescue. Let’s meet some common ones.

Assignment Operator: =

We’ve already met this assignment operator! We’ve used it several times throughout the previous lessons. It’s represented by the equals sign (=) and it means assign to the variable on the left the value that is on the right.

You can also use the assignment operator to copy the content of a variable onto another:

wallColor = "white"
doorColor = wallColor

Now, doorColor would contain "white". In English, we’d say assign to doorColor the value of wallColor.

Plus Operator: +

The plus sign can mean two things: the arithmetic plus or the string concatenation operator. If + is used on one of the numbers data types, it will add numbers. If it is used between two strings, it will add one to the other also known as strings concatenation.

  • 3 + 2 outputs 5
  • "Hello " + "world!" outputs "Hello world!"
  • 5.0 + 4.2 outputs 9.2
  • "10" + "20" outputs "1020"
  • "a" + "bcd" outputs "abcd"

Minus Operator: –

The minus sign is used for subtractions between numbers.

  • 10 - 5 outputs 5
  • 120.10 - 0.1 outputs 120.0
  • 15.0 - 5.0 outputs 10.0

Multiplication Operator: *

Programming languages usually use the asterisk (*) to denote a multiplication.

  • 3 * 4 outputs 12

Division Operator: /

The division sign is represented by a forward slash (/).

  • 12 / 3 outputs 4

But what happens if you divide an integer by another one, and the result should be a fractional number? The result depends, once again, on the programming language. But it’s very common for the resulting integer to be truncated. For example, 10 / 3 equals 3 and 10 / 6 equals 1. Note how rounding doesn’t happen. Every decimal just disappears.

If you want to keep the decimals after an integer division, one of the two numbers must be a float. For example, 3 / 2.0 would result in 1.5. There’s another way called casting. We’ll explore that technique at a later stage. Fow now, if you get all of this, you’re gold!

Modulo Operator: %

The modulo operator returns the remainder of an integer division. For example, 4 % 3 outputs 1. We’ll see some practical examples using the modulo operator soon.

Relational Operators

There’s another type of operator, whose purpose is to compare data. These are known as relational operators. Like the boolean type, they’re mostly used for applying conditional logic in your code. Let’s see this in action.

Equal

Until until now, our pseudocode has always made use of the English phrase “is equal to” to describe equality. In most programming languages, is equal to is represented by a double equal sign (==). The result of an equality operation always returns a boolean value (true or false).

myAge = 35
yourAge = 38

if myAge == yourAge {
  Display "we are the same age." on the screen
}

In this example, the equality test (myAge == yourAge) would return false, displaying nothing on the screen.

Not Equal

Similarly, there’s a “is not equal to” relational operator: !=. Each time you see !=, you can say: the left side is not equal to the right side. As with the equality operator, the result of a not equal operation returns a boolean value.

carColor = "green"
bikeColor = "green"

if bikeColor != carColor {
  Display "the two vehicles have different colors." on the screen
}

Again, nothing would be displayed on the screen, as both variables store the same string representing the same color.

Greater Than, Less Than, Great Than Or Equal To, Less Than Or Equal To

There are four more relational operators that also return true or false – how exciting!

  • > means greater than
  • < means less than
  • >= means greater than or equal to
  • <= means less than or equal to

Let’s check this out with pseudocode:

apples = 3
oranges = 10
bananas = 3

if apples > oranges {
  Display "There are more apples than oranges" on the screen
}

if apples >= bananas {
  Display "There are more apples than bananas or the same quantity" on the screen
}

if bananas < oranges {
  Display "There are less bananas than oranges" on the screen
}

Now let’s use plain English:

  1. Declare 3 variables representing fruits and assign an integer value to each, representing their quantities.
  2. Check whether there are more apples than oranges (does apples > oranges return true?). If yes, display a message on the screen.
  3. Check whether there are more apples than bananas or the same quantity. If yes, display a message on the screen.
  4. Check if there are less bananas than oranges. If yes, display a message on the screen.

What a fruit salad! Hungry yet?

And / Or

There are some instances when we would want to test for more than one conditional check. Meet your new friends: and and or. These work in code like they do in English. Consider the following sentence:

  • Say “Good morning, Sir” if it’s morning and the person is a man

The and used in the sentence would be represented in code by a double ampersand character: &&. Let’s translate this into pseudocode:

person = "man"
timeOfDay = "evening"

if (timeOfDay == "morning") && (person == "man") {
  Display "Good morning, Sir" on the screen
}

The message wouldn’t be displayed on the screen because the two equality checks need to evaluate to true. Note that to separate multiple conditional checks, we wrap them between parentheses ( ). In this case, the first check, timeOfDay == "morning", would evaluate to false.

We can apply the same logic to the or operator. We represent or using two pipe characters (tip: CMD + 7 on the Mac keyboard and AltGr + 7 on a Windows keyboard): ||.

person = "woman"
age = 60

if (person == "man") || (age > 50) {
  Display "The person might be a man or might be older than 50. One of them is true"
}

Here, even though the first conditional check evaluates to false, the message will be displayed on the screen because the second conditional check evaluates to true. With the or operator, only one check needs to be true for the whole expression to be evaluated to true. When we use or in English, we mean one or the other, but not bothIn code, we mean *one or the other, or both.*

Summary

We’ve covered a lot of ground! At this point, you might be feeling a little overwhelmed, wondering how all of this theory will allow you to create actual applications. Little by little, step by step as you continue your journey of code, everything will come together and you’ll be able to call yourself a programmer.

In this lesson, we explored common data types and how you can tell the computer which one(s) you want to use in your source code. We’ve learned the difference between type annotations and type inference as well as when to use each. Then, we had a look at several operators implemented in most programming languages, that allow us to manipulate data. Finally, we had a look at relational operators and how they can help us tell if something is true or false.

Rock on!

Important Words

  • Data type
  • Integer
  • Float
  • Character
  • String
  • Boolean: true and false
  • Nil
  • Type annotations
  • Type inference
  • Operators: +-*/%
  • String concatenation
  • Relational operators: ==!=>>=<<=

Exercise

Time to lay down the base of an app we’ll be building together very soon: a calculator! Let’s start small by creating a pseudocode function named Calculate that takes 3 arguments: two numbers and the operation (“add”, “subtract” etc). This function should return the result. Bonus point: can you write it using type annotations? As usual, don’t be shy and share your work in the comments below!

Share to friends