First off: avoid the algorithm and math problems. The one or two geeks in the class will love them, the rest of the class will be turned off from programming for the rest of their lives. I have a Ph.D. in CS and still hate those types of problems (ok, I have a love/hate relationship with those types of problems - i love them, but hate using them for pedagogical purposes).
That said, the single best intro to programming/software engineering project I had was a graphics programming project when we barely knew how to program. Our professor gave us a small library that had functions like "create_window()", "draw_rect()", "clear_screen()", "get_input()" and had us do a series of exercises that put objects on the screen, moved them around, and then refactored into our own graphics library. Some of the more advanced students made simple games.
From a software engineering perspective, this taught a number of important lessons early on:
- Code reuse/trusting third party code (we had a library for the complex stuff - if you can stop NIH syndrome before it starts, you've already won)
- User interfaces (we had to get some input from the user to decide what to draw)
- Event loops (software does not live in a vacuum, despite what the functional guys want you to believe ;) )
- Debugging/iterative development (no one's project worked the first time)
- Teamwork (do this as a team, have different members write different parts to learn how to interface with other programmers... save pair programming for later)
- Refactoring/code organization (how to recognize when you've wrote the same code for each shape and move that into a function)
- That you can do cool looking things easily with software (never underestimate the power of a graphics to get people excited about computers)
This was in 1992, so we used X windows on Sparc stations and wrote everything in C.
In 2016, here's how I'd do the same project:
- Stick with simple functions and introduce hash tables/dicts as a general purpose container. Don't do objects (esp in JS, since there are too many ways to do them)
- Provide a library that creates an SVG canvas (use this as the graphics area)
- Create a few related elements like a text box or buttons for controls and user input, but do this via your library
- Have a mechanism for callbacks/closures (don't tell them what they are yet and lose them, just show them how to use them)
- Do it entirely in the browser with a simple text editor (this is a development environment everyone has on their computer already, IDEs are a course on their own)
- Have some exercises that use the interactive developer interpreter
- For the advanced students, give them a library call for loading remote data and have them change their graphics in response to it
In addition to the stuff we learned, this also:
- Introduces the browser as a development/rapid prototyping platform
- Gives students a basic idea of how web content gets made
- Teaches some basic networking
- Gives the advanced students a platform to get creative with