Computational Thinking + Doing

Selection Logic

Comparing how courses of action (based on certain conditions) are tested and taken—using R, Python, and Julia.

Selection logic (often embodied in if-else and switch-case statements) is a cornerstone of computer programming languages that enable decision-making capabilities within the code. By evaluating conditions that are either true or false, selection logic dictates which block of code are executed—ensuring a program’s flow is both controlled and predictable. This mechanism is crucial for handling different scenarios and outcomes, and allowing for dynamic responses to user input, data changes, or other environmental factors.

Selection logic is the bedrock upon which the reliability and functionality of programs are built—making it a fundamental concept in the field of computer science (CS). Let’s examine this CS 101 concept that you will use (and reuse) in almost all your code.


Boolean Data Type

Boolean data types represent two possible values: true or false. In selection logic, they serve as the foundation for decision-making—determining which code paths are executed based on evaluated conditions. They’re essential for controlling program flow and enabling conditional operations within software. Let’s validate this specific data type.

# Boolean value in uppercase
r_for_statistics = TRUE
typeof(r_for_statistics)
[1] "logical"
# Boolean value capitalized
python_for_data_science = True
type(python_for_data_science)
<class 'bool'>
# Boolean value in lowercase
julia_for_scientific_computing = false;
typeof(julia_for_scientific_computing)
Bool

Relational (or Comparison) Operators to Compare Two Values

Relational operators are symbols, such as >, <, ==, !=, >=, and <=, that compare two values. They evaluate the relationship between operands and return a Boolean value—pivotal for control flow decisions in selection logic.

# Equal to
1754 == 1856
[1] FALSE
# Not equal to
1754 != 1856
[1] TRUE
# Greater than
1754 > 1856
[1] FALSE
# Greater than or equal to
1754 > 1856
[1] FALSE
# Less than or equal to
1754 < 1856
[1] TRUE
# Equal to
1754 == 1856
# Not equal to
False
1754 != 1856
# Greater than
True
1754 > 1856
# Greater than or equal to
False
1754 > 1856
# Less than or equal to
False
1754 < 1856
True
# Equal to
1754 == 1856
false
# Not equal to
1754 != 1856
true
# Greater than
1754 > 1856
false
# Greater than or equal to
1754 > 1856
false
# Less than or equal to
1754 < 1856
true

Logical Operations to Combine Condition Statements

Logical operators like && (AND), || (OR), and ! (NOT) are used to combine multiple condition statements in programming. They orchestrate complex decision-making by evaluating combined conditions—returning a Boolean result that guides the execution flow in selection logic.

FOUNDING_COLUMBIA_UNIVERSITY <- 1754
FOUNDING_UNIVERSITY_MARYLAND <- 1856
FOUNDING_USA <- 1776

# AND operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) && (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
[1] FALSE
# OR operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) || (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
[1] TRUE
# NOT operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) && !(FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
[1] TRUE
FOUNDING_COLUMBIA_UNIVERSITY = 1754
FOUNDING_UNIVERSITY_MARYLAND = 1856
FOUNDING_USA = 1776

# AND operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) and (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
# OR operator
False
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) or (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
# NOT operator
True
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) and not(FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
True
const FOUNDING_COLUMBIA_UNIVERSITY = 1754;
const FOUNDING_UNIVERSITY_MARYLAND = 1856;
const FOUNDING_USA = 1776;

# AND operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) && (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
false
# OR operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) || (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
true
# NOT operator
(FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) && !(FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
true

If-Else and If...Else If...Else Statements

While the if-else statement is a two-branch selection construct in programming, the if...else if...else statement is a multi-branch selection construct that allows for multiple conditions to be evaluated sequentially. They direct the program flow to different code blocks based on the first true condition—enhancing decision-making precision and handling various outcomes in selection logic.

if (FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA && FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA) {
    print("Both universities are two of nine colonial colleges.")
} else if (FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA) {
    print("Columbia University is one of nine colonial colleges, but the University of Maryland is not.")
} else if (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA) {
    print("The University of Maryland is one of nine colonial colleges, but Columbia University is not.")
} else {
    print("Neither university is one of nine colonial colleges.")
}
[1] "Columbia University is one of nine colonial colleges, but the University of Maryland is not."
if (FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA and FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA):
    print("Both universities are two of nine colonial colleges.")
elif (FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA):
    print("Columbia University is one of nine colonial colleges, but the University of Maryland is not.")
elif (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA):
    print("The University of Maryland is one of nine colonial colleges, but Columbia University is not.")
else:
    print("Neither universities is one of nine colonial colleges.")
Columbia University is one of nine colonial colleges, but the University of Maryland is not.
if (FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA && FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
    print("Both universities are two of nine colonial colleges.")
elseif (FOUNDING_COLUMBIA_UNIVERSITY < FOUNDING_USA)
    print("Columbia University is one of nine colonial colleges, but the University of Maryland is not.")
elseif (FOUNDING_UNIVERSITY_MARYLAND < FOUNDING_USA)
    print("The University of Maryland is one of nine colonial colleges, but Columbia University is not.")
else
    print("Neither universities is one of nine colonial colleges.")
end
Columbia University is one of nine colonial colleges, but the University of Maryland is not.

Switch-Case Statement

Switch-case statements allow a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each case. If-else statements, on the other hand, check for a series of conditions and execute the first one that is true. Unlike if-else, switch-case can easily compare a variable to many values, making the code cleaner and more efficient.

founding_century <- function(year) {
    century <- floor(year / 100) * 100
    switch(
        as.character(century),
        "1600" = "Founding in the 17th century",
        "1700" = "Founding in the 18th century",
        "1800" = "Founding in the 19th century",
        "Unknown century"
    )
}

print(founding_century(FOUNDING_COLUMBIA_UNIVERSITY))
[1] "Founding in the 18th century"
print(founding_century(FOUNDING_UNIVERSITY_MARYLAND))
[1] "Founding in the 19th century"
print(founding_century(FOUNDING_USA))
[1] "Founding in the 18th century"
def founding_century(year):
    century = (year // 100) * 100
    return {
        1600: "Founding in the 17th century",
        1700: "Founding in the 18th century",
        1800: "Founding in the 19th century",
    }.get(century, "Unknown century")

print(founding_century(FOUNDING_COLUMBIA_UNIVERSITY))
Founding in the 18th century
print(founding_century(FOUNDING_UNIVERSITY_MARYLAND))
Founding in the 19th century
print(founding_century(FOUNDING_USA))
Founding in the 18th century
# Julia does not currently support switch-case statements

Summary

In programming, selection logic like if-else and switch-case statements, combined with relational and logical operators, guide the flow of execution based on specific conditions. Relational operators compare values, while logical operators combine multiple conditions. If-else statements execute different code blocks depending on whether a condition is true or false. Switch-case statements, on the other hand, allow a variable to be tested against multiple cases, executing the code associated with the matching case. These tools provide flexibility and control—enabling complex logic to be implemented efficiently and effectively, and thereby making our code smarter and more dynamic.


Appendix A: Environment, Language Versions, and Coding Style

If you are interested in reproducing this work, here are the versions of R, Python, and Julia that I used. Additionally, my coding style here is verbose, in order to trace back where functions/methods and variables are originating from, and make this a learning experience for everyone—including me.

cat(
    R.version$version.string, "-", R.version$nickname,
    "\nOS:", Sys.info()["sysname"], R.version$platform,
    "\nCPU:", benchmarkme::get_cpu()$no_of_cores, "x", benchmarkme::get_cpu()$model_name
)
R version 3.6.0 (2019-04-26) - Planting of a Tree 
OS: Darwin x86_64-apple-darwin15.6.0 
CPU: 4 x Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
import sys
import platform
import os
import cpuinfo
print(
    "Python", sys.version,
    "\nOS:", platform.system(), platform.platform(),
    "\nCPU:", os.cpu_count(), "x", cpuinfo.get_cpu_info()["brand"]
)
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 20:42:06) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] 
OS: Darwin Darwin-19.6.0-x86_64-i386-64bit 
CPU: 4 x Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
using InteractiveUtils
InteractiveUtils.versioninfo()
Julia Version 1.2.0
Commit c6da87ff4b (2019-08-20 00:03 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin18.6.0)
  CPU: Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, ivybridge)

Further Readings

  • Grolemund, G. (2014). Hands-On Programming with R: Write Your Own Functions and Simulations. O’Reilly.
  • Kalicharan, N. (2021). Julia—Bit by Bit: Programming for Beginners. Springer. https://doi.org/10.1007/978-3-030-73936-2
  • Kernighan, B. W., & Ritchie, D. M. (1988). The C Programming Language (2nd ed.). Pearson.
  • Lutz, M. (2013). Learning Python (5th ed.). O’Reilly.
  • Wickham, H. (2019). Advanced R (2nd ed.). CRC. https://doi.org/10.1201/9781351201315
Recent Thoughts