Mr. Meinzen - AP CSA Summer Institute Forms

"Success is the ability to go from one failure to another with no loss of enthusiasm." Winston Churchill

Home | Day 1 | Day 2 | Day 3 | Day 4 | Day 5 | Handouts

 

AP CSA pre-Workshop Participant Survey

 

[Optional] Your name, school, & email/contact:

 

 

I. Circle the description that best fits the answer to "Why are you in this workshop?"

I like the free lunches.

I am/will be teaching APCS for the first time

I want to focus on a specific topic/issue.

Your answer...

 

II. Circle the answer that best describes your experience with programming:

How many years have you known or taught Object-Oriented Programming (OOP)? What language?

0

1

2-3

4-5

>5

How many years have you taught AP Computer Science?

0

1

2-3

4-5

>5

Is your course authorized?

Yes
No
Pending
What?
 

 

III. Circle the number that reflects your priority regarding the following:

(0=lowest priority)

Goal 1a: Become familiar with the Advanced Placement Program & AP Computer Science (AP CSA) including Equity & Access Issues

0

1

2

3

4

Goal 2: Become familiar with the official Course Description

0

1

2

3

4

Goal 3: Become familiar with the new Exemplar Labs

0

1

2

3

4

Goal 4: Become familiar with the AP CSA Exam

0

1

2

3

4

Goal 5: Structure your Syllabus and meet the Course Audit requirements

0

1

2

3

4

Goal 6: Become familiar with Instructional Design & Strategies for Teaching Content

0

1

2

3

4

Rank the following in order of importance when setting up an AP Program
(1=most important, 6=least important)

Curriculum/ Syllabus

Advocacy

Administration permission/rules

Content

Standards Alignment

Other (list below)

_______ _______ _______ _______ _______ _______

 

IV. What, if any, AP CSA topic or goal would you like to have addressed today?

 

 

 

V. What, if any, AP CSA topic or goal would you like to have addressed this week?

 

 

 

VI. What, if any, expertise or information would you be willing to share with the other workshop participants (or workshop leader)?

 

 

Feedback from Participants after the Workshop:

 

[Optional] Your name, school, & email/contact:

 

 

I. How well do you feel YOUR...

(0=not met, 1=poorly, 2=satisfactory, 3=well, 4=extremely well)

 

...goals were met in the workshop? [add any comments/clarifications in III below]

0

1

2

3

4

...classroom/community needs were met? [add any comments/clarifications in III below]

0

1

2

3

4

 

II. Circle the number that reflects your ability to:

(0=no ability, 1=basic ability but still need individualized help, 2=capable but may need some support, 3=fully capable, 4=mastery)

 

align your instruction with the goals of AP CSA Course

0

1

2

3

4

identify the skills & knowledge that the AP CSA Exam assesses

0

1

2

3

4

identify the content & abilities for which your students may need greater preparation

0

1

2

3

4

draft a syllabus that meets the curricular and audit requirements for the course

0

1

2

3

4

make equitable access a guiding principle in designing instruction

0

1

2

3

4

 

III. What comments or clarifications can you make regarding the APSI to enhance your abilities listed above?

 

 

 

 

IV. How well do you feel that you can accomplish the goals listed below?

(0=not at all, 1=poorly, 2=satisfactorily, 3=well, 4=extremely well)

 

Goal 1: are familiar with the Advanced Placement Program & AP Computer Science (AP CSA)

0

1

2

3

4

Goal 2: are familiar with the official Course Description

0

1

2

3

4

Goal 3: are familiar with the new Exemplar Labs

0

1

2

3

4

Goal 4: are familiar with the AP CSA Exam

0

1

2

3

4

Goal 5: can structure your Syllabus and meet the Course Audit requirements

0

1

2

3

4

Goal 6: are familiar with Instructional Design & Strategies for Teaching Content

0

1

2

3

4

 

V. What comments or clarifications can you make regarding the question above "How well can you accomplish the goals listed"?

 

 

AP CSA sample code: Mapgie Exemplar Lab [Magpie2.java]


Student Exercises on page 212 & 213 [demo]

  1. Alter code to have it respond "Tell me more about your pets" when statement contains the word "dog" or "cat"
  2. Alter code to have it respond favorably when it sees the name of your teacher. Be sure to use appropriate pronouns.
    • Statement: Mr. Finkelstein is telling us about robotics.
    • Response: He sounds like a good teacher.
  3. Alter code to use the String.trim() method to remove spaces at beginning and end and check for length of trimmed statement. If no characters then have the response be "Say something, please."
  4. What happens when you try: "My mother has a dog but no cat." or "I know the state capitals." or "I like vegatables smothered in cheese."

 

/**
 * A program to carry on conversations with a human user.
 * This is the initial version that:  
 * 
 *       Uses indexOf to find strings
 * 
 * 		    Handles responding to simple words and phrases 
 * 
 * This version uses a nested if to handle default responses.
 * @author Laurie White
 * @version April 2012
 */
public class Magpie2
{
	/**
	 * Get a default greeting 	
	 * @return a greeting
	 */
	public String getGreeting()
	{
		return "Hello, let's talk.";
	}
	
	/**
	 * Gives a response to a user statement
	 * 
	 * @param statement
	 *            the user statement
	 * @return a response based on the rules given
	 */
	public String getResponse(String statement)
	{
		String response = "";
		if (statement.indexOf("no") >= 0)
		{
			response = "Why so negative?";
		}
		else if (statement.indexOf("mother") >= 0
				|| statement.indexOf("father") >= 0
				|| statement.indexOf("sister") >= 0
				|| statement.indexOf("brother") >= 0)
		{
			response = "Tell me more about your family.";
		}
		else
		{
			response = getRandomResponse();
		}
		return response;
	}

	/**
	 * Pick a default response to use if nothing else fits.
	 * @return a non-committal string
	 */
	private String getRandomResponse()
	{
		final int NUMBER_OF_RESPONSES = 4;
		double r = Math.random();
		int whichResponse = (int)(r * NUMBER_OF_RESPONSES);
		String response = "";
		
		if (whichResponse == 0)
		{
			response = "Interesting, tell me more.";
		}
		else if (whichResponse == 1)
		{
			response = "Hmmm.";
		}
		else if (whichResponse == 2)
		{
			response = "Do you really think so?";
		}
		else if (whichResponse == 3)
		{
			response = "You don't say.";
		}

		return response;
	}
}

AP CSA sample code: Elevens Exemplar Lab [Card.java & Deck.java]



/**
 * Card.java
 *
 * Card represents a playing card.
 */
public class Card {

	/**
	 * String value that holds the suit of the card
	 */
	private String suit;

	/**
	 * String value that holds the rank of the card
	 */
	private String rank;

	/**
	 * int value that holds the point value.
	 */
	private int pointValue;


	/**
	 * Creates a new Card instance.
	 *
	 * @param cardRank  a String value
	 *                  containing the rank of the card
	 * @param cardSuit  a String value
	 *                  containing the suit of the card
	 * @param cardPointValue an int value
	 *                  containing the point value of the card
	 */
	public Card(String cardRank, String cardSuit, int cardPointValue) {
		//initializes a new Card with the given rank, suit, and point value
		rank = cardRank;
		suit = cardSuit;
		pointValue = cardPointValue;
	}


	/**
	 * Accesses this Card's suit.
	 * @return this Card's suit.
	 */
	public String suit() {
		return suit;
	}

	/**
	 * Accesses this Card's rank.
	 * @return this Card's rank.
	 */
	public String rank() {
		return rank;
	}

	/**
	 * Accesses this Card's point value.
	 * @return this Card's point value.
	 */
	public int pointValue() {
		return pointValue;
	}

	/** Compare this card with the argument.
	 * @param otherCard the other card to compare to this
	 * @return true if the rank, suit, and point value of this card
	 *              are equal to those of the argument;
	 *         false otherwise.
	 */
	public boolean matches(Card otherCard) {
		return otherCard.suit().equals(this.suit())
			&& otherCard.rank().equals(this.rank())
			&& otherCard.pointValue() == this.pointValue();
	}

	/**
	 * Converts the rank, suit, and point value into a string in the format
	 *     "[Rank] of [Suit] (point value = [PointValue])".
	 * This provides a useful way of printing the contents
	 * of a Deck in an easily readable format or performing
	 * other similar functions.
	 *
	 * @return a String containing the rank, suit,
	 *         and point value of the card.
	 */
	@Override
	public String toString() {
		return rank + " of " + suit + " (point value = " + pointValue + ")";
	}
}


import java.util.List;
import java.util.ArrayList;

/**
 * The Deck class represents a shuffled deck of cards.
 * It provides several operations including
 *      initialize, shuffle, deal, and check if empty.
 */
public class Deck {

	/**
	 * cards contains all the cards in the deck.
	 */
	private List cards;

	/**
	 * size is the number of not-yet-dealt cards.
	 * Cards are dealt from the top (highest index) down.
	 * The next card to be dealt is at size - 1.
	 */
	private int size;


	/**
	 * Creates a new Deck instance.
	 * It pairs each element of ranks with each element of suits,
	 * and produces one of the corresponding card.
	 * @param ranks is an array containing all of the card ranks.
	 * @param suits is an array containing all of the card suits.
	 * @param values is an array containing all of the card point values.
	 */
	public Deck(String[] ranks, String[] suits, int[] values) {
		cards = new ArrayList();
		for (int j = 0; j < ranks.length; j++) {
			for (String suitString : suits) {
				cards.add(new Card(ranks[j], suitString, values[j]));
			}
		}
		size = cards.size();
		shuffle();
	}


	/**
	 * Determines if this deck is empty (no undealt cards).
	 * @return true if this deck is empty, false otherwise.
	 */
	public boolean isEmpty() {
		return size == 0;
	}

	/**
	 * Accesses the number of undealt cards in this deck.
	 * @return the number of undealt cards in this deck.
	 */
	public int size() {
		return size;
	}

	/**
	 * Randomly permute the given collection of cards
	 * and reset the size to represent the entire deck.
	 */
	public void shuffle() {
		/* *** TO BE IMPLEMENTED IN ACTIVITY 4 *** */
	}

	/**
	 * Deals a card from this deck.
	 * @return the card just dealt, or null if all the cards have been
	 *         previously dealt.
	 */
	public Card deal() {
		if (isEmpty()) {
			return null;
		}
		size--;
		Card c = cards.get(size);
		return c;
	}

	/**
	 * Generates and returns a string representation of this deck.
	 * @return a string representation of this deck.
	 */
	@Override
	public String toString() {
		String rtn = "size = " + size + "\nUndealt cards: \n";

		for (int k = size - 1; k >= 0; k--) {
			rtn = rtn + cards.get(k);
			if (k != 0) {
				rtn = rtn + ", ";
			}
			if ((size - k) % 2 == 0) {
				// Insert carriage returns so entire deck is visible on console.
				rtn = rtn + "\n";
			}
		}

		rtn = rtn + "\nDealt cards: \n";
		for (int k = cards.size() - 1; k >= size; k--) {
			rtn = rtn + cards.get(k);
			if (k != size) {
				rtn = rtn + ", ";
			}
			if ((k - cards.size()) % 2 == 0) {
				// Insert carriage returns so entire deck is visible on console.
				rtn = rtn + "\n";
			}
		}

		rtn = rtn + "\n";
		return rtn;
	}
}


AP CSA sample code: Picture Exemplar Lab [SimplePicture.java]


Student Exercises [Activity 3 on page 255]

  1. A1 - Intro to RGB, pixels, binary

  2. A2 - picking a Color

  3. A3 - Explore Picture [demo]

  4. A4 - 2D arrays (matrices)

  5. A5 - modifying an image using PictureTester [demo]

  6. A6 & A7 mirroring an image using PictureTester

  7. A8 - creating a collage

  8. A9 - edge detection


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import java.awt.*;
import java.io.*;
import java.awt.geom.*;

/**
 * A class that represents a simple picture.  A simple picture may have
 * an associated file name and a title.  A simple picture has pixels, 
 * width, and height.  A simple picture uses a BufferedImage to 
 * hold the pixels.  You can show a simple picture in a 
 * PictureFrame (a JFrame).  You can also explore a simple picture.
 * 
 * @author Barb Ericson ericson@cc.gatech.edu
 */
public class SimplePicture implements DigitalPicture
{
  
  /////////////////////// Fields /////////////////////////
  
  /**
   * the file name associated with the simple picture
   */
  private String fileName;
  
  /**
   * the title of the simple picture
   */
  private String title;
  
  /**
   * buffered image to hold pixels for the simple picture
   */
  private BufferedImage bufferedImage;
  
  /**
   * frame used to display the simple picture
   */
  private PictureFrame pictureFrame;
  
  /** 
   * extension for this file (jpg or bmp)
   */
  private String extension;
  
 
 /////////////////////// Constructors /////////////////////////
 
 /**
  * A Constructor that takes no arguments.  It creates a picture with
  * a width of 200 and a height of 100 that is all white.
  * A no-argument constructor must be given in order for a class to
  * be able to be subclassed.  By default all subclasses will implicitly
  * call this in their parent's no-argument constructor unless a 
  * different call to super() is explicitly made as the first line 
  * of code in a constructor.
  */
 public SimplePicture() 
 {this(200,100);}
 
 /**
  * A Constructor that takes a file name and uses the file to create
  * a picture
  * @param fileName the file name to use in creating the picture
  */
 public SimplePicture(String fileName)
 {
   
   // load the picture into the buffered image 
   load(fileName);
   
 }
 
 /**
  * A constructor that takes the width and height desired for a picture and
  * creates a buffered image of that size.  This constructor doesn't 
  * show the picture.  The pixels will all be white.
  * @param width the desired width
  * @param height the desired height
  */
 public  SimplePicture(int width, int height)
 {
   bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
   title = "None";
   fileName = "None";
   extension = "jpg";
   setAllPixelsToAColor(Color.white);
 }
 
 /**
  * A constructor that takes the width and height desired for a picture and
  * creates a buffered image of that size.  It also takes the
  * color to use for the background of the picture.
  * @param width the desired width
  * @param height the desired height
  * @param theColor the background color for the picture
  */
 public  SimplePicture(int width, int height, Color theColor)
 {
   this(width,height);
   setAllPixelsToAColor(theColor);
 }
 
 /**
  * A Constructor that takes a picture to copy information from
  * @param copyPicture the picture to copy from
  */
 public SimplePicture(SimplePicture copyPicture)
 {
   if (copyPicture.fileName != null)
   {
      this.fileName = new String(copyPicture.fileName);
      this.extension = copyPicture.extension;
   }
   if (copyPicture.title != null)
      this.title = new String(copyPicture.title);
   if (copyPicture.bufferedImage != null)
   {
     this.bufferedImage = new BufferedImage(copyPicture.getWidth(),
                                            copyPicture.getHeight(), BufferedImage.TYPE_INT_RGB);
     this.copyPicture(copyPicture);
   }
 }
 
 /**
  * A constructor that takes a buffered image
  * @param image the buffered image
  */
 public SimplePicture(BufferedImage image)
 {
   this.bufferedImage = image;
   title = "None";
   fileName = "None";
   extension = "jpg";
 }
 
 ////////////////////////// Methods //////////////////////////////////
 
 /**
  * Method to get the extension for this picture
  * @return the extension (jpg, bmp, giff, etc)
  */
 public String getExtension() { return extension; }

 
 /**
  * Method that will copy all of the passed source picture into
  * the current picture object 
  * @param sourcePicture  the picture object to copy
  */
 public void copyPicture(SimplePicture sourcePicture)
 {
   Pixel sourcePixel = null;
   Pixel targetPixel = null;
   
   // loop through the columns
   for (int sourceX = 0, targetX = 0; 
        sourceX < sourcePicture.getWidth() &&
        targetX < this.getWidth();
        sourceX++, targetX++)
   {
     // loop through the rows
     for (int sourceY = 0, targetY = 0; 
          sourceY < sourcePicture.getHeight() && 
          targetY < this.getHeight();
          sourceY++, targetY++)
     {
       sourcePixel = sourcePicture.getPixel(sourceX,sourceY);
       targetPixel = this.getPixel(targetX,targetY);
       targetPixel.setColor(sourcePixel.getColor());
     }
   }
   
 }
 
 /**
  * Method to set the color in the picture to the passed color
  * @param color the color to set to
  */
 public void setAllPixelsToAColor(Color color)
 {
   // loop through all x
   for (int x = 0; x < this.getWidth(); x++)
   {
     // loop through all y
     for (int y = 0; y < this.getHeight(); y++)
     {
       getPixel(x,y).setColor(color);
     }
   }
 }
 
 /**
  * Method to get the buffered image
  * @return the buffered image 
  */
 public BufferedImage getBufferedImage() 
 {
    return bufferedImage;
 }
 
 /**
  * Method to get a graphics object for this picture to use to draw on
  * @return a graphics object to use for drawing
  */
 public Graphics getGraphics()
 {
   return bufferedImage.getGraphics();
 }
 
 /**
  * Method to get a Graphics2D object for this picture which can
  * be used to do 2D drawing on the picture
  */
 public Graphics2D createGraphics()
 {
   return bufferedImage.createGraphics();
 }
 
 /**
  * Method to get the file name associated with the picture
  * @return  the file name associated with the picture
  */
 public String getFileName() { return fileName; }
 
 /**
  * Method to set the file name
  * @param name the full pathname of the file
  */
 public void setFileName(String name)
 {
   fileName = name;
 }
 
 /**
  * Method to get the title of the picture
  * @return the title of the picture
  */
 public String getTitle() 
 { return title; }
 
 /**
  * Method to set the title for the picture
  * @param title the title to use for the picture
  */
 public void setTitle(String title) 
 {
   this.title = title;
   if (pictureFrame != null)
       pictureFrame.setTitle(title);
 }
 
 /**
  * Method to get the width of the picture in pixels
  * @return the width of the picture in pixels
  */
 public int getWidth() { return bufferedImage.getWidth(); }
 
 /**
  * Method to get the height of the picture in pixels
  * @return  the height of the picture in pixels
  */
 public int getHeight() { return bufferedImage.getHeight(); }
 
 /**
  * Method to get the picture frame for the picture
  * @return the picture frame associated with this picture
  * (it may be null)
  */
 public PictureFrame getPictureFrame() { return pictureFrame; }
 
 /**
  * Method to set the picture frame for this picture
  * @param pictureFrame the picture frame to use 
  */
 public void setPictureFrame(PictureFrame pictureFrame)
 {
   // set this picture object's picture frame to the passed one
   this.pictureFrame = pictureFrame;
 }
 
 /**
  * Method to get an image from the picture
  * @return  the buffered image since it is an image
  */
 public Image getImage()
 {
   return bufferedImage;
 }
 
 /**
  * Method to return the pixel value as an int for the given x and y location
  * @param x the x coordinate of the pixel
  * @param y the y coordinate of the pixel
  * @return the pixel value as an integer (alpha, red, green, blue)
  */
 public int getBasicPixel(int x, int y)
 {
    return bufferedImage.getRGB(x,y);
 }
    
 /** 
  * Method to set the value of a pixel in the picture from an int
  * @param x the x coordinate of the pixel
  * @param y the y coordinate of the pixel
  * @param rgb the new rgb value of the pixel (alpha, red, green, blue)
  */     
 public void setBasicPixel(int x, int y, int rgb)
 {
   bufferedImage.setRGB(x,y,rgb);
 }
  
 /**
  * Method to get a pixel object for the given x and y location
  * @param x  the x location of the pixel in the picture
  * @param y  the y location of the pixel in the picture
  * @return a Pixel object for this location
  */
 public Pixel getPixel(int x, int y)
 {
   // create the pixel object for this picture and the given x and y location
   Pixel pixel = new Pixel(this,x,y);
   return pixel;
 }
 
 /**
  * Method to get a one-dimensional array of Pixels for this simple picture
  * @return a one-dimensional array of Pixel objects starting with y=0
  * to y=height-1 and x=0 to x=width-1.
  */
 public Pixel[] getPixels()
 {
   int width = getWidth();
   int height = getHeight();
   Pixel[] pixelArray = new Pixel[width * height];
   
   // loop through height rows from top to bottom
   for (int row = 0; row < height; row++) 
     for (int col = 0; col < width; col++) 
       pixelArray[row * width + col] = new Pixel(this,col,row);
    
   return pixelArray;
 }
 
 /**
  * Method to get a two-dimensional array of Pixels for this simple picture
  * @return a two-dimensional array of Pixel objects in row-major order.
  */
 public Pixel[][] getPixels2D()
 {
   int width = getWidth();
   int height = getHeight();
   Pixel[][] pixelArray = new Pixel[height][width];
   
   // loop through height rows from top to bottom
   for (int row = 0; row < height; row++) 
     for (int col = 0; col < width; col++) 
       pixelArray[row][col] = new Pixel(this,col,row);
    
   return pixelArray;
 }
 
 /**
  * Method to load the buffered image with the passed image
  * @param image  the image to use
  */
 public void load(Image image)
 {
   // get a graphics context to use to draw on the buffered image
   Graphics2D graphics2d = bufferedImage.createGraphics();
   
   // draw the image on the buffered image starting at 0,0
   graphics2d.drawImage(image,0,0,null);
   
   // show the new image
   show();
 }
 
 /**
  * Method to show the picture in a picture frame
  */
 public void show()
 {
    // if there is a current picture frame then use it 
   if (pictureFrame != null)
     pictureFrame.updateImageAndShowIt();
   
   // else create a new picture frame with this picture 
   else
     pictureFrame = new PictureFrame(this);
 }
 
 /**
  * Method to hide the picture display
  */
 public void hide()
 {
   if (pictureFrame != null)
     pictureFrame.setVisible(false);
 }
 
 /**
  * Method to make this picture visible or not
  * @param flag true if you want it visible else false
  */
 public void setVisible(boolean flag)
 {
   if (flag)
     this.show();
   else 
     this.hide();
 }

 /**
  * Method to open a picture explorer on a copy (in memory) of this 
  * simple picture
  */
 public void explore()
 {
   // create a copy of the current picture and explore it
   new PictureExplorer(new SimplePicture(this));
 }
 
 /**
  * Method to force the picture to repaint itself.  This is very
  * useful after you have changed the pixels in a picture and
  * you want to see the change.
  */
 public void repaint()
 {
   // if there is a picture frame tell it to repaint
   if (pictureFrame != null)
     pictureFrame.repaint();
   
   // else create a new picture frame
   else
     pictureFrame = new PictureFrame(this);
 }
 
 /**
  * Method to load the picture from the passed file name
  * @param fileName the file name to use to load the picture from
  * @throws IOException if the picture isn't found
  */
 public void loadOrFail(String fileName) throws IOException
 {
    // set the current picture's file name
   this.fileName = fileName;
   
   // set the extension
   int posDot = fileName.indexOf('.');
   if (posDot >= 0)
     this.extension = fileName.substring(posDot + 1);
   
   // if the current title is null use the file name
   if (title == null)
     title = fileName;
   
   File file = new File(this.fileName);

   if (!file.canRead()) 
   {
     // try adding the media path 
     file = new File(FileChooser.getMediaPath(this.fileName));
     if (!file.canRead())
     {
       throw new IOException(this.fileName +
                             " could not be opened. Check that you specified the path");
     }
   }
   
   bufferedImage = ImageIO.read(file);
 }


 /**
  * Method to read the contents of the picture from a filename  
  * without throwing errors
  * @param fileName the name of the file to write the picture to
  * @return true if success else false
  */
 public boolean load(String fileName)
 {
     try {
         this.loadOrFail(fileName);
         return true;

     } catch (Exception ex) {
         System.out.println("There was an error trying to open " + fileName);
         bufferedImage = new BufferedImage(600,200,
                                           BufferedImage.TYPE_INT_RGB);
         addMessage("Couldn't load " + fileName,5,100);
         return false;
     }
         
 }

 /**
  * Method to load the picture from the passed file name
  * this just calls load(fileName) and is for name compatibility
  * @param fileName the file name to use to load the picture from
  * @return true if success else false
  */
 public boolean loadImage(String fileName)
 {
     return load(fileName);
 }
 
 /**
  * Method to draw a message as a string on the buffered image 
  * @param message the message to draw on the buffered image
  * @param xPos  the x coordinate of the leftmost point of the string 
  * @param yPos  the y coordinate of the bottom of the string  
  */
 public void addMessage(String message, int xPos, int yPos)
 {
   // get a graphics context to use to draw on the buffered image
   Graphics2D graphics2d = bufferedImage.createGraphics();
   
   // set the color to white
   graphics2d.setPaint(Color.white);
   
   // set the font to Helvetica bold style and size 16
   graphics2d.setFont(new Font("Helvetica",Font.BOLD,16));
   
   // draw the message
   graphics2d.drawString(message,xPos,yPos);
   
 }
 
 /**
  * Method to draw a string at the given location on the picture
  * @param text the text to draw
  * @param xPos the left x for the text 
  * @param yPos the top y for the text
  */
 public void drawString(String text, int xPos, int yPos)
 {
   addMessage(text,xPos,yPos);
 }
 
 /**
   * Method to create a new picture by scaling the current
   * picture by the given x and y factors
   * @param xFactor the amount to scale in x
   * @param yFactor the amount to scale in y
   * @return the resulting picture
   */
  public Picture scale(double xFactor, double yFactor)
  {
    // set up the scale transform
    AffineTransform scaleTransform = new AffineTransform();
    scaleTransform.scale(xFactor,yFactor);
    
    // create a new picture object that is the right size
    Picture result = new Picture((int) (getWidth() * xFactor),
                                 (int) (getHeight() * yFactor));
    
    // get the graphics 2d object to draw on the result
    Graphics graphics = result.getGraphics();
    Graphics2D g2 = (Graphics2D) graphics;
    
    // draw the current image onto the result image scaled
    g2.drawImage(this.getImage(),scaleTransform,null);
    
    return result;
  }
  
  /**
   * Method to create a new picture of the passed width. 
   * The aspect ratio of the width and height will stay
   * the same.
   * @param width the desired width
   * @return the resulting picture
   */
  public Picture getPictureWithWidth(int width)
  {
    // set up the scale transform
    double xFactor = (double) width / this.getWidth();
    Picture result = scale(xFactor,xFactor);
    return result;
  }
  
  /**
   * Method to create a new picture of the passed height. 
   * The aspect ratio of the width and height will stay
   * the same.
   * @param height the desired height
   * @return the resulting picture
   */
  public Picture getPictureWithHeight(int height)
  {
    // set up the scale transform
    double yFactor = (double) height / this.getHeight();
    Picture result = scale(yFactor,yFactor);
    return result;
  }
 
 /**
  * Method to load a picture from a file name and show it in a picture frame
  * @param fileName the file name to load the picture from
  * @return true if success else false
  */
 public boolean loadPictureAndShowIt(String fileName)
 {
   boolean result = true;  // the default is that it worked
   
   // try to load the picture into the buffered image from the file name
   result = load(fileName);
   
   // show the picture in a picture frame
   show();
   
   return result;
 }
 
 /**
  * Method to write the contents of the picture to a file with 
  * the passed name
  * @param fileName the name of the file to write the picture to
  */
 public void writeOrFail(String fileName) throws IOException
 {
   String extension = this.extension; // the default is current
   
   // create the file object
   File file = new File(fileName);
   File fileLoc = file.getParentFile(); // directory name
   
   // if there is no parent directory use the current media dir
   if (fileLoc == null)
   {
     fileName = FileChooser.getMediaPath(fileName);
     file = new File(fileName);
     fileLoc = file.getParentFile(); 
   }
   
   // check that you can write to the directory 
   if (!fileLoc.canWrite()) {
        throw new IOException(fileName +
        " could not be opened. Check to see if you can write to the directory.");
   }
   
   // get the extension
   int posDot = fileName.indexOf('.');
   if (posDot >= 0)
       extension = fileName.substring(posDot + 1);
   
   // write the contents of the buffered image to the file
   ImageIO.write(bufferedImage, extension, file);
     
 }

 /**
  * Method to write the contents of the picture to a file with 
  * the passed name without throwing errors
  * @param fileName the name of the file to write the picture to
  * @return true if success else false
  */
 public boolean write(String fileName)
 {
     try {
         this.writeOrFail(fileName);
         return true;
     } catch (Exception ex) {
         System.out.println("There was an error trying to write " + fileName);
         ex.printStackTrace();
         return false;
     }
         
 }
 
 /**
  * Method to get the directory for the media
  * @param fileName the base file name to use
  * @return the full path name by appending
  * the file name to the media directory
  */
 public static String getMediaPath(String fileName) {
   return FileChooser.getMediaPath(fileName);
 }
 
  /**
   * Method to get the coordinates of the enclosing rectangle after this
   * transformation is applied to the current picture
   * @return the enclosing rectangle
   */
  public Rectangle2D getTransformEnclosingRect(AffineTransform trans)
  {
    int width = getWidth();
    int height = getHeight();
    double maxX = width - 1;
    double maxY = height - 1;
    double minX, minY;
    Point2D.Double p1 = new Point2D.Double(0,0);
    Point2D.Double p2 = new Point2D.Double(maxX,0);
    Point2D.Double p3 = new Point2D.Double(maxX,maxY);
    Point2D.Double p4 = new Point2D.Double(0,maxY);
    Point2D.Double result = new Point2D.Double(0,0);
    Rectangle2D.Double rect = null;
    
    // get the new points and min x and y and max x and y
    trans.deltaTransform(p1,result);
    minX = result.getX();
    maxX = result.getX();
    minY = result.getY();
    maxY = result.getY();
    trans.deltaTransform(p2,result);
    minX = Math.min(minX,result.getX());
    maxX = Math.max(maxX,result.getX());
    minY = Math.min(minY,result.getY());
    maxY = Math.max(maxY,result.getY());
    trans.deltaTransform(p3,result);
    minX = Math.min(minX,result.getX());
    maxX = Math.max(maxX,result.getX());
    minY = Math.min(minY,result.getY());
    maxY = Math.max(maxY,result.getY());
    trans.deltaTransform(p4,result);
    minX = Math.min(minX,result.getX());
    maxX = Math.max(maxX,result.getX());
    minY = Math.min(minY,result.getY());
    maxY = Math.max(maxY,result.getY());
    
    // create the bounding rectangle to return
    rect = new Rectangle2D.Double(minX,minY,maxX - minX + 1, maxY - minY + 1);
    return rect;
  }
  
  /**
   * Method to get the coordinates of the enclosing rectangle after this
   * transformation is applied to the current picture
   * @return the enclosing rectangle
   */
  public Rectangle2D getTranslationEnclosingRect(AffineTransform trans)
  {
    return getTransformEnclosingRect(trans);
  }
 
 /**
  * Method to return a string with information about this picture
  * @return a string with information about the picture 
  */
 public String toString()
 {
   String output = "Simple Picture, filename " + fileName + 
     " height " + getHeight() + " width " + getWidth();
   return output;
 }

} // end of SimplePicture class

AP CSA Exam: Select 2015 Sample Questions


Multiple Choice [pages 17-60 (14-57) of Workshop Handbook]

  • # 7 (inheritance)

  • # 15* (polymorphism)

  • # 16* (recursion)

  • # 20 (challenging newer style)

  • # 23 (shuffle--see Elevens lab)

  • # 24 (arrays of arrays)

  • # 25* (selectionSort)


Free Response [page 53 (50), cononical solution on page 60 (57)]

  • #4 (1D and 2D array/matrix manipulation)

AP CSA Curriculum Module: Recursion [Workshop Workbook]

  • Activity 1: Introduction to the Concept of Recursion (definition and online resources) - pages 8-9

  • Activity 2: Identifying & Tracing Recursion via factorial & debugger - pages 11-13

  • Handouts 2 & 3: Multiple Choice Questions - pages 37-42

  • Handout 6: Recursion Quiz - page 48

Equity and Access Policy Statement


The College Board strongly encourages educators to make equitable access a guiding principle for their AP programs by giving all willing and academically prepared students the opportunity to participate in AP. We encourage educators to:

  • Eliminate barriers that restrict access to AP for students from ethnic, racial, and socioeconomic groups that have been traditionally underserved.

    Make every effort to ensure their AP classes reflect the diversity of their student population.

    Provide all students with access to academically challenging coursework before they enroll in AP classes

Only through a commitment to equitable preparation and access can true equity and excellence be achieved.


  • In small groups (4 or less):

    1. assign one person to read aloud the Equity & Access Policy Statement.
    2. assign one person to be the spokesperson to share one of the group's responses to the following discussion.
  • Discuss for a few minutes (5 or less) fairness and sensitivity issues such as:

    1. barriers to effective application of the statement at their schools.
    2. suggestions to overcome such challenges.