Day 14

For next time

Today

MP3 survey

We used the results of previous surveys to form MP4 partner pairs for today. We’ll use the results of this post-MP3 survey to respond to your feedback as best we can on a rolling basis and when we form Final Project Teams. When you are done with MP3, and have had a moment to sleep (we know that our assignments keep rolling, but we do expect that you know when to call it a night), please fill out the Post-MP3 survey.

MP4: Interactive Programming

See who you are partnered with on this MP4 partner and studio list. Take a moment to find the partner(s) and sit with them for the rest of this class - all in AC326 today, but in the studio listed after Spring Break.

With your partner(s), discuss the issues raised in the “Getting Started” section. Bring course staff into your conversation as desired.

After you’ve come to a shared understanding, start generating project ideas and working on your written proposal (due at 9:00 AM tomorrow as a Canvas submission).

If your partner was unable to make it to today’s class session, you will set up and host the repo from your account. The proposal that you add to the repo and submit a link for on canvas can include up to three ideas for a project. Submitting more than one idea can get you instructor feedback on more than one possible MP4 direction. You can then discuss these possible directions with your partner when they are able to meet. If possible, this meeting should happen before Friday’s class.

The Model-View-Controller (MVC) Pattern

Throughout this course, there are implementation techniques that you have learned and applied in different contexts. For example, you have created and iterated over a list to do things like find a maximum value, process a series of files, or to read and write a dictionary. Many implementation tasks often decompose into sub-problems that can often be solved by applying a pattern you have seen before.

Similarly, when thinking about the design of larger programs, there are patterns that you can learn to recognize and apply. As this description would suggest, we call these design patterns. The world of object-oriented programming uses design patterns quite often, and these patterns often provide helpful templates to structure your classes and their methods.

In interactive software and user interface design, the Model-View-Controller (MVC) pattern is common. In short, MVC separates the design of a system into three components:

Here is a graphical representation of the MVC components and their interactions with the user:

a graph of the interactions in the model-view-controller design pattern

When done well, MVC makes it easy to reason about what can change the state of the system (the controller) and what can read the state of the system (the view). The relatively intuitive separation of tasks also makes the design modular: components can be easily swapped out for others that do a similar task. For example, two different views and controllers can be used to interact with the same system model, one on a desktop and one on a phone or tablet.

Because this mini-project focuses on interactive computing, we think the MVC pattern is particularly well-suited for your tasks, and we’d like you to spend some time practicing designing software that follows this pattern.

To help get you started, here’s an example of how MVC could be used for a code editor, like Atom:

It’s important to remember that design patterns are about the structure, and may leave some details unclear. For example, in the above design, should the font be part of the model or the view? It depends, and you could make a well-reasoned case for either one.

Now, you can try coming up with a similar design for an interactive graphical game.

MVC Pac-Man

Take a few minutes to think about how the game Pac-Man could be designed according to the MVC pattern. What would the model, view, and controller contain or do?

Once you have answered these questions, try to translate that design into classes, functions, and variables in Python. Try not to look ahead until you’ve gotten the chance to write your thoughts down.

Here are some classes that we came up with that you might use to implement a Pac-Man clone:

(The last class in the above list is specific to a certain Python library that follows this framework.)

There are many ways to implement Model-View-Controller, so this is not the only way to operationalize Model-View-Controller in the context of Pac-Man. Remember, this is not the only way to structure your object-oriented design (code that uses classes), but we hope it will be helpful at least as a jumping off point.

Other possible MVCs

With your partner, revisit one of the project ideas that you discussed. Try to think about what a model of that project might contain. What would be some of the controls in a controller class? The teaching team will be available throughout the studio time to ask questions about this.

Git merge conflicts

Today is a great day to sharpen your understanding of how working on code with someone else in the same repo can bring you great joy and great pain. Below, you’ll find exercises and examples that help you prepare to avoid or resolve situations that arise when partner pushes modifications to the same file.

When this happens, you need to go through a process to decide how to blend these changes together into a single new version. Read about resolving merge conflicts.

Exercise: resolving merge conflicts

Let’s create a merge conflict so we can practice resolving it. Follow along with these commands and try it yourself. We’re going to do everything locally, but you can imagine that repo1 and repo2 belong to you and your partner on separate machines - everything works the same way.


# Create new Git repository and commit a file
$ mkdir repo1
$ cd repo1/
$ git init
$ echo -e "Knock knock\nWho's there?" > joke.txt
$ git add joke.txt
$ git commit -m "Add joke setup"

# Clone the repo (simulating a partner)
$ cd ..
$ git clone repo1/ repo2
$ cd repo2

# Make a change in both repos simultaneously (merge conflict)
$ cd ../repo1/
$ echo "Interrupting cow" >> joke.txt
$ git commit -a -m "Cows are always funny"
$ cd ../repo2/
$ echo "Banana" >> joke.txt
$ git commit -a -m "Fruit-based jokes are the best"

So now we’ve got a merge conflict brewing. Two copies of the repository started from the same commit (the joke setup) but made diverging changes. Let’s see what that looks like, and how to resolve it:

# From within repo2:
$ git pull origin master
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/ben/merge_example/repo1
 * branch            master     -> FETCH_HEAD
   b056309..2d02106  master     -> origin/master
Auto-merging joke.txt
CONFLICT (content): Merge conflict in joke.txt
Automatic merge failed; fix conflicts and then commit the result.

Here Git is attempting to merge the two repository contents automatically for you. Many times it can do so successfully (e.g. if you have each changed different files, it will merge by creating a commit that has both of your changes). But in this case, we’ve edited the same part of the same file, so a choice must be made by a human about what should stay and what should go.

At this point, the contents of joke.txt in repo2 look like this:

Knock knock
Who's there?
<<<<<<< HEAD
Banana
=======
Interrupting cow
>>>>>>> 2d0210609e38d9f38bb48d8a77fbf57c3d05d15c

Git has inserted these markers around the two choices that need to be resolved. We fix the merge conflict by choosing one of the options, removing the other option and the marker lines (<<..., ==..., and >>...), and then committing the file.

You can use any text editor you like to do this, but Atom is particularly nice since it is aware of how git works (you can actually do everything including writing commit messages within Atom, feel free to explore on your own). If you open the conflicted file in Atom, it presents you with buttons like this:

Clicking one of them automatically performs the edits described above. With those changes made and saved, the last step is to commit the merge:

$ git add joke.txt
$ git commit -m "Resolved merge conflict (cows rule)"

At this point the merge conflict is resolved in repo2. In your actual workflow you would then want to push the merge resolution commit to a shared location, so that repo1 can pull it and both partners can work from a common history again.

So: merge conflicts are nothing to be afraid of, but they certainly are annoying. Some concrete suggestions for avoiding merge conflicts

Going Beyond: Git branches

What is the “master” in git push origin master? It’s the name of a branch!

Developers often use branches to work on a new feature (without halting ongoing development on the master branch). Then once the feature is complete and tested, they can merge it back into master.

To see this visually, work through the first three levels of “Learn Git Branching