Wednesday, October 19, 2011
DeMillo wrote this post for me already
I have been reading and enjoying Rich DeMillo's new book, Abelard to Apple: The Fate of American Colleges and Universities. I am planning to read the final chapter tonight and had intended to post a summary afterward. However, on his innovate-edu blog today, DeMillo posted his comments to the Joint Education Subcommittee of the Georgia Senate, and these provide an excellent summary of the book. This link will get you there.
Friday, October 7, 2011
Computer Science: It's not just for dead women
How ironic that today is Ada Lovelace Day, as I just took a picture of her out of a Computer Science Department display case this morning.
Since I came to Ball State, we had a display case that showed four images of women in computing. I did not snap a picture of the display case, but here are the four individual images.
On one hand, one could argue that these images show that women can succeed in computing. On the other hand, I think there's a good chance that a modern young woman who walks by these will come to the conclusions that women could succeed in computing, ... back before color photography and pants. That's not very relevant to a generation that has grown up with the Internet, social media, games, and service learning, four factors that have been identified that get girls interested in pursuing Computer Science.
I got the blessing from my department to update the display case, which now looks like this:
The plaques on the left and right are awards from the 2008 and 2011 CCSC:Midwest Programming Competitions, in which teams from Ball State placed second and third, respectively. In the middle is a research poster put together by the students who were involved in both the Morgan's Raid and the Digital Archaeology project. The poster describes how we used Scrum and principles of agile software development and the lessons learned in the process.
One wouldn't know to look at the plaques, but both teams comprised of two men and one woman. The genders of these students was irrelevant: their success speaks for itself. Taking a closer look at the poster, you can see that although the teams have a male majority, there are women there too.
This is not as flashy as the University of Washington's excellent Why CSE page, which overtly demonstrates how underrepresented groups can and do succeed in Computer Science and Engineering. However, it does show that—right here and now—women are integral parts of successful research and development projects. Whenever I meet with a prospective CS major, we walk by this display case. I am glad that now I can point to these pictures of some of our most successful majors and show how they are working hard, together, and that they are proud of their work.
After all, Computer Science is not just for dead women.
Since I came to Ball State, we had a display case that showed four images of women in computing. I did not snap a picture of the display case, but here are the four individual images.
On one hand, one could argue that these images show that women can succeed in computing. On the other hand, I think there's a good chance that a modern young woman who walks by these will come to the conclusions that women could succeed in computing, ... back before color photography and pants. That's not very relevant to a generation that has grown up with the Internet, social media, games, and service learning, four factors that have been identified that get girls interested in pursuing Computer Science.
I got the blessing from my department to update the display case, which now looks like this:
The plaques on the left and right are awards from the 2008 and 2011 CCSC:Midwest Programming Competitions, in which teams from Ball State placed second and third, respectively. In the middle is a research poster put together by the students who were involved in both the Morgan's Raid and the Digital Archaeology project. The poster describes how we used Scrum and principles of agile software development and the lessons learned in the process.
One wouldn't know to look at the plaques, but both teams comprised of two men and one woman. The genders of these students was irrelevant: their success speaks for itself. Taking a closer look at the poster, you can see that although the teams have a male majority, there are women there too.
This is not as flashy as the University of Washington's excellent Why CSE page, which overtly demonstrates how underrepresented groups can and do succeed in Computer Science and Engineering. However, it does show that—right here and now—women are integral parts of successful research and development projects. Whenever I meet with a prospective CS major, we walk by this display case. I am glad that now I can point to these pictures of some of our most successful majors and show how they are working hard, together, and that they are proud of their work.
After all, Computer Science is not just for dead women.
A new team's first Daily Scrum
We spent the first several weeks in my game programming class covering the basics and exploring two platforms for game development, Slick and Unity. On Monday, the eleven students decided that for their semester project, they would like to work on one big team to try porting Morgan's Raid to Unity. I decided to mentor the team using Scrum, since that has worked so well for me in the past. For Wednesday, I put together a product backlog and the team had its first spring planning meeting. While I had recommended that the students read The Scrum Primer, I got the distinct impression that the vast majority had not done so; in their defense, I had emailed the link Tuesday night.
The planning meeting went well, although fifty minutes was awfully tight to introduce the fundamentals of Scrum and to do the planning. I used my Scrum diagram as a reference to talk through the process. We were missing three of the eleven team members, but we were still able to get a reasonable number of stories committed for the first Sprint.
Today was the team's first "daily scrum." At 8am sharp, everyone was present. I told them to get into a circle and report what they had done since last time, what they had planned for next time, and what were the impediments. They got up and moved to the open area in the front of the classroom, while I stood behind the teaching station.
Here's where the team really surprised me. In using Scrum with students many times in the past, I have found that they find it challenging to report to each other, that they prefer to report to me. I wrote about how my Summer team was able to leverage the physical space to have productive Daily Scrums, but that team was half comprised of people experienced with Scrum, so their team-facing attitude was to be expected. This team of eleven had one student with Scrum experience (Tom), and the rest had none. They formed the circle and showed a few signs of anxiety, but Tom started right in with his daily status. He passed it on to the teammate by his side, and the whole stand-up meeting went as smoothly as one could hope.
There are four differences between this team and those from my past experiences, and I suspect that each is a contributor to this team's success. First and foremost, I learned a lot about managing a Scrum team through my experiences last academic year, and so I was more careful to separate myself from the stand-up meeting. Second, there was the issue of physical obstacles between me and the team: as with the Summer team, the furniture provided a convenient separation. Third, there was exactly one team member who had Scrum experience, and he showed no hesitation in starting the meeting and reporting progress to the team. Whether he meant to or not, his example provided the perfect template from which the other students intuited the expected social behavior. Fourth, all save one of these students have taken previous courses with me in which we repeatedly applied principles of agile development. We did not use Scrum in particular, but we discussed the philosophy and the implications as well as learning the practice through a six-week project in two deliverables.
I wish I had more data to support that last point. I would love to be able to claim that the students' experience in CS222 is a contributing factor to their ability to work in teams in upper-level courses, since that's one of the explicit goals of CS222. Unfortunately, the assessment data is not that rich. I mentioned three other contributing factors, and there are undoubtedly more. Still, it's anecdotal evidence that some combination of my teaching and the curriculum are working in tandem to improve student learning experiences.
The planning meeting went well, although fifty minutes was awfully tight to introduce the fundamentals of Scrum and to do the planning. I used my Scrum diagram as a reference to talk through the process. We were missing three of the eleven team members, but we were still able to get a reasonable number of stories committed for the first Sprint.
Today was the team's first "daily scrum." At 8am sharp, everyone was present. I told them to get into a circle and report what they had done since last time, what they had planned for next time, and what were the impediments. They got up and moved to the open area in the front of the classroom, while I stood behind the teaching station.
Here's where the team really surprised me. In using Scrum with students many times in the past, I have found that they find it challenging to report to each other, that they prefer to report to me. I wrote about how my Summer team was able to leverage the physical space to have productive Daily Scrums, but that team was half comprised of people experienced with Scrum, so their team-facing attitude was to be expected. This team of eleven had one student with Scrum experience (Tom), and the rest had none. They formed the circle and showed a few signs of anxiety, but Tom started right in with his daily status. He passed it on to the teammate by his side, and the whole stand-up meeting went as smoothly as one could hope.
There are four differences between this team and those from my past experiences, and I suspect that each is a contributor to this team's success. First and foremost, I learned a lot about managing a Scrum team through my experiences last academic year, and so I was more careful to separate myself from the stand-up meeting. Second, there was the issue of physical obstacles between me and the team: as with the Summer team, the furniture provided a convenient separation. Third, there was exactly one team member who had Scrum experience, and he showed no hesitation in starting the meeting and reporting progress to the team. Whether he meant to or not, his example provided the perfect template from which the other students intuited the expected social behavior. Fourth, all save one of these students have taken previous courses with me in which we repeatedly applied principles of agile development. We did not use Scrum in particular, but we discussed the philosophy and the implications as well as learning the practice through a six-week project in two deliverables.
I wish I had more data to support that last point. I would love to be able to claim that the students' experience in CS222 is a contributing factor to their ability to work in teams in upper-level courses, since that's one of the explicit goals of CS222. Unfortunately, the assessment data is not that rich. I mentioned three other contributing factors, and there are undoubtedly more. Still, it's anecdotal evidence that some combination of my teaching and the curriculum are working in tandem to improve student learning experiences.
Labels:
cs315,
learning,
morgan's raid,
scrum,
teaching
Thursday, October 6, 2011
UI classes should not implement event listener interfaces
When one does a rudimentary search for Swing tutorials, one finds approximately a zillion examples that recommend writing code like this:
The problem I want to focus in on is that
That's a little better, and if you followed the first, you can follow the second. Now, to the heart of the matter. While this works, I argue that it is not right. When we say that
That "works," in that when we press enter in the text field—which fires an
I've added a private inner class,
Now, there is no doubt that this specific behavior is tied to the button. Of course, if I had a need to replicate this behavior, I could make a named class or an Action object, but we can cross that bridge when we get there. Better to solve the problem at hand than one that may or may not come up later. Moving to an anonymous inner class provides with another interesting refactoring opportunity. I like to have as few fields in my objects as I can. Now that the text field is only ever accessed or manipulated from the constructor, I can pull it into a local variable rather than an instance variable. The only piece of Java magic required for this is that we have to make the field final so that it can be read from the inner class:
Nice and tidy, but more importantly, our PressMePanel is well-encapsulated.
Now, textbook and tutorial authors, you can stop making every class under the sun implement listener interfaces.
You're welcome.
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
/**
* A frame that holds a button which really wants to be pressed.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
public class PressMeFrame extends JFrame implements ActionListener {
/**
* Start the application.
*
* @param args
* command-line arguments (ignored)
*/
public static void main(String[] args) {
PressMeFrame frame = new PressMeFrame();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/** The uneditable text field into which we will put our output */
private JTextField outputField;
/**
* Create an instance of this class.
*/
public PressMeFrame() {
outputField = new JTextField(20);
outputField.setEditable(false);
JButton button = new JButton("Press me");
button.addActionListener(this);
Container contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
contentPane.add(button);
contentPane.add(outputField);
}
@Override
public void actionPerformed(ActionEvent arg0) {
outputField.setText("Thank you.");
}
}
The problem I want to focus in on is that
PressMeFrame implements ActionListener, but in truth, I can't stand looking at a class that extends JFrame when it doesn't have to. Do I really want to bind myself to JFrame right now? Not when I can just as easily make a reusable component that can be stuck into other things.
Let me start this again...
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* A frame that holds a button which really wants to be pressed.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
public class PressMePanel extends JPanel implements ActionListener {
/**
* Start the application.
*
* @param args
* command-line arguments (ignored)
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new PressMePanel());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/** The uneditable text field into which we will put our output */
private JTextField outputField;
/**
* Create an instance of this class.
*/
public PressMePanel() {
outputField = new JTextField(20);
outputField.setEditable(false);
JButton button = new JButton("Press me");
button.addActionListener(this);
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(button);
add(outputField);
}
@Override
public void actionPerformed(ActionEvent arg0) {
outputField.setText("Thank you.");
}
}
That's a little better, and if you followed the first, you can follow the second. Now, to the heart of the matter. While this works, I argue that it is not right. When we say that
PressMePanel implements ActionListener, we are making a bold statement: we are saying that every PressMePanel instance is designed to listen for action events. For example, we could make another class that uses PressMePanel, like this:
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* A panel for text entry.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
public class TextEntryPanel extends JPanel {
/**
* Start the application.
*
* @param args
* command-line arguments (ignored)
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TextEntryPanel());
frame.pack();
frame.setVisible(true);
}
public TextEntryPanel() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
PressMePanel pressMePanel = new PressMePanel();
JTextField textField = new JTextField(10);
textField.addActionListener(pressMePanel);
add(textField);
add(pressMePanel);
}
}
That "works," in that when we press enter in the text field—which fires an
ActionEvent—the message comes up in the PressMePanel. However, it doesn't really make sense. The interaction logic of PressMePanel is internal. It's simply not designed to be used in this way, but because it implemented ActionListener, this is perfectly legal.
Defensive coding practice dictates that we should prevent this kind of abuse if we can. We get much better encapsulation if, instead of having PressMePanel implement ActionListener, it creates its own delegate listeners. One easy way to do this is to create inner classes to handle it:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* A frame that holds a button which really wants to be pressed.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
public final class PressMePanel extends JPanel {
/**
* Start the application.
*
* @param args
* command-line arguments (ignored)
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new PressMePanel());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/** The uneditable text field into which we will put our output */
private JTextField outputField;
/**
* Create an instance of this class.
*/
public PressMePanel() {
outputField = new JTextField(20);
outputField.setEditable(false);
JButton button = new JButton("Press me");
button.addActionListener(new MyButtonListener());
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(button);
add(outputField);
}
/**
* Listens for action events, posting a message to the {@link #outputField}
* when this happens.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
private final class MyButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
outputField.setText("Thank you.");
}
}
}
I've added a private inner class,
MyButtonListener, which has one job: listen for action events and update the message in outputField when that happens. This is nicely encapsulated, and by making the class private, I'm not exporting it for potential abuse by other parts of the system. (Notice that I've also made both classes final. In the spirit of defensive programming, if I'm not designing for extension, I should prevent it.)
There's another design improvement to be made. By defining the MyButtonListener as a class, I can now make as many instances of it as I want. Yet, my semantic model is that there is really only one, and it's attached to the button. Notice that this is implied by the naming of the class. Let's use anonymous inner classes instead:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* A frame that holds a button which really wants to be pressed.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
public final class PressMePanel extends JPanel {
/**
* Start the application.
*
* @param args
* command-line arguments (ignored)
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new PressMePanel());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/** The uneditable text field into which we will put our output */
private JTextField outputField;
/**
* Create an instance of this class.
*/
public PressMePanel() {
outputField = new JTextField(20);
outputField.setEditable(false);
JButton button = new JButton("Press me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
outputField.setText("Thank you.");
}
});
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(button);
add(outputField);
}
}
Now, there is no doubt that this specific behavior is tied to the button. Of course, if I had a need to replicate this behavior, I could make a named class or an Action object, but we can cross that bridge when we get there. Better to solve the problem at hand than one that may or may not come up later. Moving to an anonymous inner class provides with another interesting refactoring opportunity. I like to have as few fields in my objects as I can. Now that the text field is only ever accessed or manipulated from the constructor, I can pull it into a local variable rather than an instance variable. The only piece of Java magic required for this is that we have to make the field final so that it can be read from the inner class:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* A frame that holds a button which really wants to be pressed.
*
* @author <a href="http://paulgestwicki.blogspot.com">Paul Gestwicki</a>
*/
public final class PressMePanel extends JPanel {
/**
* Start the application.
*
* @param args
* command-line arguments (ignored)
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new PressMePanel());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
* Create an instance of this class.
*/
public PressMePanel() {
final JTextField outputField = new JTextField(20);
outputField.setEditable(false);
JButton button = new JButton("Press me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
outputField.setText("Thank you.");
}
});
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(button);
add(outputField);
}
}
Nice and tidy, but more importantly, our PressMePanel is well-encapsulated.
Now, textbook and tutorial authors, you can stop making every class under the sun implement listener interfaces.
You're welcome.
Thursday, September 29, 2011
Students' reactions to the XP Episode
After giving them a brief introduction and experience with pair programming, I had my students read Engineer Notebook: An Extreme Programming Episode and write an essay response. I found a few of their comments particularly insightful, and so I'd like to share them here.
"I felt that most of the things my partner and I were doing was making statements, but the two Bobs thrive on asking questions."
"As students we tend to be focused entirely on what we know and what we can do that we don't sit down and realize that most of the people in our class can do the exact same thing."
"Respect is key to pair programming."
"I felt that most of the things my partner and I were doing was making statements, but the two Bobs thrive on asking questions."
"As students we tend to be focused entirely on what we know and what we can do that we don't sit down and realize that most of the people in our class can do the exact same thing."
"Respect is key to pair programming."
Wednesday, September 28, 2011
The words faculty use to describe their activities
I am on the university strategic planning committee. Over the course of the last several weeks, we have held many information gathering sessions with stakeholder groups, including faculty, students, parents, employers, and staff. Right now, my subcommittee is analyzing the data from two specific questions asked at the information gathering sessions:
- What did you learn about BSU over the last five years that you did not know before?
- If you could choose one area of focus that will have the greatest positive impact on the university, what would it be?
A few minutes ago, I finished my first pass through the responses, and this was my first attempt at open coding. Most of the data came from faculty sessions, and I was struck by how often the word "teaching" was used. Practically absent from their responses was any discussion of learning. The words faculty used to describe themselves and their activity matched exactly those words most commonly seen in promotion and tenure guidelines and annual reports: professors are obligated to do some amount "teaching."
Maybe I am reading too much into this, but it seems to belie a teacher-centric rather than learning-centric philosophy. I am reminded again of the advice of my colleagues, David Concepcion and Mahesh Daas: that the role of a professor is designer of learning experiences, and that to be a good teacher, one must be a humble learner.
The dean of my college, Michael Maggiotto, has been encouraging a transition from "teaching, research, and service" to "learning, scholarship, and engagement," as long as I have been here. At first, I dismissed this as simple alpha equivalence, and as potentially dangerous as it eschews the relationships among Boyer's four scholarships. However, reflecting on this in light of the data I just waded through, Maggiotto's approach may be a step in the right direction. The words we use shape the thoughts we think.
As an aside, I can't help but hope that I'm the first person to reference grounded theory and lambda calculus in the same post.
Monday, September 26, 2011
The Design Thinking Game
This morning in my game programming class, we started a short unit on game design. I brought in some prototyping materials and gave the students ten minutes to whip up a board game in the roll-and-move genre. This was inspired by Ian Schreiber's Game Design Concepts Level 1 activity and its primary purpose is to get students over the invisible barrier, "what if I cannot make a game?"
To explain what "design" is, I had started with a brief presentation of design thinking. Once I got the students started with the activity, I decided to sketch out a game as well. Glancing at the chalkboard, it struck me that the design thinking cycle could be modeled as a board game, so I made this:
The captions on the boxes are:- Empathy: an audience
- Identify: a problem
- Ideate: a solution
- Build: a prototype
- Test: a strategy
Each player starts at Empathy. Each turn, you roll a die and move that many spaces along the cycle. Grab a blank card and write down something that happens in that phase, using the caption to guide you. For example, my first turn, I rolled a three, and ended up on Build, so I made a build card, "Sketch." Then I rolled a two, putting me on Empathy, so I made an empathy card called, "Elderly." As soon as there is at least one card for each category, that player takes one card at random from each category and has to make narrative that explains how these five things fit together. I didn't get far enough in my own design process to decide on an initial scoring or elimination process, but I imagined that the other players would somehow score the story, and there would be a time or point threshold to trigger the end of the game.
That's it. A ten-minute game, most obviously inspired by design thinking, 1000 Blank White Cards, and Dixit. Is it fun? No, not really. You fly around the board and are forced to invent artifacts separated from any context, so you can only be very generic. Is it good? No, not really. It completely misses the point of design thinking, that you have to go through each phase to get to the next. So, why write it up here? It was actually a fun thought experiment. I used this ten-minute design exercise at the AIM conference a week ago, but I did not actually participate, I just observed. It was much more fun to actually get in and do it. I also enabled me then to present my flawed game design first, demonstrating the importance of metacognition, specifically learning from the process rather than judging the artifact too harshly.
Labels:
cs315,
design,
design thinking,
games,
teaching
Subscribe to:
Posts (Atom)






