Showing posts with label AP Computer Science. Show all posts
Showing posts with label AP Computer Science. Show all posts

Friday, July 24, 2015

Studying at College

Studying At College

Studying At College

Introduction

This blog has spent a significant amount of time providing insight into AP Computer Science. The next step ultimately will be going to College. AP courses offer a taste of college material but that material is spread over the course of a school year. In college that same material is covered in about 15 weeks. That really is the difference and it's a huge difference. There is very little room for an error. There will be fewer tests each covering more material. Since many who come to this site are just starting out in the field of Computer Science I thought I would collect some web sites here that can provide you some help on studying.

My own experience, way back when, was a hodge podge of mistakes and mishaps. I only wish the world wide web was around when I was going to college. If nothing else than to find out what help was available at my school for subjects I was having trouble with. Instead I would ask around or ask someone who was doing well in the course but in the end they had limited time to help. My college years were spent muddling through as best I could, studying long hours without seeing much success on these tough courses. In my day jobs were plentiful and GPA was important but it wasn't everything. Once you graduated and gained real life experience you could shift jobs, change direction without much difficulty.

Those days are gone. Jobs are a little more difficult to come by. US corporations keep lobbying for increases in the H1B visa program so they can bring in foreign STEM workers cheap. Why should I hire a B student from any State University when I can grab an A student from India Institute of Technology? In a better day US companies were restricted from doing things like that. Now, not so much. That doesn't mean you can't find a job it just means that now more than ever your GPA right out of college is your ticket to getting your foot in the door of corporate America.

Do what you love and never work a day in your life.

There is truth to this old saying. You have to be realistic of course. No one is going to pay you to eat and drink beer all day. But you can get paid for a variety of fun jobs. If you like programming computers and designing software there are jobs available that pay pretty well. If you like training dogs there are ways to make money doing this. So your first step when you go to college is to figure out what Major you are going to love.

I didn't do that. I decided that Computer Science was too easy and that I needed to understand how the electronics worked behind the computer. So I suffered through an Electrical Engineering degree, when I could have breezed through a Computer Science degree. In the end it worked out OK but it took me 4 years after college to finally land a software job. In the end the hardware and software experience would help me start up a company so I can't complain. But I could have taken Computer Science as my major and taken the fun courses in Electrical Engineering as part of my electives and looked a heck of a lot better on paper.

I bore you with this only because if you are a college student who is struggling with their course load, I know the feeling, I've been there. I've made every mistake in the book. I've told myself every excuse there was on how it wasn't my fault. The reality was two fold: First I was in the wrong major and second I had no idea how much time I was supposed to be spending on studying. From my high school experience I needed a couple of hours of studying the night before a test. In college that is not going to cut it unless your a super genius and if you are a super genius thank you for reading my blog! But if you're a mere mortal like me it would be nice to know the minimum amount of time you should be working.

Getting into "The Flow"

You may have experienced what people call "The Flow" when working on a computer project. It's that point in time where the work ahead is clear in your mind and you are just spitting out lines of a program quickly and easily. When you come out you realize you have just been super productive have gotten 80 to 90% of the work done and you're wondering: why couldn't that have happened sooner? I would have been completely finished by now. You may have experienced "The Flow" when reading a good book. You get to a particular section where the story sort of tells itself and you don't really notice the time passing. You become "absorbed" in the book.

The key is to get into "The Flow" for whatever you happen to be studying. This can be quite difficult for a required course you don't like very much and it can be simple for a course you love. The point is you need to train yourself to get into "The Flow" quickly whenever you need to whether you like the material or not. That is easier said than done and I don't know of a method to guarantee this happens quickly. My method is to observe yourself. How long do you have to sit there and what things do you do to get yourself into "The Flow"?

Start creating a routine (this is where you start to become OCD and superstitious) that you do before you begin to study. If you have to pace back and forth 5 times after you set up your study material on the desk, so be it. If you need a sip of coffee, red bull or diet coke make sure you have it handy. If you need to wash your hands 5 times OK whatever, it doesn't matter. What does matter is that you develop a routine that you do every time you start to study. The idea is to condition the mind over time that this routine will lead to "The Flow" and sooner or later your mind will start to cooperate.

For me, I found that I basically needed 5 hours to study 3 (meaning over the 5 hours I sat down to study only 3 hours of "good" study happened). Sometimes 5 hours to get 2 hours of good study. This becomes the crux of the matter, I alluded to the minimum amount of time you needed to study for each course in the previous section. We will get to that number shortly but that number represents good study time. By observing yourself and objectively assessing your use of study time, you should be able to set up a schedule for yourself and map out your entire week. Guess what. If you need 5 hours to study 3 there isn't going to be much time left for extracirricular activities.

The Formula credit hours to study hours

The University of Michigan at Flint study website (https://www.umflint.edu/advising/surviving_college) says you need:

  • 2 hours of study for every 1 credit hour of class
  • So a 12 credit hour semester = 24 hours of extra study per week.

Based on that, between classes and studying you will chew up 36 hours per week. So even a light semester schedule is equivalent to a full time job in terms of hours spent. If you're like me and you need 4 - 5 hours to get 2 hours of good study you are looking at about 60 hours per week. That's the equivalent of full time job and a part time job at night. If you want weekends off you will need to start work at 8am and finish by 5pm Monday - Friday (includes 1 hour lunch) if your an efficient studier. To get to 60 and have weekends off 8am - 10pm with an hour for lunch and an hour for dinner included. If you want to join a club and need your evenings free, you need to study more efficiently (good luck with that because if your still reading then your doomed like me ot be an inefficient studier, not because you're reading slowly but because your still looking for advice) or you will need to use your weekend time to make up the difference.

This may seem absurd to you but I assure you that in the real world of the salaried employee there are many times where you are called on to work 60 - 80 hours per week. That's the point of college, right? To prepare you for what you might have to do in the real world? I hope you take my advice because I assure you I have tried everything to avoid having to aquiesce to this reality and in the end I found out that there is no way around hard work. Trust me on this I spent a lot of time in my life trying to make up for this fact. After college if I wasn't studying at night to perform better at my job I was taking courses so I could get the job I really wanted. So the hard work eventually gets put in, it's all a matter of timing. It also shows that what employers are really buying when they hire a college graduate is a person who has learned how to study. It provides a level of confidence that when new stuff crops up on the job the employee will be able to work through it and figure out a way to accoplish it. In a technical field most of your knowledge will be obsolete in 5 years anyway, so the reality is your entire value you bring to the table as a college graduate is your ability to study.

Links to other study sites

I would encourage you to do your own web search on the topic of study skills or study in college on a frequent basis. You may discover something that is very helpful to your own personality. Remember you must take this information and personalize it for yourself. Somethings that work for other people may not work for you. But you need to keep searching for the answers.

Study block or the little voice that won't

In any endeavor there is a part of your mind that tells you: you can't do it. this is a waste of time. Your a fool for trying. This will never work. I noticed it first when I played keeper in Soccer. It was fun to dive at first but after a few dives I noticed the thought process increased (ie. that little voice got louder). Sometimes your internal dialog is helpful, but a lot of times it's your own worst enemy. Somewhere during a game the thoughts would be you're never going to stop this guy's shots why even bother to dive? or He's in too close the ball will be well past you even if you try to dive. At this point I would dive no matter what. Even if my reaction time was off and I'm diving well after the shot. The point was to show that part of my mind we are diving anyway there is no way to avoid the pain so from now on let's get with the program and see if we can stop these shots.

That same thought process happens when you try to study. It starts as: "lets play a video game first". "Check what's on TV we can study later". "It's such a long walk to the library why bother just read a little bit hear in your room". But if you choose to entertain the thought process it devolves into. "You're going to fail anyway". "2 hours is enough you know all you can get is a C". "You're just not good at this course so why bother with it". This is all part of what I call study block. It's like writer's block but it encompasses the whole study process not just the writing part.

The way out of the thought process is rituals. By going through rituals you are telling your inner voice I'm not listening. See I'm getting ready to study and there's nothing you can do about it. Over time you train yourself to get into a study mode. I would make the following suggestions if you're having trouble studying:

  • Find a study area that is not part of your living quarters, your home should be the reward and sanctuary for good studying, or used on special occasions.
  • If possible find a place where you have access to a white board or chalk board
  • Try to get a study room if they are available rather than a carol where you have a table to spread out on
  • If you must listen to music choose instrumentals rather than anything with singing. Experiment with your musical selections and see if any produce better studying.
  • If you find that you keep reading the same passage over and over read aloud for a while. Reading aloud forces you to engage more of your brain. It slows you down a little because you can read faster when you read silently, but if it's the only way to push through the material so be it.
  • Make a cheat sheet. Not to cheat mind you, but hypothetically if you were to cheat what could you put down on an 8.5 x 11 inch piece of paper that would guarantee you a good grade? This is really a good method of condensing your notes but, somehow, because you call it a cheat sheet, the "little voice" gets intriuged and starts to help you: "Don't for get to put down stuff for this section"

More on flow

There's a lot on the internet about flow. It's a concept that's been around a while and everyone rediscovers it from time to time. Back in the late 80's early 90's I remember an article that talked about helping programmers achieve flow. The single most important thing they found was to provide them an office with a door. Literally to shut out distractions.

In Software Development there are always discussions about "The Flow". I believe that the reason so many programmers work into the wee hours of the morning has to do with maintaining the flow state. There are fewer distractions at night. You are tired which I believe stops the internal chatter that can get in the way of achieving the flow state. There is also the reward of going to bed when you're finished. I can't tell you how many times I've told myself, at 1 in the morning, let me finish up the code for this last method and make sure it compiles and I'll call it a night and finally crawl into bed around 3.

Just to show you I'm not making this stuff up check out the following short article:

One thing you will see mentioned about flow, in some articles,is to do something that you love. That's something that College Students may not have the luxury of doing. You are not going to love every course you take. But you still need to try to get into flow if you are going to study well. The above article does a good job of describing some of the symptoms of flow. But you don't really know your in it until your out of it. Then you realize that wow I just got alot done or you find that 2 hours have gone by and you hardly noticed. This state is highly personalized as well. Don't feel too bad if you don't have the highly romanticized experiences described on the web. In the end you're just looking for some highly productive time where things seemed to finally click. In the end "The Flow" is just some good efficient study time, if you get anymore emotional benefits from it it's just icing on the cake.

Author: Nasty Old Dog

Validate

Sunday, June 16, 2013

AP Computer Science: The Summer After

AP Computer Science: The Summer After

AP Computer Science: The Summer After

Introduction

It is now almost summer (2013) and for those of you who have completed the AP Computer Science course you may be wondering: How do you maintain (and/or improve) your computer skills? At least this was the question from one student I know in a similar situation and I thought it was a good question to address.

Program For Yourself

The first thing you must do is program for yourself. The Blackjack series of programs from this blog was my attempt to show new students that the subject matter of your programs need not be seemingly useless programs. You should be able to dream up any program that may interest you. If your not sure what interests you then I suggest start with some simple things from your math classes. Programming is an excellent way to reinforce your mathematic abilities.

A Summer After Sylabus

Numerical Integration - Trapezoidal Rule

In calculus you learned to differentiate and integrate various functions. You should have learned that some functions (eg. 1/(ln x)) do not have an integral that can be expressed as a formula. That's where the Trapezoidal Rule comes in to play. By just knowing the original function you can estimate the area under its curve (ie. find an estimate of the definite integral) by dividing the area up into tiny trapezoids and summing up their area. The smaller the width of the trapezoids the more accurate the estimate.

  1. Find the definition of the Trapezoidal Rule in your calculus book or Wikipedia
  2. Create a program that implements the trapezoidal rule.
  3. test the program on the function f(x) = x2 and compare trapezoidal answer to the actual integral (1/3)x3.
  4. If you book has an example of a function that does not have a solvable integral test your program on that function and see that it provides the same answers
  5. Investigate the use of System.out.format to make the output line up nicely
  6. Try implementing Simpson's Rule after you have the Trapezoidal rule working

Big Project

You have this nice integrator function working let's get it ready to share with other people. You could package it as a desktop application but these days everyone wants to access things on the web. There are 2 ways to do this but both need a web server to deliver the program.

  • Applet a java program that is downloaded via the web and run by the web browser
  • Servlet a java program that runs in a Web Server and serves web pages to a browser

Servlet first

To create a servlet you are going to need a web server program. For Java servlets there are a couple available I prefer Apache Tomcat just because I learned that first. Some people like Jetty. The servlet program will be written the same way no matter which you choose. The installation of that servlet will vary depending on which one you use.

For this project the following steps should be taken:

  1. Google the Servlet servers and pick one of your liking
  2. Download and install the server (tomcat project page: http://tomcat.apache.org/)
  3. Get it up and running. Under Tomcat if it's running properly then you should be able to see the admin page when you put http://localhost:8080 in your browser.
  4. Both Eclipse and Netbeans IDE will set up a Servlet project. Google a HelloWorld example under each and get it to compile in your IDE.
  5. Figure out how to get the project to create a .war file so the app can be deployed
  6. Look at the Tomcat User documents and find out where to place the .war file
  7. Once the .war file has been placed you should see it appear in the tomcat admin page.
  8. Go to the servlet in your browser at http://localhost:8080/<app-dir-name>
  9. Create a new project for a servlet and adapt your integration code to run as a servlet
  10. Install the project under tomcat and verify that the code comes up properly

Improving the Integration Servlet

  • create another Servlet that will accept the following user input
    • a - the starting point for the definite integral
    • b - the end point
    • step - the step size
  • Make sure to add a submit button the submit button should call the integration servlet and provide the parameters
  • modify your Servlet to look for the parameters from the new input servlet
  • To make this really amazing can you figure out a way to allow the user to input a function and the servlet compiles it into java code and integrates it. I believe this is possible but I have never done it.

Final Big Project for the Summer

I have 2 suggestions for a final project for the summer.

  • Learn a new language
    • The key to being a good Software Developer is to learn new computer languages quickly. The best way to learn quickly is to dive in and just start learning a new progrmamming language. Then repeat the process, add another and another language to your repertoire. Each successive language learned will be assimilated faster.
    • LISP/Scheme
    • PERL
    • Ruby
    • C/C++
    • J
    • Javascript
    • Prolog
  • Find the Harvard CS50 lecture videos and watch them. The course goes over C, Javascript, and some other languages while teaching introductory principles of Computer Science

Conclusion

That's it! No code at this point. It's time for those that have taken AP Computer Science to start learning to read online documentation and getting things up and running. If you have any problems you should be able to post a comment to the blog I would be glad to give some pointers.

What I will do in the next article will be to create an interface for the function class. Then use that interface to create an Applet that integrates the function. The Applet should then be a specification for how the Servlet project should work from a functional perspective.

Author: Nasty Old Dog

Validate XHTML 1.0

Sunday, May 12, 2013

Graphics Based Black Jack

AP Computer Science: After the Exam: Graphical BlackJack

AP Computer Science: After the Exam: Graphical BlackJack

The AP COMP SCI test is done

Congratulations to every one that took the 2013 AP Exam. This is probably the last series AP Computer Science Articles I write (at least until another one of my kids decides to take the course). Whatever score you end up getting I hope you pursue a few computer courses in college. Computers are involved in every aspect of business and manufacturing and understanding the concepts of building working programs will make you better managers and business owners. Too many managers in the 21st Century think that understanding how to use a spreadsheet is all they require to manage a 21st Century business. Instead I propose that great managers understand what it takes to get things accomplished and understand what goes into making a great product. My hope for the new generation of entrepreneurs is that you persue your talents with passion and take us forward in ways the spreadsheet jockeys can't even dream of, much less understand.

Now that you have some time and aren't worried about taking tests. I wanted to take the BlackJack Program to its next evolutionary step and add a Graphical User Interface to the BlackJack Program. I haven't used the Java Swing classes in a long time and have never considered myself a User Interface Programmer so I will step you through the process as an example of how at least one programmer treads into uncharted territory.

Spicing up BlackJack

First things first I'm going to steal some pictures and code. It seems legal because the developer has placed them on his(or her) website for free. So go to http://www.jfitz.com/cards/index.html and download the classic-cards.zip. That file contains a .png file of all the card faces needed to implement the game. The picture of all the cards in one file is there to. You are viewing it at the above site. By using your browser to do a "Copy Image Location" you can save the http address for use in the program.

Now go to the following message board site: stackoverflow.com There you will find a piece of code that uses the cards you downloaded. The code there shows you how to use them directly from the web without downloading prior to using them. Feel free to cut and paste the code into your IDE and see how it works. For this project I'm going to adapt one portion of that code: there is a "Factory" class called CreateCards. This grabs portions of the .png file to cut out single card images and store them in objects in a list.

class CreateCards {
   private static final int SUIT_COUNT = 4;
   private static final int RANK_COUNT = 13;

   public static List<ImageIcon> createCardIconList(String pathToDeck)
         throws MalformedURLException, IOException {
      BufferedImage fullDeckImg = ImageIO.read(new URL(pathToDeck));
      int width = fullDeckImg.getWidth();
      int height = fullDeckImg.getHeight();
      List<ImageIcon> iconList = new ArrayList<ImageIcon>();

      for (int suit = 0; suit < SUIT_COUNT; suit++) {
         for (int rank = 0; rank < RANK_COUNT; rank++) {
            int x = (rank * width) / RANK_COUNT;
            int y = (suit * height) / SUIT_COUNT;
            int w = width / RANK_COUNT;
            int h = height / SUIT_COUNT;
            BufferedImage cardImg = fullDeckImg.getSubimage(x, y, w, h);
            iconList.add(new ImageIcon(cardImg));
         }
      }
      Collections.shuffle(iconList);
      return iconList;
   }
}

Now the above code is not quite what we will use but it is informative. The author (pseudonym: Hovercraft Full of Eels) shows how to take the full deck image and divide it up into individual card images. The BlackJack program we created has a bit of a problem because we used modulo to create card face values and suits.

Instead of looping through the suits and "rank" (rank is what I originally termed face_value), use modulo to get the rank and suit. Change the text model order for the suits:

  • was: private String suit = "HDSC";
  • now: private String suit = "CSHD";

Now the card images get set up in a one to one correspondence image to text. Pretty simple change for some borrowed code.

This program doesn't really need the ImageIcon object. That provides some capabilities to move the image around on the screen. For a simple blackjack program there isn't really a need for this functionality. The code has been adapted further to use the BufferedImage class directly.

Hide the Image Down Deep Inside

To adapt the above code the question arises where do you store the image? The PlayingCard object is the obvious choice. A PlayingCard should know how to display itself.

The CardDeck object already loops 52 times to create all the PlayingCard's by calling the PlayingCard constructor method. By creating a BufferedImage field in the PlayingCard object and using the CardImageFactory method makeCardImage in the constructor, all the images will be associated with the PlayingCard Objects with very little coding. All that is needed is to properly map from our cardno in a PlayingCard to the appropriate image in the large image file.

First the new factory class CardImageFactory:

package blackjack;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

/**
 * Factory class to create images for each card so it may be displayed 
 * graphically. Everything is static but initCardImageFactory method 
 * must be called first to set up the full image of all the cards in memory
 * this way the call to makeCardIcon does not make 52 web accesses
 * 
 * @author Nasty Old Dog
 */
public class CardImageFactory {
   private static final int SUIT_COUNT = 4;
   private static final int RANK_COUNT = 13;
   private  static BufferedImage fullDeckImg = null;
   public static   int width = 0;
   public static   int height = 0;

      /**
    * Initialized the .png image in memory and sets up width and height 
    * readying size parameters to cut the image up into icons. This also
    * isolates IO exceptions to this method so the individual calls 
    * do not have to have exception handling.
    * 
    * @param pathToDeck the http address of the full card image file
    * @throws MalformedURLException
    * @throws IOException 
    */
   public static void initCardImageFactory(String pathToDeck) 
           throws MalformedURLException, IOException{
      fullDeckImg = ImageIO.read(new URL(pathToDeck));
      width = fullDeckImg.getWidth();
      height = fullDeckImg.getHeight();
   }

   /**
    * For the structure of the current Black Jack program this returns 
    * individual card images instead of a full list. This allows you to 
    * develop a class hierarchy where the image is stored at the individual
    * PlayingCard object level.
    * 
    * @param rank card face value number 0 - 12
    * @param suit suits 0 - 4
    * @return 
    */
   public static BufferedImage makeCardIcon(int rank, int suit) {
            int x = (rank * width) / PlayingCard.RANK;
            int y = (suit * height) / PlayingCard.SUIT;
            int w = width / PlayingCard.RANK;
            int h = height / PlayingCard.SUIT;
            return fullDeckImg.getSubimage(x, y, w, h);
            // BufferedImage cardImg = fullDeckImg.getSubimage(x, y, w, h);
           // return new ImageIcon(cardImg);
   } 

   /**
    * The original image list created from the example found at: 
    * http://stackoverflow.com/questions/9692465/java-how-do-i-drag-and-drop-a-control-to-a-new-location-instead-of-its-data
    * created by author who goes by pseudonym: "Hovercraft Full of Eels"
    * @return
    * @throws MalformedURLException
    * @throws IOException 
    */
   public static List<ImageIcon> createCardIconList()
         throws MalformedURLException, IOException {
      //BufferedImage fullDeckImg = ImageIO.read(new URL(pathToDeck));
      width = fullDeckImg.getWidth();
      height = fullDeckImg.getHeight();
      List<ImageIcon> iconList = new ArrayList<ImageIcon>();

      for (int suit = 0; suit < SUIT_COUNT; suit++) {
         for (int rank = 0; rank < RANK_COUNT; rank++) {
            int x = (rank * width) / RANK_COUNT;
            int y = (suit * height) / SUIT_COUNT;
            int w = width / RANK_COUNT;
            int h = height / SUIT_COUNT;
            BufferedImage cardImg = fullDeckImg.getSubimage(x, y, w, h);
            iconList.add(new ImageIcon(cardImg));
         }
      }
      Collections.shuffle(iconList);
      return iconList;
   }

}

I left the "Eels" original method in the class as a reminder of where all the code came from. I split the file access from the image chopping because the file access routines throw exceptions. I want to handle those right away. So they have been placed in the "initCardImageFactory" method. This method is called in the main method to set up images in memory to be cut up when calls to the PlayingCard constructor are made. There's no sense trying to even create PlayingCards or running the program further if the program can't access the image file. As a rule I don't like to have exceptions in constructors the code becomes ugly when trying to create an object.

The other problem with creating a CardImageFactory object is where will the object reside so that the PlayingCard object has access to it. It could be set up in CardDeck and then passed in to the PlayingCard constructor but this again makes the code ugly. It is better to make it a set of static fields and method calls and limit where they are called from.

Java Swing and Graphics2D Libraries

Now that the decision has been made about where the image creation will be done one more thing that is needed is some code that will open a window for all this great graphics to be displayed in. Once that is in place the code changes can be added to the PlayingCard object so that PlayingCard instances (the objects created by CardDeck) get displayed properly.

The Java Swing Library is a graphics API. It provides windows for the program to run in. It has a call to "add" graphic objects into the window. The blackjack program needs a window object and a class that the window object knows how to display.

  • JFrame class: from the Swing API provides a graphics window
  • JComponent class: Swing API class that can be displayed in a JFrame

Any object that has a graphical representation will need to extend JComponent. This gives the object the ability to be used within a JFrame. It also needs a paint method. JFrame will call the paint method on all the objects that have been added to it when 2 method calls take place:

  • frame.pack();
  • frame.setVisible(true);

Assuming the PlayingCard object has been modified the following code is all we need to display a card:

JFrame frame = new JFrame("BlackJack");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PlayingCard p1 = new PlayingCard(2);
frame.getContentPane().add(p1);
frame.pack();
frame.setVisible(true);

The PlayingCard Class

The PlayingCard Object is where most of the action takes place. The constructors have the calls to makeCardIcon have been placed. The next changes that are necessary is the object must extend JComponent and have a "paint" method. The paint method takes a "Graphics" object as a parameter. This will ultimately be supplied by JFrame after we add the PlayingCard to the list of objects to be displayed.

There is some ugly casting of the "Graphics" object to the "Graphics2D" object. This harkens back to the early days of Java and the use of the AWT drawing classes. The Swing drawing classes are an improvement over the AWT classes because the Swing classes make calls directly to the windowing system of the computer. So windows computers will see MS Windows style windows and Mac users will see Mac style windows. To make this change happen without killing off the AWT API and all the programs that were created the idea of supplying a Graphics2D object came about. It implements everything that the AWT had so you can send it to an old AWT style program and it will think it the old "Graphics" object. But in newer code where you know your using a version of Java that supports Graphics2D you can cast the graphics object to Graphics2D and get all the extra functionality that the new class provides.

Without further ado the PlayingCard Class now looks like:

/*
 * PlayingCard.java - Playing card class for BlackJack
 */
package blackjack;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;

/**
 * Object model of a simple playing card. Class has been adapted to be displayed
 * in a JFrame 
 * 
 * @author Nasty Old Dog
 */
public class PlayingCard extends JComponent{
    public static final int RANK=13;
    public static final int SUIT=4;
    private int cardno;
    private int card_score[] = {11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};
    private BufferedImage img = null;

    private String faceVal = "A23456789TJQK";
    private String suit = "CSHD";

    public PlayingCard(int cardno)
    {
        this.cardno = cardno;
        this.img = CardImageFactory.makeCardIcon(cardno%RANK, cardno%SUIT);
    }

    public PlayingCard(int cardno, int[] card_score)
    {
        this.cardno = cardno;
        this.card_score = card_score;
        this.img = CardImageFactory.makeCardIcon(cardno%RANK, cardno%SUIT);
    }

    /**
     * Get the card scoring value for blackjack face cards = 10 ace = 11 
     * all other cards equal their face value. Aces can equal 1 at times and 
     * is handled elsewhere
     * @return 
     */
    public int card_value()
    {
        return card_score[cardno % 13];
    }

    /**
     * convert cardno into text string of face value and suit
     * @return 
     */
    public String getCardText() {
        int card_val = this.cardno % 13;
        int card_suit = this.cardno % 4;
        return this.faceVal.substring(card_val, card_val + 1)
                + this.suit.substring(card_suit, card_suit + 1);
    }

    /**
     * paint the image for the Playing card as Graphics2D image
     * @param _g 
     */
    @Override
    public void paint(Graphics _g) {
        Graphics2D g = (Graphics2D) _g;
        g.drawImage(img,10,10,null);
    }
}

Testing the program so far

The BlackJack class (the main class for this project) looks like this:

/*
 * BlackJack a simple implementation upgrade for graphical card display
 */
package blackjack;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Scanner;
import javax.swing.JFrame;

/**
 * This class controls the game logic of this simple implementation of 
 * Black Jack. A more profession version would allow for multiplayer games
 * via a game server so you could play your friends on the internet. 
 * Some improvements would be:
 * <p>
 *    Adding insurance (players could insure bets against a dealer having blackjack) <p>
 *    Increase the payout for a blackjack hand to 1.5 x the original bet <p>
 *    Double Down <p>
 *    Splitting pairs <p>
 * 
 * @author Nasty Old Dog
 */
public class BlackJack {

    int card_score[] = {11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};
    CardDeck card;
    Hand player;
    Hand dealer;

    public BlackJack()
    {
        this.card = new CardDeck();
    }

    /**
     * run method that does all the work of this class
     */
    public void run() {
// **************************************************************
//   Added graphics code
        JFrame frame = new JFrame("BlackJack");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        PlayingCard p1 = new PlayingCard(2);
        frame.getContentPane().add(p1);
        frame.pack();
        frame.setVisible(true);
// **************************************************************
        this.card.display();
        this.card.shuffle();
        this.card.display();

        // Now I just need to create the hand objects
        this.player = new Hand("Player Hand");
        this.dealer = new Hand("Dealer Hand");
/*
 *               .
 *               .
 *               .
 *      The rest of the code for run() remains unchanged from it's 
 *      previous incantation
 *               .
 *               .
 *               .
 */

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            // initialize the CardImageFactory to use the full card image file
            CardImageFactory.initCardImageFactory("http://www.jfitz.com/cards/classic-playing-cards.png");
            BlackJack game = new BlackJack();

            game.run();
        } catch (MalformedURLException ex) {
            System.out.println(ex.getMessage());
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }        
    }
}

The call to init the CardImageFactory has been placed in the main routine. The calls to the JFrame have been added and one PlayingCard object is created to see if we can create a window that displays a PlayingCard as a graphic instead of the text we have been doing before.

The Graphics

For this project I took the 4 BlackJack Classes created earlier (BlackJack, CardDeck, PlayingCards, and Hand) and added the CardImageFactory class and put them all into a new project. This helps to isolate the program so it can be packaged as a stand alone program. When you make the changes to BlackJack and PlayingCards you should see a window pop up.

It needs to be enlarged and the window is responsive to mouse commands. When it is enlarged we see a card was created and displayed using the PlayingCard.

Conclusion

The small window that opens up when the program is run is annoying. Nobody wants to have to reset the size with the mouse to see what is going on. The addition of one more method call on the JFrame object will fix the problem:

  • frame.setPreferredSize(new Dimension(300,300));

Adding this will open a window where the full card is displayed.

The other interesting behavior this program has is that the window is in control of terminating the program. If you kill the window the whole program terminates. For a graphics program this is the expected behavior. Right now the BlackJack program lives in a text based world that is separated from the graphics based world. It would be nice as the program transitions to span both worlds at the same time so a direct comparison between the graphics presentation and the text based presentation can be made. This may be beyond the scope of this project as JFrame objects are meant to run in a multi-threaded environment and weaving control back and forth may not be the best way forward.

For the entire source code download the following and unzip:

blackjacksrc.zip

NEXT STEPS

  • Modify CardDeck so it displays the entire deck of cards as a test to see that all images have been accounted for
  • Modify Hand so it displays it's cards graphically
  • Add graphic controls for the user to control the game
  • Weave in the blackjack control code into the graphics code to complete the game

References

  1. stackoverflow.com "Java: How do I drag and drop a control to a new location instead of its data?" answer by author pseudonym "Hovercraft Full of Eels" stackoverflow.com Link
  2. The Java Tutorials (oracle.com) "Using Swing Components: Using Top-Level Containers" Top-level Containers Link
  3. Hardy, Vincent J. "Java 2D API Graphics" Palo Alto, CA: Sun Microsystems, 2000.

Author: Nasty Old Dog

Validate XHTML 1.0

Sunday, April 28, 2013

AP Computer Science Study Guide as Computer Program Take 2

AP Computer Science Study Guide Take 2 <![CDATA[/*>

AP Computer Science Study Guide Take 2

Introduction

This guide was started in a previous article with comments for language elements an AP Student should know and be able to give a code example. This incantation of the same topic fills in most of the blanks with coding examples. If you were a good student you should be able to compare yours to mine. If you are a lazy student (meaning you didn't try to add any of your own code to the study guide) you better look through the code examples carefully and make sure they look familiar to you.
How to use this guide:
  • Pull the code into your IDE in its own project and run the program.
  • Generate the javadoc for the project. There should be a menu command to do it. In netbeans in was found in the run menu. For eclipse users if you can't find a quick web search should give you an answer.
  • Read through the code. The comments tell the story of what is going on.
  • Print out
    • the JavaDoc
    • the code
    • the output
  • Place them side by side on a large table and look through line by line and find where things are happening and why.

Things to look for

Different Types of Java Comments

The AP overview indicates you should be aware of the various types of comments. The most complex is the Javadoc style block comment. It contains @param and @return metafunctions in them. These comments start with /** and have *'s beginning each line with a terminating */ (on the last line). If they occur just before a method or class declaration the text within the comment will appear in the generated Javadoc. There are 2 other forms of comments one the // is used extensively in the APSubset code. The regular block comment /* . . . */ is shown only once.
The reason to point this out to you is that large portions of the code have to be used to engage the Java comments in an insignificant way. Where most of the java code examples can be accomplished with a few lines of code and a few output statements.

Method overloading

This functionality is spread in 2 different sections of code. The reverse method is defined twice. Once for Strings and then for integers. It is then used in the main method showing how the call signatures are the same and only the parameters change.

Exceptions

This could almost be done within the main method alone except that you also need to know about throwing an Exception. For this I created a small method that looks at its 'int' input parameter and throws an Exception if the parameter is the 'int' 3. Otherwise it just prints some diagnostic text to let you know it was called. The AP document was not too specific about which 'Exception's you should know about. I picked 3 that I thought you may have come across already in your projects. The fourth 'Exception' used is the parent class for Exceptions. Using this class is a useful way to catch Exceptions when your not sure which ones are likely to be thrown.
The reason for try-catch-finally and 'Exceptions' are to allow a program to either die gracefully or recover from an error. They are used extensively in large programming projects and Java does a nice job of integrating them in a modular way.
The 'finally' clause is run after every exception 'catch' clause has completed. In the code set up in APSubset the try catch block is run in a loop. The loop is set up to simulate a different error during each iteration. In a more robust program the try-catch block may be around your entire code. Remember most of the time Exceptions are things to avoid in the design of your code. You put them in because you may not be aware of every error scenario that could occur. In a small example such as this I had to force things to happen in a very small space. The idea behind 'finally' is that it gives you a guarenteed exit point from any Exception. A place where you can reset things or decide that the error involved was too grave and you must terminate the program. It's a place where common error handling or recovery can be done.
In the exception code there is a line commented out. It does a divide by zero but it is outside the try-catch block. Uncomment it in the IDE and run the code. You should find that the program will terminate there and no other statements past that point will be executed. Now compare that with the way the zero divide works inside the try-catch block. That should give you an idea of the utility of the Exception handling facilities in Java.

APSubset.java

The code is 600+ lines of code so rather than place it in the text of the article I have made it into a downloadable file. Go ahead and download it and run it yourself in your own Java IDE.
APSubset.java

Output (Run from Netbeans IDE)

run:
APSubset: BASIC TYPES
APSubset: int a = 0
APSubset: double b = 0.0
APSubset: boolean c = false
APSubset: 

APSubset: BASIC OPERATORS
APSubset: int a = 1 + 2 = 3
APSubset: double b = 2.0 + 3.5 = 5.5
APSubset: int a = 2 - 3 = -1
APSubset: double b = 2.0 - 3.5 = -1.5
APSubset: int a = 2 * 3 = 6
APSubset: double b = 2.0 * 3.5 = 7.0
APSubset: int a = 3 / 2 = 1
APSubset: double b = 3.5 / 2.0 = 1.75
APSubset: int a = 17 % 5 = 2
APSubset: double b = 17.0 % 6.0 = 5.0
APSubset: 

APSubset: Pre/Post-increment and Pre/Post-decrement
APSubset: int a = 2
APSubset: a++ = 2
APSubset: int a = 3
APSubset: ++a = 4
APSubset: int a = 4
APSubset: a-- = 4
APSubset: int a = 3
APSubset: --a = 2
APSubset: int a = 2
APSubset: double b = 5.0
APSubset: b++ = 5.0
APSubset: double b = 6.0
APSubset: ++b = 7.0
APSubset: double b = 7.0
APSubset: b-- = 7.0
APSubset: double b = 6.0
APSubset: --b = 5.0
APSubset: double b = 5.0
APSubset: 

APSubset: Assignment operators +=, -=, *=, /=, %=
APSubset: int a = 13
APSubset: double b = 13.0
APSubset: int a += 7 = 20
APSubset: double b += 7.5 = 20.5
APSubset: int a -= 3 = 17
APSubset: double b -= 3.5 = 17.0
APSubset: int a *= 2 = 34
APSubset: double b *= 2.0 = 34.0
APSubset: int a /= 2 = 17
APSubset: double b /= 2.0 = 17.0
APSubset: int a %= 5 = 2
APSubset: double b %= 6.0 = 5.0
APSubset: boolean c = 1 == 1 = true
APSubset: boolean c = 2 != 3 = true
APSubset: boolean c = 2 < 1 = false
APSubset: boolean c = 2 < 3 = true
APSubset: boolean c = 2 <= 4 = true
APSubset: boolean c = 2 <= 2 = true
APSubset: boolean c = 4 > 1 = true
APSubset: boolean c = 4 >= 5 = false
APSubset: boolean c = 5 >= 5 = true
APSubset: 

APSubset: Logical Operators ||, &&, !
APSubset: boolean c = true || true = true
APSubset: boolean c = true || false = true
APSubset: boolean c = false || false = false
APSubset: boolean c = true && true = true
APSubset: boolean c = true && false = false
APSubset: boolean c = false && false = false
APSubset: int[] d = null: in else clause due to short circuit
APSubset: int[] d = 1  2  3  4  5  
APSubset: double b = 5.0/2 = 2.5
APSubset: double b = (int) b = 2.0
APSubset: int a = (int) 5.0/2 = 2
APSubset: double b = 5.0/(int) 2 = 2.5
APSubset: double b = (int) 5.0/(int) 2 = 2.0
APSubset: double b = ((int) 5.0)/(double) 2 = 2.5
APSubset: double b = ((int) 5.0)/ 2 = 2.0
APSubset: Take a string, concat a number13and another string
APSubset: to see a back slash must escape it with a backslash \\ = \
APSubset: to print a double quote use backslash double quote \" = "
APSubset: 
 to get
 extra 
 lines use backslash-n (\n) 

APSubset: Look at the code for this because there are some interesting \ (backslash) uses


APSubset: One Dimension Array: Size = 5  array = 0 1 2 3 4
APSubset: Notice in the code that the size is 5 and the indexes range from 0 - 4
APSubset: Output 2 x 2 array in matrix form
0  1   
1  0   
APSubset: twod[0].size = 2
APSubset: twod[1].size = 2
APSubset: twod.size = 2
APSubset: if statements: single statement follows
APSubset:   stmt1:
APSubset:   single statement if: 1 < 2
APSubset:   stmt2:
APSubset: if statements: compound statements
APSubset:   stmt1:
APSubset:   compound if:
APSubset:   1 < 2 is true
APSubset:   all statements are executed within braces
APSubset:   stmt2:
APSubset: only 1 of the if statement is executed in the compound ifs
APSubset: then clause: num + 5 < 20 is true
APSubset: else clause: num + 15 < 20 is false
APSubset: while loop: count numbers from 0 to 9
0 1 2 3 4 5 6 7 8 9 APSubset: end while loop
APSubset: for loop: version of above while loop
APSubset: for(i = 0; i < 10; i++): all loop controls are in first line (you don't have to search through the loop)
0 1 2 3 4 5 6 7 8 9 APSubset: end for loop
APSubset: for each: use on intarr defined above, check the difference
APSubset: this version uses the fact that if you are going to visit each element
APSubset: the computer knows the size and can automatically code the loop parameters
0 1 2 3 4 APSubset: end for each style loop
APSubset: new operator: using new to create an object instance of APSubset
APSubset: this will give us an object to use the 'reverse' methods defined above
APSubset: apsubset instantiated to an APSubset object
APSubset: method over loading: 2 reverses have been defined:
APSubset: one to reverse strings and one to give a string of reversed 'int'
APSubset: look at their definitions they have different call parameters
APSubset: the compiler figures out which one to use based on parameter type
APSubset: apsubset.reverse("abcdefg") = gfedcba
APSubset: apsubset.reverse(12345) = 54321
APSubset: The methods do similar things but to different types of parameters.
APSubset: Run your IDE JavaDoc on this class and you will see what different
APSubset: comment styles do for the JavaDoc Documentation.
APSubset: Single line comments starting with // are used copiously in this class
APSubset: these 'log' statements are defined as static they can be used anywhere
APSubset: inside this class definition. If one were to use it in another class
APSubset: would have to use: APSubset.log();
APSubset: APSubset.log() call check the code
APSubset: static field: APSubset.ANSWER = 42
APSubset: String nullstr = null;  can't print this because it's null it has no String value yet
APSubset: We can test if the variable is a null variable
APSubset: null: reserved variable name value is null
APSubset: if (e = true): Forgot the extra equal sign setting e to true rather than testing with ==
APSubset: e = true; f = false
APSubset: if (e = f): in else clause because of '=' assignment now e is false
APSubset: e = true; f = true
APSubset: if (e == f): Now this works as expected.
APSubset: Be careful with your use of = and == especially with booleans
APSubset: exceptionGeneratorMethod executed no exception thrown ctr = 0
APSubset: try-catch ArithmeticException: / by zero
APSubset: finally clause executed: j = 0
APSubset: exceptionGeneratorMethod executed no exception thrown ctr = 1
APSubset: try-catch NullPointerException: null
APSubset: finally clause executed: j = 1
APSubset: exceptionGeneratorMethod executed no exception thrown ctr = 2
APSubset: loop past intarr boundry
0 1 2 3 4 APSubset: try-catch IndexOutOfBoundsException: 5
APSubset: finally clause executed: j = 2
APSubset: try-catch Exception: exeptionGenerator Method: ctr = 3
APSubset: finally clause executed: j = 3
APSubset: java.lang.Object
APSubset:  
APSubset: java.lang.Integer
APSubset: Integer myint = new Integer(55) therefore myint.intValue() = 55
APSubset: Integer.MIN_VALUE = -2147483648
APSubset: Integer.MAX_VALUE - 2147483647
APSubset:  
APSubset: java.lang.Double
APSubset: Double mydub = new Double(35.75) therefore mydub.doubleValue() = 35.75
APSubset:  
APSubset: java.lang.String
APSubset: String test_str = "this has 22 characters"
APSubset: test_str.length = 22
APSubset: test_str.substring(4,10) =  has 2
APSubset: test_str.substring(4) -  has 22 characters
APSubset: test_str.indexOf("has") = 5
APSubset: test_str.compareTo("this has 22 characters") = 0
APSubset: test_str.compareTo("this has 22 characters") = 19
APSubset: test_str.compareTo("this has 22 characters") = -6
APSubset:  
APSubset: java.lang.Math
APSubset: Math.abs(-3) = 3
APSubset: Math.abs(-3.56) = 3.56
APSubset: Math.pow(2.0,5.0) = 32.0
APSubset: Math.sqrt(2.0) = 1.4142135623730951
APSubset: Math.random() = 0.025126650838768416
APSubset: Math.random() = 0.8468764801673784
APSubset: Math.random() = 0.5932715934489992
APSubset:  
APSubset: Added values to end of list in succession: 
1 2 3  
APSubset: intList.size() = 3
APSubset: Added 4 to end of list: inList.size() = 4
APSubset: intList.get(2) = 3
APSubset: intList.add(2,5): 
1 2 5 3 4  
APSubset: Added 5 to each value using intList set: 
6 7 10 8 9  
APSubset: intList.remove(1): 
6 10 8 9  
APSubset: intList.remove(2): 
6 10 9  
APSubset: Because remove shifts the elements the 2 method calls end up removing
APSubset: elements at index 1 and 3 of the original array
BUILD SUCCESSFUL (total time: 1 second)

APSubset JavaDoc

A pdf of the JavaDoc Generated from netbeans can be downloaded from:
APSubset JavaDoc

Conclusion

There are still some things from the AP document not coded. Some of them were outside the scope of this type of study guide. Some I couldn't think of a simple yet elegant example. I've marked those in the comments of the APSubset code. Most of them you should have been exposed to in projects you've done in your class.
This study guide is meant to remind you of the functional elements of Java available to you during your AP Test. I think it is more of a guide for the free response problems. Helping you to cast your answers in the subset so that you don't over think the problem or over utilize functionality available in advanced libraries.
I did not cover the Grid World case study in this and certainly that is something you need to look over and understand. The idea here was to cover the foundational elements of Java by way of a program so you may remember them if you need them.

References

  1. https://apstudent.collegeboard.org/apcourse/ap-computer-science-a/course-details "Course Details." AP Computer Science A. N.p., n.d. Web. 29 Mar. 2013.
Author: Nasty Old Dog
-->