Data Types Lecture and Hacks

Initial Extra Credit on Seed

public class BinaryAddition {
    public static String add(String byte1, String byte2){
        return Integer.toBinaryString(Integer.parseInt(byte1, 2) + Integer.parseInt(byte2, 2));
    }
    public static void main(String [] args){
        System.out.println(add("101", "100"));
    }
}
BinaryAddition.main(null);
1001

Example Code Learned in Class

public class IntegerByValueOrReference {
    
    public static void changeInteger(Integer n) {
        System.out.println("In changeInteger method");
        System.out.println("\tBefore change: n = " + 
                            n + // prints 5
                            " hash code = " + 
                            n.hashCode()); 

        n += 10;  // behind the scenes, this is:  n = new Integer(n+10)
        
        System.out.println("\tAfter change: n = " + 
                            n + // prints 15
                            " hash code = " + 
                            n.hashCode()); 
    }

    public static void main(String[] args) {
        Integer n = 5;
        System.out.println("Main method before changeInteger(n): n = " + 
                            n + // prints 5
                            " hash code = " + 
                            n.hashCode()); 

        changeInteger(n);
        
        System.out.println("Main method after changeInteger(n): n = " + 
                            n +  // now prints 15
                            " hash code = " + 
                            n.hashCode());     
    }
}
IntegerByValueOrReference.main(null);
Main method before changeInteger(n): n = 5 hash code = 5
In changeInteger method
	Before change: n = 5 hash code = 5
	After change: n = 15 hash code = 15
Main method after changeInteger(n): n = 5 hash code = 5
import java.util.concurrent.atomic.AtomicInteger;

public class PassByReference {
    
    public static void changeAtomicInteger(AtomicInteger n) {
        System.out.println("In changeAtomicInteger method");
        System.out.println("\tBefore change: n = " + 
                            n + // prints 5
                            " hash code = " + 
                            n.hashCode()); 
        n.set(n.get() + 10);  // at this point, we are clearly working with reference data type
        System.out.println("\tAfter change: n = " + 
                            n + // prints 15
                            " hash code = " + 
                            n.hashCode()); 
}

    public static void main(String[] args) {
        AtomicInteger n = new AtomicInteger(5); // unlike conventional wrapper class, this requires new
        System.out.println("Main method before changeAtomicInteger(n): n = " + 
                            n + // prints 5
                            " hash code = " + 
                            n.hashCode()); 
        changeAtomicInteger(n);
        System.out.println("Main method after changeAtomicInteger(n): n = " + 
                            n +  // now prints 15
                            " hash code = " + 
                            n.hashCode()); 
    }
}
PassByReference.main(null);
Main method before changeAtomicInteger(n): n = 5 hash code = 639588921
In changeAtomicInteger method
	Before change: n = 5 hash code = 639588921
	After change: n = 15 hash code = 639588921
Main method after changeAtomicInteger(n): n = 15 hash code = 639588921

Hacks

Small Code Excersice

public class PrimitivesTest {
    public static void main(String[] args) {
      int[] array1;
      array1 = new int[4];
      array1[0] = 6;
      array1[1] = 4;
      array1[2] = 3;
      array1[3] = 19;
      for (int i = 0; i < array1.length; i++)
      System.out.println("Element at index " + i +  " : "+ array1[i]);
    char[] array2;
      array2 = new char[4];
      array2[0] = 'm';
      array2[1] = 'o';
      array2[2] = 'r';
      array2[3] = 't';
      for (int i = 0; i < array2.length; i++)
      System.out.println(array2[i]);
    }
    }
    PrimitivesTest.main(null);
public class WrapperTest {
    public static void main(String[] args) {
        ArrayList<Integer> values = new ArrayList<>(Arrays.asList(6, 4, 3, 19, 21, 45));
        System.out.println(values);
        ArrayList<Character> chars = new ArrayList<>(Arrays.asList('m', 'o', 'r', 't'));
        System.out.println(chars);
      }
}
WrapperTest.main(null);
[6, 4, 3, 19, 21, 45]
[m, o, r, t]

Exploring Teacher Code

Methods and Control Structures

  • Methods

    • methods are also known as functions and procedures
    • they are blocks of code that perform specific tasks
    • methods can be called from other parts of a program to perform the required task
    • they can accept input parameters, process those inputs, and return an output
    • for instance, if you have written instructions to draw a star in the method, it will do that task
  • Control Structures

    • control structures can be considered as the building blocks of computer programs and describe the flow of execution of code
    • they are commands that enable a program to make decisions and follow one path or another
    • a program is usually not limited to a linear sequence of instructions as it can repeat code or bypass sections if they are not needed
    • they control how many times a block of code is executed, which code is executed, and in what order
  • Types

    • conditional statements: program makes decisions based on a condition (if/else, if/else if)
    • loops: iterate/repeat code block (for/while/enhanced for)
    • switch statements: select from several possible options based on a variable

Diverse Array

  • the matrix code shown contains methods and control structures
    • there are multiple methods that allow different processes to happen within the code
    • there are also multiple control structures that control the execution of the matrix code (order and when things should happen)
  • Examples in Matrix Code

    • loops
    • for
    • while
    • if statements
  • Main Takeaway: Most code segment that we see and write include and are related to methods and control structures. It is very hard to have code with neither of these things included in them

DoNothingByValue

  • changing a variable but the variable doesn't actually change because it is changing the subvalue/temporary value and not the actual value
  • changing a variable only happens at a large scale
    • can not do it locally within this function/method
class Triple<T1, T2, T3> {
    T1 one;
    T2 two;
    T3 three;

    Triple(T1 one, T2 two, T3 three) {
        this.one = one;
        this.two = two;
        this.three = three;
    }

    public T1 getOne() { return this.one; }
    public void setOne(T1 one) { this.one = one; }

    public T2 getTwo() { return this.two; }
    public void setTwo(T2 two) { this.two = two; }

    public T3 getThree() { return this.three; }
    public void setThree(T3 three) { this.three = three; }
}
public class DoNothingByValue {
    public int[] arr;
    public int val;
    public String word;


    // changed to show what is happening
    public DoNothingByValue (int [] arr, int val, String word) {
        this.arr = new int[5];
        this.val = 0;
        this.word = word.substring(0, 5);

        System.out.print("constructor: ");
        for (int k = 0; k < arr.length; k++) {
            arr[k] = 0;                          // int array is initialized to 0's, not needed
            System.out.print(arr[k] + " ");

        }
        System.out.println(this.word);

    }

    // Local instance variables
    // IntelliJ shows that something is wrong, calling the values passed as parameters as local
    public static void changeIt(int [] arr, int val, String word) {
        arr = new int[5];
        val = 0;
        word = word.substring(0, 5);

        System.out.print("changeIt: "); // added
        for (int k = 0; k < arr.length; k++) {
            arr[k] = 0;
            System.out.print(arr[k] + " "); // added
        }
        System.out.println(word);   // added

    }

    // Variable name are Reference
    // names of variables make no difference, they are just references to addresses
    public static void changeIt2(int [] nums, int value, String name) {
        nums = new int[5];           // new creates new memory address
        value = 0;                   // primitives are pass by value
        name = name.substring(0, 5); // all wrapper classes have automatic "new", same as word = new String(word.substring(0, 5));

        // this loop changes nums locally
        System.out.print("changeIt2: ");
        for (int k = 0; k < nums.length; k++) {
            nums[k] = 0;
            System.out.print(nums[k] + " ");
        }
        System.out.println(name);

    }


    // If you want to change values, think about Return values, but you are limited to one in Java
    // changed to show what is happening
    public static String changeIt3(int [] arr, String word) {
        word = new String(word.substring(0, 5));    // wrapper class does a "new" on any assignment

        System.out.print("changeIt3: ");
        for (int k = 0; k < arr.length; k++) {
            arr[k] = 0;                          // int array is initialized to 0's, not needed
            System.out.print(arr[k] + " ");

        }
        System.out.println(word);

        return word;
    }

    // Variable inside of Object Triple are references
    public static Triple<int[], Integer, String> changeIt4(Triple<int[], Integer, String> T) {
        T.setOne(new int[5]);
        T.setTwo(0);                   // primitives are pass by value
        T.setThree(T.getThree().substring(0, 5)); // all wrapper classes have automatic "new", same as word = new String(word.substring(0, 5));

        // this loop changes nums locally
        System.out.print("changeIt4: ");
        for (int i : T.getOne()) {
            System.out.print(i + " ");
        }
        System.out.println(T.getThree());

        return T;
    }


    // Original method changed to main in order to be a Tester
    public static void main(String[] args) {
        // Does nothing
        int [] nums = {1, 2, 3, 4, 5};
        int value = 6;
        String name = "blackboard";
        System.out.println("Do Nothings");
        // dumb and useless
        changeIt(nums, value, name);
        // dumber and useless
        changeIt2(nums, value, name);
        System.out.print("main: ");
        for (int k = 0; k < nums.length; k++) {
            System.out.print (nums[k] + " ");
        }
        System.out.print(value + " ");
        System.out.print(name);

        System.out.println();
        System.out.println();


        // int[] by reference, return value  -- not complete
        System.out.println("Limited return");
        int[] nums2 = {1, 2, 3, 4, 5};
        value = 6;
        name = "limited";
        name = changeIt3(nums2, name);
        System.out.print("main2: ");
        for (int num : nums2) {
            System.out.print(num + " ");
        }
        System.out.print(value + " ");
        System.out.print(name);

        System.out.println();
        System.out.println();


        // Class/Object
        System.out.println("Do Something with Class");
        int[] nums3 = {1, 2, 3, 4, 5};
        value = 6;
        name = "classy";
        DoNothingByValue doSomething = new DoNothingByValue(nums3, value, name);

        System.out.print("main3: ");
        for (int num : doSomething.arr) {      // should be teaching enhanced for loop on arrays
            System.out.print(num + " ");
        }
        System.out.print(doSomething.val + " ");
        System.out.print(doSomething.word);

        System.out.println();
        System.out.println();

        // Generics
        System.out.println("Do Something with Generics");
        int[] nums4 = {1, 2, 3, 4, 5};
        value = 6;
        name = "generics";
        Triple<int[],Integer,String> tri = changeIt4(new Triple<>(nums4, value, name));

        System.out.print("main: ");
        for (int num : tri.getOne())
            System.out.print (num + " ");

        System.out.print(tri.getTwo() + " ");
        System.out.print(tri.getThree());
    }

}

// This class can be used to pass variables by reference

IntBy Reference

  • by using the IntByReference for objects a and b, integers are passed by reference, which allows for modifications of the values within the methods
    • these changes can then be reflected outside of the method as well
  • swapping the integers as type int, which is a primitive, wouldn't allow for modifications in a method to be reflected outside the method which is important to have
import java.util.Scanner;

public class IntByReference {
    private int value;

    // all-arg constructor
    public IntByReference(Integer value) {
        this.value = value;
    }

    public String toString() {
        return (String.format("%d", this.value));
    }

    public void setValue(Integer value){
        this.value = value;
    }

    public void swapToLowHighOrder(IntByReference i) {
        if (this.value > i.value) {
            int tmp = this.value;
            this.value = i.value;
            i.value = tmp;
        }
    }

    public static void swapper(int n0, int n1) {
        IntByReference a = new IntByReference(n0);
        IntByReference b = new IntByReference(n1);
        System.out.println("Before: " + a + " " + b);
        a.swapToLowHighOrder(b);  
        System.out.println("After: " + a + " " + b);
        System.out.println();
    }

    public static void main(String[] ags) {
        IntByReference.swapper(20, 12);
        IntByReference.swapper(12, 20);
        IntByReference.swapper(12, -2);
    }

}
IntByReference.main(null);
Before: 20 12
After: 12 20

Before: 12 20
After: 12 20

Before: 12 -2
After: -2 12

// The MenuRow Class has title and action for individual line item in menu
class MenuRow {
    String title;       // menu item title
    Runnable action;    // menu item action, using Runnable

    /**
     *  Constructor for MenuRow,
     *
     * @param  title,  is the description of the menu item
     * @param  action, is the run-able action for the menu item
     */
    public MenuRow(String title, Runnable action) {
        this.title = title;
        this.action = action;
    }

    /**
     *  Getters
     */
    public String getTitle() {
        return this.title;
    }
    public Runnable getAction() {
        return this.action;
    }

    /**
     *  Runs the action using Runnable (.run)
     */
    public void run() {
        action.run();
    }
}

// The Main Class illustrates initializing and using Menu with Runnable action
class Driver {
    /**
     *  Menu Control Example
     */
    public static void main(String[] args) {
        // Row initialize
        MenuRow[] rows = new MenuRow[]{
            // lambda style, () -> to point to Class.Method
            new MenuRow("Exit", () -> main(null)),
            new MenuRow("Do Nothing", () -> DoNothingByValue.main(null)),
            new MenuRow("Swap if Hi-Low", () -> IntByReference.main(null)),
            // new MenuRow("Matrix Reverse", () -> Matrix.main(null)),
            // new MenuRow("Diverse Array", () -> Matrix.main(null)),
            // new MenuRow("Random Squirrels", () -> Number.main(null))
        };

        // Menu construction
        Menu menu = new Menu(rows);

        // Run menu forever, exit condition contained in loop
        while (true) {
            System.out.println("Hacks Menu:");
            // print rows
            menu.print();

            // Scan for input
            try {
                Scanner scan = new Scanner(System.in);
                int selection = scan.nextInt();

                // menu action
                try {
                    MenuRow row = menu.get(selection);
                    // stop menu
                    if (row.getTitle().equals("Exit")) {
                        if (scan != null) 
                            scan.close();  // scanner resource requires release
                        return;
                    }
                    // run option
                    row.run();
                } catch (Exception e) {
                    System.out.printf("Invalid selection %d\n", selection);
                }

            } catch (Exception e) {
                System.out.println("Not a number");
            }
        }
    }
}
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * Menu: custom implementation
 * @author     John Mortensen
 *
 * Uses String to contain Title for an Option
 * Uses Runnable to store Class-Method to be run when Title is selected
 */

// The Menu Class has a HashMap of Menu Rows
public class Menu {
    // Format
    // Key {0, 1, 2, ...} created based on order of input menu
    // Value {MenuRow0, MenuRow1, MenuRow2,...} each corresponds to key
    // MenuRow  {<Exit,Noop>, Option1, Option2, ...}
    Map<Integer, MenuRow> menu = new HashMap<>();

    /**
     *  Constructor for Menu,
     *
     * @param  rows,  is the row data for menu.
     */
    public Menu(MenuRow[] rows) {
        int i = 0;
        for (MenuRow row : rows) {
            // Build HashMap for lookup convenience
            menu.put(i++, new MenuRow(row.getTitle(), row.getAction()));
        }
    }

    /**
     *  Get Row from Menu,
     *
     * @param  i,  HashMap key (k)
     *
     * @return  MenuRow, the selected menu
     */
    public MenuRow get(int i) {
        return menu.get(i);
    }

    /**
     *  Iterate through and print rows in HashMap
     */
    public void print() {
        for (Map.Entry<Integer, MenuRow> pair : menu.entrySet()) {
            System.out.println(pair.getKey() + " ==> " + pair.getValue().getTitle());
        }
    }

    /**
     *  To test run Driver
     */
    public static void main(String[] args) {
        Driver.main(args);
    }

}
Menu.main(null);
Hacks Menu:
0 ==> Exit
1 ==> Do Nothing
2 ==> Swap if Hi-Low
Do Nothings
changeIt: 0 0 0 0 0 black
changeIt2: 0 0 0 0 0 black
main: 1 2 3 4 5 6 blackboard

Limited return
changeIt3: 0 0 0 0 0 limit
main2: 0 0 0 0 0 6 limit

Do Something with Class
constructor: 0 0 0 0 0 class
main3: 0 0 0 0 0 0 class

Do Something with Generics
changeIt4: 0 0 0 0 0 gener
main: 0 0 0 0 0 0 generHacks Menu:
0 ==> Exit
1 ==> Do Nothing
2 ==> Swap if Hi-Low

Exploring AP Classroom FRQ

2021 Free Response Question

The question involves the WordMatch class, which stores a secret string and provides methods that compare other strings to that secret string. You will write two methods in the WordMatch class.

  1. a. Write the WordMatch method scoreGuess. To determine the score to be returned, scoreGuess finds the number of times that guess occurs as a substring of secret and then multiplies that number by the square of the length of guess. Occurrences of guess may overlap within secret. Assume that the length of guess is less than or equal to the length of secret and that guess is not an empty string.
public int scoreGuess (String guess){
    int count = 0
    // iterates through the length of the array secret and guess, and checks each value of the array to determine if guess is within secret
    for (int = 0; i <= secret.length() - guess.length(); i++){
        if (secret.substring(i, i + guess.length()).equals(guess)){
            count ++
        }
    }
}
  1. b. Write the WordMatch method findBetter Guess, which returns the better guess of its two String parameters, guess1 and guess2. If the scoreGuess method returns different values of guess1 and guess2, then the guess with the higher score is returned. If the scoreGuess method returns the same value of guess1 and guess2, then the alphabetically greater guess is returned.
public String findBetterGuess(String guess1, String guess2){
    if (scoreGuess (guess1) > scoreGuess (guess2)){
        return guess1;
    }
    if (scoreGuess (guess2) > scoreGuess (guess1)){
        return guess2
    }
    if (guess1.compareTo(guess2 > 0)){
        return guess1
    }
    return guess2
}

Advanced Running FRQ

public class WordMatch {

    private String secret;   // initializes and declares the variable secret 

    public WordMatch (String secret) { // constructs WordMatch object with an initialization of secret string
        this.secret = secret;
    }

    public void setSecret(String secret) {  // sets the secret value
        this.secret = secret;
    }

    public int scoreGuess(String guess) { 

    // shows the use of control structures (in this example, it is a for loop)

        int count = 0; 

        for (int n = 0; n < secret.length(); n++) {  // continues to loop over the entirety of secret String
            if (secret.substring(n).indexOf(guess) == 0) { // start at 0 index 
                count++;    // increment the count each time it goes through the for loop
            }
        }

        return count * guess.length() * guess.length(); // returns the score (product of how many times the guess appeared in secret and the square of the length of guess)
    }

    public String findBetterGuess (String guess1, String guess2) { 
        
        // this is using the method of scoreGuess above and is inputs guess1 and guess2 into scoreGuess to check which one is closer to the guess

        if (scoreGuess(guess1) > scoreGuess(guess2)) {   // checking if the score of guess 1 is greater than the score of guess2
            return guess1;   // if score1 is greater, then it is the better guess
        }
        if (scoreGuess(guess1) < scoreGuess(guess2)) {  // checking if the score of guess 2 is greater than the score of guess1
            return guess2; // if score2 is greater, then it is the better guess
        }
        if (guess1.compareTo(guess1) > 0) { // compare guess1 and guess2 and the alphabetically greater one is returned (in the case the scores are equal)
            return guess1;
        }
        return guess2;
    }

    public static void main(String args[]) {  

        Scanner sc = new Scanner(System.in);

        // System.out.println("Enter a guess: ");
        String guess = sc.nextLine();

        String secret = "birthday";   // the secret word
        WordMatch wordMatch = new WordMatch(secret);

        int score = wordMatch.scoreGuess(guess);
        System.out.println("Score For " + guess + " Is: " + score);

        // System.out.println("Enter another guess: " +);
        String guess1 = sc.nextLine();


        int score1 = wordMatch.scoreGuess(guess1);
        System.out.println("Score For " + guess1 + " Is: " + score1);


        String compare = wordMatch.findBetterGuess(guess, guess1);
        System.out.println("The Better Guess Between Options " + guess + " and " + guess1 + " Is: " + compare);

        sc.close();
    }
}

WordMatch.main(null)
Score For birth Is: 25
Score For day Is: 9
The Better Guess Between Options birth and day Is: birth