I recently tried to solve this problem in my data structures and algorithms course. Four programming projects are assigned throughout the semester. Ideally, each project builds upon the previous project or at least reuses abstract data types. I decided to try programming projects for teams of two instead of individual projects. Working with others can be a terrific learning experience.
Students see other approaches to solving problems as well as different programming styles.
It also allows me to assign larger projects than one person could complete in a short amount of time. Exposure to more realistic projects in terms of scope and content is beneficial to students. During the semester I tried different approaches for assigning partners and for assessing grades. After each project I surveyed the students to find what they liked and disliked about the approaches. Based on their feedback I modified the approach for the next project.