Sunday, July 31, 2011

Program to Draw a Random Card

Problem: Write a program that displays the name of a card randomly chosen from a complete deck of 52 cards. You program should display the complete name of the card. (Roberts ch 6, problem 1).

What it looks like (2 sample runs):

How the code looks:
/*
/*File: DrawCard.java
 * This program simulates drawing a card from a standard deck. It uses an instance of acm.util's 
 * RandomGenerator class to create two new random integers: one helping to supply the value (2-10, Ace, Jack, Queen, 
 * King), and the other integer helps determine the suit (Spades, Clubs, Hearts, Diamonds). Each integer value maps
 * to a card value or suit.
 *  * */
import acm.program.*;
import acm.util.*;

public class DrawCard extends ConsoleProgram{

    public void run() {
   
    int d1 = rgen.nextInt(1,4);
    int d2 = rgen.nextInt(1,12);
   
        String suit = null; //Declare a variable of null value. 
        //Then use switch statement to set a value
        switch (d1) {
            case 1: suit = "Spades"; break;
            case 2: suit = "Clubs"; break;
            case 3: suit = "Hearts"; break;
            case 4: suit = "Diamonds"; break;  
        }
   
        String value = null;
        switch (d2) { 
            case 1: value = "Ace"; break;
            case 11: value = "Jack"; break;
            case 12: value = "Queen"; break;
            case 13: value = "King"; break;
            default: value = Integer.toString(d2); break; // Returns a numeric value in string form
                // if a non-face card gets drawn
        }
        
    println("The " + value + " of " + suit);
   
    }
    //Instance variable for our random generator macheeeeen
    private RandomGenerator rgen = RandomGenerator.getInstance();
}

What made this interesting:

Two interesting concepts you exercise here:

1) Compartmentalizing your program. Instead of just storing 52 potential card values and randomly picking one of them, you can build something neater. There are 4 suits of equal distribution and 13 numeric values, so we can generate two random numbers for the face and numeric numbers and map them to card values. This is better than simply storing 52 potential card values because...

2) The concept of using an instance of a class to do stuff. In this case is a class of objects available to me called RandomGenerator. An instance of the RandomGenerator class is not one random number itself. It is an object that you can create in your program and then call upon to return random numbers. (It will recognize the method getInt() method). So the individual random numbers are a layer of abstraction away from the class that we get from the ACM library.

Why is this important?

This was actually familiar to me based on my work at Twilio. Twiio's REST API lets you make calls, send SMS messages, and pull information about your Twilio account. You can make a request to the API by a raw HTTP request to Twiio. Or, you can be clever and use a wrapper library that creates a "REST client". This is actually a class of objects that know how to make HTTP requests to Twilio, so instead of piecing together a big URL every time you need to communicate to Twilio, you can send commands to your instance of the REST client and communicate via methods instead of a raw URL.

Examples:

A1) Making a phone call directly via a direct HTTP POST to Twilio's API:

POST https://api.twilio.com/2010-04-01/Accounts/account123/Calls/
Auth Headers: username account123, password token456


POST parameters:
* To: 503-111-2222
* From: 503-222-3333
* Url: http://mycoolapp.renee.com


A2) Sending an SMS:


POST https://api.twilio.com/2010-04-01/Accounts/account123/SMS/Messages
Auth Headers: username account123, password token456


POST parameters:
* To: 503-111-2222
* From: 503-222-3333
* Body: Hello World

VERSUS

B) Making a phone call, then sending an SMS message using an instance of the TwilioClient class (from Sean Sullivan's Java wrapper library):

/*import twilio.client.*;
TwilioClient c = new TwilioClient("account123", "token456");

c.call("503-111-2222", "503-222-3333");
c.sendSMSMessage("503-111-2222", "503-222-3333", "Hello world");

See, isn't that better? The advantage is don't have to put together the URL every time or worry about validating each request. You just create your object, which has the account SID and auth token baked in and can recognize the methods "call" and "sendSMSMessage." Instead of needing to be familiar with the Twilio API (which is actually very simple), you can just be familiar with methods in your language of choice that let you make calls or send SMS.

Sunday, July 10, 2011

Program to Print Perfect Numbers

Problem: Greek mathematicians took special interest in numbers that are equal to the sum of their proper divisors (a proper divisor of n is any divisor less than n itself). They called such numbers *perfect numbers*. For example, 6 is a perfect number because it is the sum of 1, 2 and 3, which are numbers less than 6 that divide equally into 6. Similarly, 28 is a perfect number because it is the sum of 1, 2, 4, 7, and 14.


Write a predicate method isPerfect(n) that returns *true* if the integer n is perfect, and *false* otherwise. Test your implementation by writing a main program that uses the isPerfect method to check for perfect numbers in the range 1 to 9999 by testing each number in turn. Whenever it identifies a perfect number, your program should display that number on your screen. Your program should find two other perfect numbers in that range as well. (Roberts ch 5, problem 12).


What it looks like:





/*
* File: printPerfects.java
* Name: Chu
* Section Leader: 
* This program prints the numbers between 1 and 9999 that are perfect numbers. Perfect numbers are those
* where the divisors (integers that divide evenly into it) all sum up to that number. It uses the private
* predicate method isPerfect.
* 
*/

 
package ch6_practice;
import acm.program.*;

public class printPerfects extends ConsoleProgram {
    public void run() {    
        for (int i = 1; i < 9999; i++) {
            if (isPerfect(i)) {
                println(i);
            }
        }
    }
    private boolean isPerfect (int n) {
        int sum = 0;
        for (int i = 1; i < n; i++) {
            if (n % i == 0) {
            sum += i; }
            }
            if (sum == n) {
                return true;
            }
        else return false;
        
    }
}

This was a simple little program that simply re-enforced the practice of breaking certain operations of a program into their own methods. The method "isPerfect" creates a new variable "sum", initialized at a value of zero. For any number that you're testing to see if it is perfect, you find all the divisors via brute force. Whenever you find a divisor, you add it to "sum." If, after finding all the divisors, the value of "sum" equals the number you're testing, then you know that the number is perfect.

Sunday, June 19, 2011

Program to Find Whether a Number is Prime

Problem: "An integer greater than 1 is said to be *prime* if it has no divisors other than itself and one. The number 17, for example, is prime because it has no factors other than 1 and 17. The number 91, however, is not prime because it is divisible by 7 and 13. Write a predicate methode isPrime(n) that returns *true* if the integer n is prime, and *false* otherwise. As an initial strategy implement isPrime using a brute-force algorithm that simply tests every possible divisor. Once you have that version working, try to come up with improvements to your algorithm that increase its efficiency without sacrificing its correctness." (Roberts ch 5, problem 11).

Code:

/*
* File: isPrimeSmarty.java
* Name: Chu
* Section Leader: 
* Description: This program lets the user enter in as many positive integers as she likes and calls the 
* private boolean "isPrimeSmarty" to evaluate whether the integer is prime or not. We also had the 
* isPrimeBrute method evaluate it, but optimized the method so that instead of testing all divisors
* you only have to iterate up to the square root of the tested number.
* 
*/

 
package ch6_practice;
import acm.program.*;

public class primeTesterSmarty extends ConsoleProgram {
   
    public void run() {
        println("This program evaluates whether positive integer is prime or not.");
        
        while (true) {        
            int number = readInt("Enter any positive integer, and enter 0 to stop:");
                if (number == 0) {
                    break;
                }
                if (number < 0) {
                    println ("Positive integer please! Why are you messin with me, thug? No more primes for you.");
                    break;
                }
                if (isPrimeSmarty(number)) {
                    println ("Yes," + number + " is a prime number.");
                }
            else println ("Nope, not a prime number.");
            }
        println("Thanks for playing.");
    }

    private boolean isPrimeSmarty(int number) {
        int k = (int)Math.sqrt(number); //Find the square root of the number you're testing for, 
        //return it rounded down to the integer
        for (int i = 2; i < k; i++){
            if (number % i == 0) {
                return false;
            }
        }
        return true;
    }
    
    // The old brute force way, commented out
    //private boolean isPrimeBrute (int number){
    //    for (int i = 2; i < number; i++){
    //        if (number % i == 0) {
    //            return false;
    //        }
    //    }
    //    return true;
    //}
}


What it looks like:



It's fun to solve problems and methodically optimize them as you think about them more, or as you learn more revisit old problems with new knowledge. This problem had a brute method solution and two potential optimizations, one that I implemented and one that I think I need to hold off on implementing until I learn more.
Brute Method: 
For any given number, iterate from 2 to that number and divide your tested number by the iterator. Is there a remainder? If you ever find a divisor where the remainder ==0, then return false, because it was divisible by a number *other than* itself and 1. If you don’t find a divisor other than itself an one, then return true.



Optimization1:
Instead of iterating from 2 to the tested number, you only need to go from 1 to the square root (rounded down to the integer) that number, so it cuts down the number of operations you have to do.

Why are we able to only test up to the square root?

Think of the tested number 21 for example.
Its divisors are: [1, 3, 7, 21].
The square root is 4.58. Under the brute force way we'd test all numbers between and including 2 and 20. Now we just test the numbers between and including 2 and 4. When we test dividing 21 by 3, the result is 7, so if we were to test out 7, we'd get the result of 3. Divisors come in pairs, and one is always less than and the other is always greater than the square root, and the square root’s value is in the middle of the list of divisors. If there was a number greater than the square root that would have shown us that the tested number is not a prime, we would have already caught it by dividing its smaller side of the pair.



Optimization2:

Once you’ve tested dividing a number by one of the iterators, you don’t need to test dividing it by a previously-tested-iterator to the n. So if you already tested 3, then you don’t need to test for 9, because if it’s divisible by 9 (aka 3 to the ^2) it’s definitely divisible by 3.

I’m not sure how to implement this second optimization. I suspect you’d have to mess with the line “for (int i = 2; i < k; i++)”, and instead of “i++” (iterating up by increments of 1) you’d want to iterate up but exclude iterators that have a previous iterator as one of its factors.

I think the way you’d do this is by creating an array that is made up of prime numbers (so that no number has any of the others as a factor) and instead of doing “i++”, you’d iterate through each value in the array. However, you don’t really know how big the array has to be, since it depends on how high the number you need to test is, so this array will probably be built on the fly as you run the program (recursive function?) I think that the syntax to implement this optimization is beyond what I know so far with Java, but I’ll come back to it later...

Saturday, June 4, 2011

Fib Sequence with Method

Problem: "The Fibonacci sequence, in which each new term is the sum of the preceding two, was introduced in Ch4, exercise 9. Rewrite the program requested in that exercise, changing the implementation so that your program calls a method "fibonacci(n) to calculate the nth Fibonacci number. In terms of the number of mathematical calculations required, is your new implementation more or less efficient than the one you used in Ch 4?" (Roberts Ch 5, problem 2).

What it looks like when you run:




Here is the code:

/*

/*
* File: FibSequenceMethods.java
* Name: Renee
* Section Leader: 
* -----------------
* The Fibonacci sequence is defined as a sequence of numbers where each integer is the sum of *the two previous integers in the sequence.
* 
* This program prompts the user for an integer N and calls the private, recursive method fib(n) 
* to print out the first "n" digits of the Fibonacci Sequence. 
*/

package ch6_practice;
import acm.program.*;

public class FibSequenceMethods extends ConsoleProgram {
    public void run() {
    println("This program prints the first 'n' digits of the Fibbonacci Sequence.");
         int n = readInt("How many digits do you want to print?");         
         for (int i = 0; i < n; i++) {
          println("Fib of " + i + " is " + fib(i) + ".");
         }
         

 }
    
    private int fib(int n) {
     if (n < 2) {
         return n;
     }
         return fib(n - 1) + fib(n - 2);
     }
     
    }


Here is the old version (not using a private method):
/*
public class FibSequence extends ConsoleProgram {
    public void run() {
        //Getting the first two in the sequence started...
        int n0 = 0;
        int n1 = 1;
        println(n0);
        println(n1);

        //Now kicking off the fun part by changing moving down the variable values; n1 becomes
//n0, n2 becomes n1, and a new n2 value is created.

        for (int i = 2; i < END; i++) {
            int n2 = n1 + n0;
            println(n2);
            n0=n1;
            n1=n2;
        }
    }

    //Private constant; "End" is the the nth number in the Fib sequence displayed.
    private static final double END = 15;
}

In the new version of the program, because the part that actually calculates each entry in the sequence is a separate method call, you can use a recursive method. In other words, when you're trying to find fib(6), you have at your disposal the ability to calculate fib(5) and fib(4) whereas you didn't before. The new version of the program is easier to write because the code looks like the way we coloquially define the fib sequence. However, it is not actually more efficient (there aren't fewer operations) than the old version because to arrive at any integer in the sequence, you have to calculate *all* the previous integers before it. I drew out the operations to calculate fib(6) using both programs, below. New Version:
Old Version:

Sunday, January 23, 2011

Predicate Method for Yes/No: The David Version

After I posted my predicate method for categorizing yes/no questions as true or false, David challenged me to rewrite the solution with a single call to readLine(prompt) and a single test for reply.equals("yes").

Here's my shot at it (tested and it works, oorah):

/*

    private boolean askYesOrNoQ(String prompt){   
        while (true) {
            String reply = readLine(prompt);
         
            if (reply.equals("yes")) {
                return true;
            }
            if (reply.equals("no")) {
                return false;
            }
            else
            println("Please enter a yes or no answer.");
        }
        
    }


The old approach said, "As long as the user enters a non-yes/no answer, keep prompting him to enter yes or no; once he does, return true or false, respectively." This version says, "Keep looping. If he enters yes, break from the loop and return true. If he enters no, break from the loop and return false. Else, keep re-prompting and looping."

I don't know if this was the strategy David was thinking of, but I'm glad I figured out how to solve a problem two ways. Comparing this method with the old version, I'm trying to figure out which one is better and why.

For reference, here is the old version:

/*

private boolean askYesOrNoQ(String prompt){ 
        String reply = readLine(prompt);
      
        while ((!reply.equals("yes"))&&(!reply.equals("no"))) {
            println("Please enter a yes or no answer.");
            reply = readLine(prompt);
        }
        return (reply.equals("yes"));
    }
}



Merits of the new version:

1) Clearer to read; you don't really need to know the syntax of Java or how booleans work to know what's going on.

2) Doesn't repeat the line "reply = readLine(prompt)". In general it's a good practice to avoid repeating code so you don't introduce bugs if you decide to change the name of the variable "reply", etc.

Merits of the old version:

1) Fewer lines of code.

2) I like the clean and elegant "return" statement. Instead of breaking down the true or false possibilities into two "if" statements, we say return(boolean); it lets the program figure out true vs false for itself. I guess you could write, "If reply equals yes or no, return(boolean)", though that would violate the challenge of only inspecting reply.equals("yes") only once.

What do you guys think? Also are there other ways of solving this problem?

Predicate Method to Categorize a Yes or No Question (with Monkey Brains program)

Problem: "Write a predicate method "askYesNoQuestion(prompt)" that prints a string "prompt" as a question for the the user and then waits for a response. If the user enters a string "yes" the askYesNoQuestion method should return true. If the user enters a string "no" the askYesNoQuestion method should return false. If the user enters anything else, the method should remind the user that it is seeking a yes-or-no answer and then repeat the question." (Roberts ch 5, problem 7).

This problem was a good illustration of how boolean methods work as part of a larger program. Let's say you want a program to say, "If True, do X, if False, do y," but the mechanics of evaluating a situation to "True" or "False" take multiple steps. If that's the case, then the "if" part would best be handled by a method call.

What it looks like:


/*

* File: YesNoPredicate.java
* Name: Renee
* Section Leader: 
* -----------------
* 
*/

import acm.program.*;

public class YesNoPredicate extends ConsoleProgram {
    public void run() {
        if (askYesOrNoQ ("Do you have monkey brains?")) {
            println ("Have a bananna");
        }
        else println ("Get outta here");
        }
    
    /*This boolean pushes the user to enter a yes or no answer to an arbitrary string (hopefully
    a question) called "prompt." If the user enters anything but yes or no, the method
    will keep looping until the user enters yes or no. If the user enters "yes", the boolean
will return "true." If the user enters "no", the boolean will return "false."*/

    private boolean askYesOrNoQ(String prompt){ 
        String reply = readLine(prompt);
      
        while ((!reply.equals("yes"))&&(!reply.equals("no"))) {
            println("Please enter a yes or no answer.");
            reply = readLine(prompt);
        }
        return (reply.equals("yes"));
    }
}




What made it tough: At first I thought this problem was super-simple, but it stumped me for 30 min before everything clicked. I knew that I wanted the boolean to say, "If the user enters 'yes,' return 'true.' If he enters anything else, return 'false.' Moreover, if the false answer is not 'no', keep re-prompting for a yes-or-no answer." But I wasn't sure how to build that re-prompt into the predicate method and at first built the re-prompt into the run() method, which isn't the proper place because the predicate part is supposed to take care of that.

I was getting close when it looked like this:

/*
    private boolean askYesOrNoQ(String prompt){ 
        String reply = readLine(prompt);
        return (reply.equals("yes"));
        if (!reply.equals("no")) {
            println("Please enter a yes or no answer.");        
        }
but I kept getting an error "Unreachable code." I had the "return true if yes" part come before the "push the user for a yes-or-no answer" part, though it appears you must have the "return" method be the last part of your private method? That makes sense, because if the user entered "gibberish" and we returned "false", the run() method would act upon the "false" without ever getting a yes-or-no answer from the predicate method.

This was also another good illustration of different ways to pass an object to a method. It's interesting that the argument you pass to the method which inspects the user's input isn't the answer itself, but the prompt. You could easily have designed this program so that you print out the prompt as part of the run() method and pass the user input to the private boolean to evaluate it to true or false; I'm trying to think what the merits of each approach are...

Saturday, January 22, 2011

Program to Display the Number of Digits in an integer

Problem: Write a method countDigits(n) that returns the number of digits in the integer 'n', which you may assume is positive. Design a main program to test your method. For hints about how to write this program, you might want to look back at the DigitSum program in Fig 4.6.

What I did: This program interacts with the user, taking in the digit input and sending that input to the countDigits method. I also made the program let the user keep entering in digits to his or her hearts' content, using the value "0" as the sentinel.





/*
/*
* File: DigitCountWithMethod.java
* Name: Chu
* Section Leader: 
* Description: This exercise prints the number of digits in an integer that
* the user enters in. The main/run method uses the digitCount method to 
* accomplish this.
* 
* The countDigits method is pretty clever and reuses the technique from the DigitSum program
* in the textbook from section 4.6. In order to count the number of digits in an 
* integer, you keep dividing the integer by 10 and adding 1 to a variable "dcount" that gets initiated
* at 0. You keep doing this iteration until the integer is zero.
*/


package ch6_practice;
import acm.program.*;

public class DigitCountWithMethod extends ConsoleProgram {
 
    public void run() {
        println("This program counts the digits in an integer.");
        //Hm, get "illegal numeric format" if it's a long integer...Java limitation? Eew.
  
        while (true) {
            int n = readInt ("Enter any integer, entering '0' if you want to exit the program:");
            if (n == 0) {
                println("Goodbye");
                break; //Oh, once you break, you can't continue in the loop; otherwise it's "unreachable code"       
            }
            else {
            println("There are " + countDigits(n) + " integers in " + n + ".");
            }
        }
    }
 
    private int countDigits(int n){
        int dcount = 0;
        while (n > 0) {
            dcount += 1;
            n /= 10;
        }
        return dcount;
    }
 
 
 
}


What made it tough: Nothing much; a lot of the countDigits strategy came from another program, DigitSum. I do see 2 curious things however. First; if the user enters in more than 10 digits, we get an error message "Illegal numeric format." Why??

Also, I wanted to let my program loop so that the user could enter in multiple digits; the only way I could think of how to do this was with establishing a sentinel with the value "0." However, this is not elegant at all; for one thing, what if I want to know how many digits zero has? However, I can't make the sentinel a string, since my prompt will only accept integers. Ideas on a better way for the user to terminate the program?