What are some good programming challenges that encourage the use of Object Oriented programming?

I'm teaching myself how to program with hopes of getting a degree someday, and aside from acting on the occasional idea I have, I mostly am practicing with programming challenges online, from sites like Programming Praxis and Project Euler and CodingBat.

However, I find that most of the challenges are most easily and intuitively solved procedurally.

I have a loose understanding of the syntax and abstractions of classes (IE a class can inherit from another class, and many instances can be made from a class and each can have their own attributes, etc), but I haven't really found anything to do that calls for them. When I have programmed classes, they're usually just small ones that don't deal with inheritance and are mostly used for encapsulating problems that have a large number of variables and methods.

I feel like I learn best about programming concepts by using them, so what type of program can I make or problem can I solve to get familiar with object oriented programming? If it matters, I tend to code in Python, but I also know some Java.

Video games tend to map well to object oriented programming, from old-school, simpler games like Asteroids, Space Invaders, galaga, defender/stargate, that sort of thing, all the way up to modern 3d fps's. Start with something on the simpler end of the scale like asteroids or space invaders, or pong.

Typically a video game like these will have some main loop that does something like:

do {

sample player input.
move everything
draw everything;
wait long enough so that we go through this loop
x times per second, no faster, no slower, with x typically 30 or 60.

} while not done;

All of the various "things" that are "moved" and "drawn" will be members (or more likely inherit from) a class of things that move and can be drawn, but may override the move and draw methods.posted by smcameron at 1:05 PM on October 27, 2011

Programming challenges are by and large algorithmic challenges, not design challenges. If you want to flex your design muscles, you're better off picking a project (make a simple game, make a simple utility, Sudoku solver, Monopoly simulation, etc.) than a problem.

Don't forget that OOP is just another abstraction, not the best or only abstraction. OOP dogmatism can easily become a hindrance, not a help.posted by wrok at 1:07 PM on October 27, 2011 [3 favorites]

Contests! Here is a genomics-themed problem that is interesting to me at the moment. Each data unit is abstract-able into an object with its own attributes and methods, and you'll definitely learn inheritance from abstracting three sub-formats of the data in question. The money is a nice motivator (as much as a getting a publication out of it).posted by Blazecock Pileon at 1:10 PM on October 27, 2011

In my observation, OOP tends to fit best in niches, and only parts of it apply to each niche. The focus on collecting bits of data into units fits reasonably well with databases. Inheritance and extension plays a large role in GUI designs: you extend the base objects with your business logic and bam, application. The proliferation of types makes a lot of sense for compilers: what code you generate depends on what basic block you're working with.

You might want to pick up the Design Patterns book, as it gives a lot of ideas for how one can use OOP to simplify rather than complicate.posted by pwnguin at 1:39 PM on October 27, 2011

This is from Nerd Ranch's iPhone book. But the design philosophy for iPhone development was MVC (model-view-controller). The model layer handled data storage. The view layer handled GUIs and presentation. The controller layer was the brains of the application. What was noticed was that the model layer lent itself to object oriented programming, and the view layer lent itself to object oriented programming, but the controller layer did not.

Java has a LinkedList and an ArrayList. Rather than needing to design object methods that handled doSomething(LinkedList a), and doSomething(ArrayList a), the doSomething method would be written as doSomething(List a) where java.util.List is the parent class/interface of both LinkedList and ArrayList.posted by DetriusXii at 1:44 PM on October 27, 2011

Write a simple engine for interactive fiction. Think about rooms, transparent windows between rooms, doors, things you can put in other things, things that can contain other things, things that can be put on top of others things, things that are in a room but out of reach, a working subway system. Keep your parser dead crude or you'll end up distracted.posted by Zed at 1:58 PM on October 27, 2011

Build a non-trivial website with Django, which relies on Python. You'll get the object oriented side via the model portion of the MVC equation, and as a bonus, you'll pick up the Model-View-Controller paradigm as well.posted by fatbird at 2:00 PM on October 27, 2011 [1 favorite]

Truckin was an OOP learning tool back in the day. The language you choose will have to support multiple inheritance.posted by Runes at 8:40 PM on October 27, 2011

I decided to try making a basic recipe analysis program, where each ingredient is an object with methods so you can convert its unit to grams. Then it gets owned by an instance of a recipe object, which contains ingredients, instructions, etc, and determines the ratio of each ingredient by mass (which is useful for baking).

Since it's fairly simple, it does feel a tad contrived compared to using a dictionary for each ingredient, but I can see how it scales nicely to crank out objects from the class, and the benefits of combining data with procedures.

It doesn't really incorporate inheritance, though, which is a concept I only seem to get in the abstract (yes, dogs are a type of animal, and corgis are a type of dog, but I don't really seem to quite follow how to build or use that hierarchy effectively yet). There was an example in a programming book I read that expanded on lists with a class, so I might go back to that.posted by mccarty.tim at 6:31 AM on October 28, 2011

To give you an example of how we use inheritance at my job, we have a system that pushes data into lots of other systems. Two such systems are of interest: LDAP and Active Directory. AD has an LDAP server, but some of the stuff cannot be accessed in the traditional way so we have a web service to access it. The client, aka the software that pushes into AD, extends the LDAP object. It overrides the constructor to change the destination and a few specific methods for creating and managing accounts.

In your recipe example, you could actually represent the steps in the process as objects. In that case you'd need to be able to represent not only eggs, butter and sugar, but also the results of each step. If you want to handle any recipe you might encounter, it would be difficult to make a series of 'batter' objects. So you might have an Ingredient class that your basic leaf classes inherit from, and a Mixture class that is an ingredient, but implemented as a weighted set of ingredients. Then you can have mixtures of mixtures, and Mixtures of mixtures with basic ingredients and so on.posted by pwnguin at 7:07 AM on October 28, 2011

Don't try to force inheritance, which is less important nowadays than it use to be. A common heuristic in OOP is "favour composition over inheritance", and this comes from decades of experience where large projects would create vast inheritance trees to give everything a nice ontological place--only to find that the resulting software was incredibly brittle and hard to modify because of the overwhelming inheritance structure.

Instead of thinking "what should inherit from what", think of polymorphism: What should I be able to use as what? There are other types of polymorphism than inheritance (e.g., mixins), and mastering the more general idea will be more useful going forward.posted by fatbird at 7:12 AM on October 28, 2011

To expand on your example, Corgi and Husky are both a subclass of Dog, and the Dog class, which is a subclass of the Mammal class, implements NumberOfLegs as 4, so Corgie and Husky classes don't reimplement the NumberOfLegs function. The Human class implements NumberOfLegs differently.

In a kitchen/cooking/recipe program, you could have a Pan class, BakingPan inherits from that, and there's CakePan and CupcakePan classes that inherit from BakingPan. The Pan class has a CanBePutInOven attribute that BakingPan answers; CakePan and CupCakePan implement VolumeOfBatterNeeded differently enough to justify having a separate class. (Perhaps more suited for a kitchen inventory program, but hopefully you get the idea.)

Yeah, the Dog example is a bit contrived because we don't expect a global event to happen that causes NumberOfLegs on a Corgi to change but in business there can be unforeseen but fundamental changes and the idea is that OOP is a vehicle to making changes (but as noted by fat bird this is only an ideal, and 'mixin's are finding favor - at least in the circles I run in).

GUI programming is often a good way to literally see hierarchies - the base screen element is a resizable area. TextInput and Button both inherit from that resizable element. For multiple inheritance, there's ToggleButton and RadioButton which both inherit from Button so they can share 'clickability' but they implement different behavior.posted by fragmede at 9:45 AM on October 28, 2011

Tags

Share

About Ask MetaFilter

Ask MetaFilter is a question and answer site that covers nearly any question on earth, where members help each other solve problems. Ask MetaFilter is where thousands of life's little questions are answered.