2: Efficient Code

Diction note: I’ll be using the terms “compile” and “compiler” a lot over this chapter. A “compiler” takes something humans can read and edit easily (like a Java or C++ program) and converts it into something that computers can read easily (known as bytecode, if you ever open an EXE file in a text editor this is what you’re looking at). To “compile” is to run a compiler on a program - you won’t generally have to touch this much, because Intellij will compile and run for you. It’s important to note that running a program (telling the computer to start reading and using bytecode) is very different from compiling!

Ok, ok, I lied. We aren’t going over classes and functions today. We do still have a lot of topics to cover, however. Firstly we’ll go over clean practices of when to use certain types of statement - when to use if, when to use switch (please don’t use switch, it’s immensely dirty), when to use for, when to use while, and how to use their various features to your benefit. If I have enough space, we’ll also go over some thumb-rules on how to write code that compiles first try. This article will mostly not apply to web development - I’ll write something for y’all CS 1300 folks soon, don’t worry.

2.1: Switch, case, if, and else

These are four very similar syntactical constructs that you probably know well by now. If you don’t, or want a quick refresher, remember that:

Note: Over this book I refer to switch/case as an ugly, dirty, and useless logic flow that can and should be replaced by the superior if/else if/else. The allure of switch/case is, however, undeniable - they allow you to shave off some work and match values in bulk. However, most of the time, unless you’re using them very carefully, they just make code dirtier. An easy rule of thumb is- if you have a bunch (or plan to, planning is important!) of fairly uniform logic operations (only == is supported by switch/case) you want to check against a single value and do very simple operations, you should be using switch/case, but if you have ANY other situation you should not. An example is when I used a switch/case statement in Platformer for art, because styles are determined by a single value (a string), so it made it cleaner instead of the opposite.

switches and ifs are very very different statements. ifs exist to do complex logic with every operator in the language - they can check less than, greater than, equal to, or not equal to, as well as run functions to test their results for even more powerful logic. On the other hand, switch statements exist to do purely equality checks, although I must admit they’re pretty good at it. So, you can extrapolate these general rules:

Now, you can replicate most of if’s functionality with switches, but that doesn’t mean you should. Indeed, you should definitely avoid doing so. That makes code dirty. You want clean, concise, and efficient, not bloated. A C++ example of what you shouldn’t do is,

#include <stdio.h> // Necessary for the program to actually run but you don't have to worry about it too much
#include <iostream>


int main(){
    int theySaid;
    std::cin >> theySaid; // Same idea as scan.nextInt(), now theySaid is equal to some piece of user input
    switch(theySaid > 50){
        case true:
            std::cout << "Your number is more than 50" << std::endl; // Just a printout.
            break;
    }
    
    switch (theySaid < 50){
        case true:
            std::cout << "Your number is less than 50" << std::endl; // Like System.out.println()
            break;
    }
    
    switch (theySaid){
        case 50:
            std::cout << "Your number is exactly 50! Hooray!" << std::endl;
            break;
    }
    
    return 0; // System-level stuff, don't worry about it
}

(This is verified to run). This technically works, but it’s kinda stupid. It’s bloated and does one more check than necessary. Observe the proper version (c++ still),

#include <stdio.h> // Necessary for the program to actually run but you don't have to worry about it too much
#include <iostream>


int main(){
    int theySaid;
    std::cin >> theySaid; // Same idea as scan.nextInt(), now theySaid is equal to some piece of user input
    if (theySaid > 50){
    	std::cout << "Your number is more than 50" << std::endl; // Just a printout.
    }
    else if (theySaid < 50){ // Else ifs are fun. Basically, if the last thing didn't return true and this next thing does return true, run some code.
    	std::cout << "Your number is less than 50" << std::endl; // Like System.out.println()
    }
    else{ // Runs if the last else-if didn't run.
        std::cout << "Your number is exactly 50! Hooray!" << std::endl;
    }
    
    return 0; // System-level stuff, don't worry about it
}

(Also verified). See, much cleaner! You don’t have to manually check against true, and you can group it all together in one block to reduce the number of operations you do and make it so only one of the printouts ever happens under any circumstances. This all applies to Java as well - surely you’ve recognized some syntaxes. However, switch/case becomes useful in situations like this (Java because C++ is weird about strings in switch/case),

import java.util.Scanner;


class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String input = scan.nextLine();
        if (input.equals("Hello")){
            System.out.println("Hello yourself");
        }
        else if (input.equals("Goodbye")){
            System.out.println("Where ya goin, city boy?");
        }
        else if (input.equals("Sausage is good")){
            System.out.println("Bacon is better");
        }
        else if (input.equals("Eggs and Biscuits are good")){
            System.out.println("What are you, Southern?");
        }
        else if (input.equals("Gravy and grits is best")){
            System.out.println("That's a good answer to my question");
        }
        else if (input.equals("Free market economies cause an underprivileged lower class")){
            System.out.println("I'm getting very mixed messages here.");
        }
    }
}

That’s kinda painful. In this single case, it actually gets more efficient to use switch/case, like so:

import java.util.Scanner;


class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String input = scan.nextLine();
        switch(input){
            case "Hello":
                System.out.println("Hello yourself");
            	break;
            case "Goodbye":
                System.out.println("Where ya goin, city boy?");
            	break;
            case "Sausage is good":
                System.out.println("Bacon is better");
            	break;
            case "Eggs and Biscuits are good":
                System.out.println("What are you, Southern?");
            	break;
            case "Gravy and grits is best":
                System.out.println("That's a good answer to my question");
            	break;
            case "Free market economies cause an underprivileged lower class":
                System.out.println("I'm getting very mixed messages here.");
            	break;
        }
    }
}

Both of these programs are verified to run.

You’ll notice that if there were only a couple, instead of 6, you’d want to use if/else; switch/case is only efficient when you have a largish number of statements (a very experienced code teacher I’m friends with corroborates, by the way).

2.2: For Loops

Ah yes. Loops. I’m not certain how many of you know how to use these already - I’m assuming most CS students by now are acquainted with basic for loops, and maybe have heard of while loops. However, I’ve noticed that the class is doing somewhat of a poor job of teaching them, so let’s go through for loops again. If you’re pretty sure you don’t need to read this part, read it anyways, because you can never be sure.

What is a for loop? A for loop is a way to run a piece of code a set number of times. It’s structured rather like an if statement, but with a lot more where the condition goes. Generally they look something like this:

for (int i = 0; i < 10; i ++){
    // Your code goes here
}

This doesn’t tell you too much, however. So let’s dissect it, Platformer from Scratch (my previous internet book, available on this website) style.

From there you just put your code in curlies ({}) and you have a for loop!

2.3: While loops

There’s a fair chance you haven’t heard of while loops yet. They’re basically if statements that continue running the code until the condition returns false - like a for loop without the iterator variable. The syntax (in most languages, actually, not just Java) is,

while (condition){
    // Code that runs until condition is false
}

A good example is checking the validity of user input, like so:

// Assume there's a class set up with a Scanner named scan and all
System.out.println("Question (Y/N): ");
String input = scan.nextLine();

while (!input.equals("Y") && !input.equals("N")){ // The check runs over and over again, so you can just change the value of input and if it's valid the loop breaks
    // While the input isn't Y and the input isn't N
    System.out.println("Please give Y or N: ");
    input = scan.nextLine(); // Prompt again.
}

System.out.println("Thank you for your response!");

(verified correct)

Running this will give something like,

Question (Y/N): 
L
Please give Y or N: 
Z
Please give Y or N: 
n
Please give Y or N: 
Y
Thank you for your response!

You don’t have to use nested ifs or break the program, you can just hang until they provide useful data! More advanced implementations of this are of course possible, but I won’t get into those.

Note: Be aware of while loops! They can and will hang your program forever (infinite loop) if for some reason the condition is never false.

That wasn’t so bad! If you need more on while loops, I think a good Google query is Java while loop (replace “Java” with whatever language you’re in; HTML and CSS don’t have them so don’t bother with those).

2.4: When to actually use For and While + Miscellaneous stuff

I think the situations in which you might want to use a for loop or a while loop are fairly obvious, but choosing which one might be more difficult. In general, you use for if you need an iterator and while if you don’t; here’s a list of thumbs:

Because this was a fairly short section, I’ll also include some bonus miscellaneous information.

Well, that was a quick chapter! I hope you find it at least marginally useful.

The next installment will probably be for HTML and CSS, such as how to keep them clean, efficient and minimal. This is a very large and difficult topic so it’s probably going to be a very large and difficult chapter. If I don’t post before this Friday afternoon, it won’t be out until the weekend after next, as I’ll be out-of-state for a week.

See ya soon, and keep coding!

My friend's blogs: Wizardwatch's overall site, Sawyer's blog (the .org part bemuses me), Luke's site. If ryleu decides to actually put something on his site, I'll link it here.