Related
When I was first started teaching myself programming, after finishing a tutorial I would feel like I still couldn't do anything in the language. So, I looked around to find something to work on. Since I had just learned a few of the basics, the amount of work involved in finding, reading and adding to an open source project seemed insurmountable. Instead I started on a couple toy projects, which ended up being incredibly beneficial.
Having seen a lot of questions from beginners similar to "what should I do now?" and a lot of answers similar to "start working for an open source project" has made me think there has to be better advice for a new programmer. While working on an open source project surely gives great experience, there is a perceptible barrier to entry.
Instead, I think it would be great if new programmers were prodded towards working on a toy program related to some interest they have. Since there are so many directions that programming can take you, I think it would be interesting to list some simple (but fun/rewarding) projects grouped by the direction the new programmer is looking to pursue. Such as:
Game Design:
Write a text adventure (like Zork)
Natural Language Processing:
Create a program that writes meaningless, but grammatically valid essays.
I recently asked a similar question (Diverse resource of problems to show merits of different languages) and got links to sites that provide problem sets, as well as validation. Check out:
http://www.codechef.com/
https://www.spoj.pl/problems/classical/
http://wiki.python.org/moin/ProblemSets
http://projecteuler.net/
Although these problems don't oftem amount to projects, they are still interesting. I'm interested in seeing what people come up with here.
I actually think that a TopCoder approach might be better... programmers can still pick topics of interests, but they're actually working for a prize on a REAL project and they get feedback. Frankly speaking, TopCoder is a bit of a bloat and as far as I can tell, they don't allow people to make free competitions. It would be great if there is a TopCoder/StackOverflow type of site: people can submit code, get voted on their implementation and just have a good time!
I'll even pitch my idea, I'm starting to work on my own version of TopCoder/StackOverflow hybrid monstrosity called MyDevArmy (although I have not done anything so far except buy the domain).
Write a program which renders Wolfram automata (esp. Rule 110).
See YelloSoft for example code.
Start by writing a Blackjack simulation. Choose whichever strategy you want for the first run.
Next, start adding additional runs for different strategies like hitting/standing when your hand's value is 15 vs. 16 vs. 17 vs. 18, and whether the hand is soft or hard (an ace's value being counted as 1 or 11). The dealer's strategy will be constant, as they really are in casinos.
By the end, your program will run, say, 1000 instances of each strategy combination. It will print out a summary of the rate of hand wins (percentage of times you beat the dealer) for each stand value and hard/soft combination.
This is easily one of my favorite projects I've done and it can really cement some techniques in the language of your choosing. Plus, if you have the initiative to start learning some of the (fairly simple) discrete math that's involved in coming up with the odds of these situations as a side project, you can come away with an even better experience. Who knows, maybe you could ditch this computer stuff and take up card counting?
I've decided to get some experience working on some project this summer.
Due to local demand on market I would prefer to learn Java (Standard and Enterprise Editions).
But I can't even to conjecture what kind of project to do. Recently I had some ideas about C. With C I could to contribute to huge Linux projects. I don't mean that my work will be surely commited. I could get the code and practice with it. But C it's not right thing to get good job in my area. In case of JavaSE there is a chance to develop some desktop applications. But thinking about JavaEE I get stuck. I'll be very thankful for answers.
CodingBat.com will give you good core Java practice.
Project Euler is still the best for all around practice. You can use whatever language you'd like to solve the problems there.
For actual projects, I almost always start on something easy like a Twitter client. It gets you exposure to all the basics along with UI and network communication. You can work up from there. Just don't start with something so overwhelming that you can't figure it out and want to give up. That's not going to get you anywhere.
The best advice is: work on a project that you have personal interest in. Something based on your hobbies, maybe.
If that doesn't work, make a blogging / CMS engine. Or an online photo album. Or an eStore. The world doesn't really need another of any of these things, but it will give you some good practical experience with JavaEE.
Another benefit of "re-inventing the wheel" (for learning) is that you have probably already used systems like these described above, and you have a good idea of how it can work, and maybe you have your own ideas of how it could work better. That can make requirements much simpler, and also will give you a sort of benchmark so you can see how close you can come to building a tool like the "real" ones out there. And if yours is really great, well, maybe release it and see what happens. ;)
There are many Java-based projects on SourceForge. Tinker with one you find interesting.
I've implemented either a betting pool or a Baccarat game in almost every language I've
learned.
This type of software covers:
Dates and times, with calculations
Currency types and things that can be converted to and from currency.
A discrete set of rules that is easy to test
States, transition between states and multiple entities responsible for state transition
Multiple users with different views of the same model End conditions
Multiple player blackjack and poker would work also.
One caveat is that in my day job I work on financial systems and there is a huge overlap
between things to consider when writing a multiplayer game of chance and a trading system.
build an address book. the concept is simple, so you're not stuck on "what" to write. You can focus on learning your chosen language. You get experience in working with a database, java ( insert any language here), and UI design.
when you decide to learn another language you can create the same thing. Since the database has been created already, you can focus on the language itself.
the concept of inputting data, storing data, and retrieving data is central to a lot of applications.
Have a look around http://openhatch.org/ for a project that sounds interesting.
I might be doing a coding competition soon, I was wondering if anyone made one and what where the guidelines/ process.
I'd like to make the competition appealing to all devs, and I m trying to come up with ideas as to how.
the scenario is: There is an event running and we(of the coding competition) will have a room that we can use (either to code or for questions, etc), however, ideally the task for the competition should be assignet and they should eb able to go and do other things, if they are so inclined.
what i wonder is what kind of challenges to give, and most importantly, what is the criteria to "win" teaching and learning good coding standards takes a looong time, and I d like to think that if you ve been coding for longer you ll do things right and quick... but in a competition, you would be cutting corners...
I would really appreciate your input on this
A competition that's appealing to all devs? That sounds... difficult. But if you want to make the competition about problem solving and algorithms, then I am a big fan of the Sphere Online Judge. Basically this is a repository of programming puzzles but you can also become a problem setter and create problems or contests on the site.
It supports a huge number of programming languages, from the "popular" ones to more obscure ones. Programs will typically read from standard in, and write to standard out. The standard judge program will simply diff a program's output with the expected output, but more elaborate judges are possible. You also set a time limit for the execution of submissions, which usually requires programmers to be more clever than brute force.
Winner is whoever solved the most problems. Ties are broken by time of correct submissions, with some time penalty for wrong submissions.
Guidelines
Limit the languages which can be submitted. If you don't, you may get proprietary languages which require a special purchased compiler or some other inconvenience.
Correctness
This is easy. Provide an easy-to-read unit test in all languages you will accept. This will allow simple, automatic testing of submissions, and will guide the interface of the solution.
Challenges
Create a theme. Make it focused, but not too specific as to require certain paradigms or language features. Then develop challenges based around that theme.
Assign points to each challenge. Give more points to more difficult problems. Be sure to review each challenge carefully and have a team attempt them before giving points so you can make a more accurate decision.
As #miorel mentioned in his answer, time limits and memory limits are wonderful. Set a time limit per test per challenge, or at least monitor them and have these metrics contribute to the points given for solving the problem.
You should look at the ACM competition. Each year they have collegiate programming competitions. These are language agnostic. The archive is located here.
http://www.ntnu.edu.tw/acm/
To start improve yourself, you need a project you can work on, a problem you want to solve, something you want to achieve. Without any context and a destination you want to end, you won't be able to learn all the necessary methods and all the connections of a language.
There is a competition, taking place 2 times a year, it is called ludum dare.
It also doesn't matter which language you are writing, you just have to create a game within 48h ( compo, just one person and all assets created by yourself ) and 72h ( jam, a team working together, can purchase assets ). After the competition when every uploaded his game, the voting starts. This will take like 20 days where everybody can upvote your game or you can upvote other peoples' games. There are taking part approximately 3000 people.
Every time the competition starts, there is a voting on 5 days in sequence. Everyday you vote on a set of themes which can be possibly the theme you will have to create a game for. My last competition had the theme "unconventional weapon". After the voting ended, the competition starts and you have to think about a game with (in my case ) an unconventional weapon and start coding a game you like.
This is not about being the best, you should start looking at other peoples projects after the competition ended. You can learn a lot of other people, ways they solve their problem and I am sure you would improve your self every time taking place in such a contest.
It's gonna be hard to designed a coding competition suitable for a wide array of languages, since languages typically serve different purposes. I'd suggest that what you're looking for doesn't exist.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
One thing I struggle with is planning an application's architecture before writing any code.
I don't mean gathering requirements to narrow in on what the application needs to do, but rather effectively thinking about a good way to lay out the overall class, data and flow structures, and iterating those thoughts so that I have a credible plan of action in mind before even opening the IDE. At the moment it is all to easy to just open the IDE, create a blank project, start writing bits and bobs and let the design 'grow out' from there.
I gather UML is one way to do this but I have no experience with it so it seems kind of nebulous.
How do you plan an application's architecture before writing any code? If UML is the way to go, can you recommend a concise and practical introduction for a developer of smallish applications?
I appreciate your input.
I consider the following:
what the system is supposed to do, that is, what is the problem that the system is trying to solve
who is the customer and what are their wishes
what the system has to integrate with
are there any legacy aspects that need to be considered
what are the user interractions
etc...
Then I start looking at the system as a black box and:
what are the interactions that need to happen with that black box
what are the behaviours that need to happen inside the black box, i.e. what needs to happen to those interactions for the black box to exhibit the desired behaviour at a higher level, e.g. receive and process incoming messages from a reservation system, update a database etc.
Then this will start to give you a view of the system that consists of various internal black boxes, each of which can be broken down further in the same manner.
UML is very good to represent such behaviour. You can describe most systems just using two of the many components of UML, namely:
class diagrams, and
sequence diagrams.
You may need activity diagrams as well if there is any parallelism in the behaviour that needs to be described.
A good resource for learning UML is Martin Fowler's excellent book "UML Distilled" (Amazon link - sanitised for the script kiddie link nazis out there (-: ). This book gives you a quick look at the essential parts of each of the components of UML.
Oh. What I've described is pretty much Ivar Jacobson's approach. Jacobson is one of the Three Amigos of OO. In fact UML was initially developed by the other two persons that form the Three Amigos, Grady Booch and Jim Rumbaugh
I really find that a first-off of writing on paper or whiteboard is really crucial. Then move to UML if you want, but nothing beats the flexibility of just drawing it by hand at first.
You should definitely take a look at Steve McConnell's Code Complete-
and especially at his giveaway chapter on "Design in Construction"
You can download it from his website:
http://cc2e.com/File.ashx?cid=336
If you're developing for .NET, Microsoft have just published (as a free e-book!) the Application Architecture Guide 2.0b1. It provides loads of really good information about planning your architecture before writing any code.
If you were desperate I expect you could use large chunks of it for non-.NET-based architectures.
I'll preface this by saying that I do mostly web development where much of the architecture is already decided in advance (WebForms, now MVC) and most of my projects are reasonably small, one-person efforts that take less than a year. I also know going in that I'll have an ORM and DAL to handle my business object and data interaction, respectively. Recently, I've switched to using LINQ for this, so much of the "design" becomes database design and mapping via the DBML designer.
Typically, I work in a TDD (test driven development) manner. I don't spend a lot of time up front working on architectural or design details. I do gather the overall interaction of the user with the application via stories. I use the stories to work out the interaction design and discover the major components of the application. I do a lot of whiteboarding during this process with the customer -- sometimes capturing details with a digital camera if they seem important enough to keep in diagram form. Mainly my stories get captured in story form in a wiki. Eventually, the stories get organized into releases and iterations.
By this time I usually have a pretty good idea of the architecture. If it's complicated or there are unusual bits -- things that differ from my normal practices -- or I'm working with someone else (not typical), I'll diagram things (again on a whiteboard). The same is true of complicated interactions -- I may design the page layout and flow on a whiteboard, keeping it (or capturing via camera) until I'm done with that section. Once I have a general idea of where I'm going and what needs to be done first, I'll start writing tests for the first stories. Usually, this goes like: "Okay, to do that I'll need these classes. I'll start with this one and it needs to do this." Then I start merrily TDDing along and the architecture/design grows from the needs of the application.
Periodically, I'll find myself wanting to write some bits of code over again or think "this really smells" and I'll refactor my design to remove duplication or replace the smelly bits with something more elegant. Mostly, I'm concerned with getting the functionality down while following good design principles. I find that using known patterns and paying attention to good principles as you go along works out pretty well.
http://dn.codegear.com/article/31863
I use UML, and find that guide pretty useful and easy to read. Let me know if you need something different.
UML is a notation. It is a way of recording your design, but not (in my opinion) of doing a design. If you need to write things down, I would recommend UML, though, not because it's the "best" but because it is a standard which others probably already know how to read, and it beats inventing your own "standard".
I think the best introduction to UML is still UML Distilled, by Martin Fowler, because it's concise, gives pratical guidance on where to use it, and makes it clear you don't have to buy into the whole UML/RUP story for it to be useful
Doing design is hard.It can't really be captured in one StackOverflow answer. Unfortunately, my design skills, such as they are, have evolved over the years and so I don't have one source I can refer you to.
However, one model I have found useful is robustness analysis (google for it, but there's an intro here). If you have your use-cases for what the system should do, a domain model of what things are involved, then I've found robustness analysis a useful tool in connecting the two and working out what the key components of the system need to be.
But the best advice is read widely, think hard, and practice. It's not a purely teachable skill, you've got to actually do it.
I'm not smart enough to plan ahead more than a little. When I do plan ahead, my plans always come out wrong, but now I've spend n days on bad plans. My limit seems to be about 15 minutes on the whiteboard.
Basically, I do as little work as I can to find out whether I'm headed in the right direction.
I look at my design for critical questions: when A does B to C, will it be fast enough for D? If not, we need a different design. Each of these questions can be answer with a spike. If the spikes look good, then we have the design and it's time to expand on it.
I code in the direction of getting some real customer value as soon as possible, so a customer can tell me where I should be going.
Because I always get things wrong, I rely on refactoring to help me get them right. Refactoring is risky, so I have to write unit tests as I go. Writing unit tests after the fact is hard because of coupling, so I write my tests first. Staying disciplined about this stuff is hard, and a different brain sees things differently, so I like to have a buddy coding with me. My coding buddy has a nose, so I shower regularly.
Let's call it "Extreme Programming".
"White boards, sketches and Post-it notes are excellent design
tools. Complicated modeling tools have a tendency to be more
distracting than illuminating." From Practices of an Agile Developer
by Venkat Subramaniam and Andy Hunt.
I'm not convinced anything can be planned in advance before implementation. I've got 10 years experience, but that's only been at 4 companies (including 2 sites at one company, that were almost polar opposites), and almost all of my experience has been in terms of watching colossal cluster********s occur. I'm starting to think that stuff like refactoring is really the best way to do things, but at the same time I realize that my experience is limited, and I might just be reacting to what I've seen. What I'd really like to know is how to gain the best experience so I'm able to arrive at proper conclusions, but it seems like there's no shortcut and it just involves a lot of time seeing people doing things wrong :(. I'd really like to give a go at working at a company where people do things right (as evidenced by successful product deployments), to know whether I'm a just a contrarian bastard, or if I'm really as smart as I think I am.
I beg to differ: UML can be used for application architecture, but is more often used for technical architecture (frameworks, class or sequence diagrams, ...), because this is where those diagrams can most easily been kept in sync with the development.
Application Architecture occurs when you take some functional specifications (which describe the nature and flows of operations without making any assumptions about a future implementation), and you transform them into technical specifications.
Those specifications represent the applications you need for implementing some business and functional needs.
So if you need to process several large financial portfolios (functional specification), you may determine that you need to divide that large specification into:
a dispatcher to assign those heavy calculations to different servers
a launcher to make sure all calculation servers are up and running before starting to process those portfolios.
a GUI to be able to show what is going on.
a "common" component to develop the specific portfolio algorithms, independently of the rest of the application architecture, in order to facilitate unit testing, but also some functional and regression testing.
So basically, to think about application architecture is to decide what "group of files" you need to develop in a coherent way (you can not develop in the same group of files a launcher, a GUI, a dispatcher, ...: they would not be able to evolve at the same pace)
When an application architecture is well defined, each of its components is usually a good candidate for a configuration component, that is a group of file which can be versionned as a all into a VCS (Version Control System), meaning all its files will be labeled together every time you need to record a snapshot of that application (again, it would be hard to label all your system, each of its application can not be in a stable state at the same time)
I have been doing architecture for a while. I use BPML to first refine the business process and then use UML to capture various details! Third step generally is ERD! By the time you are done with BPML and UML your ERD will be fairly stable! No plan is perfect and no abstraction is going to be 100%. Plan on refactoring, goal is to minimize refactoring as much as possible!
I try to break my thinking down into two areas: a representation of the things I'm trying to manipulate, and what I intend to do with them.
When I'm trying to model the stuff I'm trying to manipulate, I come up with a series of discrete item definitions- an ecommerce site will have a SKU, a product, a customer, and so forth. I'll also have some non-material things that I'm working with- an order, or a category. Once I have all of the "nouns" in the system, I'll make a domain model that shows how these objects are related to each other- an order has a customer and multiple SKUs, many skus are grouped into a product, and so on.
These domain models can be represented as UML domain models, class diagrams, and SQL ERD's.
Once I have the nouns of the system figured out, I move on to the verbs- for instance, the operations that each of these items go through to commit an order. These usually map pretty well to use cases from my functional requirements- the easiest way to express these that I've found is UML sequence, activity, or collaboration diagrams or swimlane diagrams.
It's important to think of this as an iterative process; I'll do a little corner of the domain, and then work on the actions, and then go back. Ideally I'll have time to write code to try stuff out as I'm going along- you never want the design to get too far ahead of the application. This process is usually terrible if you think that you are building the complete and final architecture for everything; really, all you're trying to do is establish the basic foundations that the team will be sharing in common as they move through development. You're mostly creating a shared vocabulary for team members to use as they describe the system, not laying down the law for how it's gotta be done.
I find myself having trouble fully thinking a system out before coding it. It's just too easy to only bring a cursory glance to some components which you only later realize are much more complicated than you thought they were.
One solution is to just try really hard. Write UML everywhere. Go through every class. Think how it will interact with your other classes. This is difficult to do.
What I like doing is to make a general overview at first. I don't like UML, but I do like drawing diagrams which get the point across. Then I begin to implement it. Even while I'm just writing out the class structure with empty methods, I often see things that I missed earlier, so then I update my design. As I'm coding, I'll realize I need to do something differently, so I'll update my design. It's an iterative process. The concept of "design everything first, and then implement it all" is known as the waterfall model, and I think others have shown it's a bad way of doing software.
Try Archimate.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I guess, the following is a standard problem on every school or university:
It is Your job to teach programming. Unfortunately, some of the students
are semi-professionals and have years of experience while others do not even know the basic concepts, e.g. the concept "typed variable".
As far as I know, this leads to one of the following situations:
Programming is tought from its very basics. The experienced students get bored and discontinue to visit the lectures. As a consequence, they will miss even the stuff they do not already know.
Teachers and professors claim that they require basic knowledge (whatever that means). Inexperienced students cannot follow the lectures and a lot of them will focus on unimportant stuff (e.g. understanding every detail of a complex example while not getting the concept behind the example). Some of them will give up.
Universities invent an artificial programming language to give experienced programmers and newbies "equal chances". Most students will get frustrated about the "useless language".
Is there a fourth solution, which is better than those above?
IMO this is a problem based on the placement of the students, not something you should be too interested in dealing with on your end as a teacher.
If the course is an introduction to programming a computer, then you really need to start with the basics. If you have a classroom full of professionals who know how to program and they don't show, it was either a problem with your course description, or the school forcing them to take the class as a pre-req without allowing them to test out.
Your job should be to describe what you want to teach in the course description, and teach it. If students enroll who are overqualified, that's their problem. I think the only thing you really need to avoid is trying to make the course too advanced for beginners if your course really is for beginners.
I think the best way to keep it interesting is to bring up practical and interesting exercises along the theory. Taking a problem-solution approach is great (with interesting, funny, exciting, real-world problems). This requires the professor himself to have hands-on experience, work with new technologies and know them pretty well and not just teach what he had learned a couple decades ago.
The thing is, programming should be learned by practice. The instructor should focus on motivating students to code and try to solve problems themselves. This can be done by assigning a complete life-like project at the beginning of the course and working through the subproblems that occur in the project in the class. This way, students will have an idea why some specific feature in the programming language exists and where it might be useful.
Just a thought though. Not tried it! ;)
I recently attended a course in which there was a very wide spectrum of experience in programming among the students. They still managed to keep the experienced programmers in the class interested by having an exercise program in which they timed the practical parts of the exercises (the programming part), and posted the results in a high score chart. At the end of each lecture, the professor gave some pointers as to how we could improve our times even more. As we all know, all engineers love competing for topping such lists, so we kept showing up, and even learned a new thing or two.
The inexperienced students managed to complete the exercises too, even if they didn't care too much about their times.
Don't know if your course is one that can implement this solution, but if it is, you should really consider it.
I think there are a couple if things you can do to help bridge the gap between advanced and beginner students and to keep everyone interested and involved in the course.
Advanced Workshops
If it can be arranged (using PHD students etc.) run an optional weekly workshop which anyone can attend, but which is aimed at the more experianced students. Set a code task / challange each week and then at the workshop go through various solutions to the problem and discuss the implications and the theory behind the different choices.
This provides an interesting challange for the more experianced coders as they have something to get thier teeth into. It opens some debate and can help intermediate people grasp interesting concetps and if you get people to present thier solutions, it introduces an open reviewing style which is beneficial. It also helps the beginners in that you don't have to present them with really advanced concepts in the main lecture series just to keep the experienced people interested.
Student Involvement
Experienced people generally are experienced because they enjoy coding etc. and a lot of people love to share their knowledge. A really good way to use this, and to help both beginners and advanced students is to get the more advanced students involved in the teaching. If you run classes/labs where students complete exercises, try getting volunteers from the more experienced students to act as mentors/ supervisors for the labs. When the beginners struggle they can help out by explaining fine details or subtleties etc.
This can really help the beginners, as there are never usually enough staff available for everyone to be able to ask individual questions. It can also really benefit the more advanced people, as having to explain concept which you "know" is a great way to reinforce them in your own mind, and even to discover that you have subtle misunderstandings in your own knowledge.
Don't assume more than you need to; try to select programming environments which don't have too much intellectual baggage. You may think a C "Hello world" program is simple, but that requires understanding source files, compilation, static typing and block structuring. There are not easy concepts for a beginner. In comparison, typing "print 'hello world'" into a Python shell avoids them. Declarations, compound types, object orientation, pointers, floating point, recursion, modularity, threads, callbacks, modularity, networking, databases and so on are all major concepts which require effort to learn. And, there are plenty of fun things to be done without them. Your goal should be to get everyone in the group doing programming exercises as soon as possible.
Mixed ability teaching is hard; stream it by splitting the group up if you can. Maybe publish a quiz of basic concepts, and have an optional basic concepts section for those who didn't get 100%. Some people think they are experienced programmers but have misunderstood basic ideas.
If the course time available is too short to let people try lots of exercises, then I'd drop the more advanced material before I dropped practical work.
In one course I took, a large part of the course grade was derived from a end-of-term project which was announced in advance with extra credit available for assorted add-ons and frills. Sufficiently experienced student could start working on it while their less prepraed brethren were being taught the basics.
But as Dave Markle says, part of this is a matter of getting the right students into your class: you really want a cohort that is fiarly well matched at the start.
If you have many experienced students or this is an upperclassmen/graduate level-course, you should focus on integration into existing ecosystem. Being able to understand and integrate into an existing project rather than to always work from scratch is the most important skills you can give to give to those students.
Thus, programming assignments should come from real world scenarios. E.g., assign them tasks in an open source project. This can also make it more interesting, especially as their work may become part of a real world project.
If it's really beginners, tough luck, you will have to stick to the basics though if the students are non-CS majors, you can create problems from their own domains (e.g., engineering, chemistry, etc.)
I think your could be toast.
After some point, the difference is just to wide. It will take the whole year to get the beginners to the point that they can even understand stuff that wont bore the more advanced people.
However this clearly depends on the topic and setting. For some combinations of those the solution is teach to the level that the class is billed for. Those that are to advance will get board and quit, those that are to inexperienced with fall behind and quit. Don't worry about it to much as neither should have taken the class anyway. If on the other hand they need to take the class then some one further up the ladder messed up.
Sitting in your chair watching someone talk is boring (even if you talk well).
Things are interesting if you can achieve something, when you can manipulate the world and have a moment of success. So add as many practical exercises as you can and make really sure that they can do them in time and that they can do them successfully in time.
Nothing is more frustrating than to hear: "Well, I'm sorry that you couldn't complete it. You can find a solution here. Let's copy that and pretend it did work and move on." Examples during a course are simple and the people in front of you know that. So if they can't even solve the simple examples you bring along for them, what are they going to think?
I always think it is best to learn through practice. At the beginning of the course especially it is incredibly boring to teach language syntax in a lecture. It is far better to require your students to complete some work on their own or in a lab with assistants. This allows the more experienced students to get through the work quickly.
Once this is done you can have a lecture where you discuss some of the solutions to problems. Why they are good and why they are bad.
This works especially well if you also structure your course in such a way that students are always building on their rpevious work. The first week can be something simple like calculate how many days old I am from my birthday. A problem that is relatively simple mathematically but has a few weird cases. This might take several hours for someone inexperienced. Especially if they are learning syntax at the same time. But it gives them a simple goal to work toward.
After this you can expend on it. eg: take lasts weeks program and add functionality that allows it to batch process a file. This teaches people the importance of restructuring and refactoring, and can be expanded week after week. You may even want to distribute a good piece of work from the previous week for those that are falling behind to use. Obviously you will need to make sure people don't get too far behind, but this is a nice way to make sure that everyone feels that they have a fair shot at it even if their previous week's work wasn't too good. Those who are doing well will end
The key is to keep your lecture sessions relatively high level, and have people learn the syntax on their own, or with lab assistants. You can teach them different ways of thinking about a problem but the actual act of writing code is much easier to learn by doing it.
I once through a scheduling nightmare ended up teaching a beginner class and an advanced class in the same classroom at the same time. What I did was divide my time between the two levels by starting out giving the advanced group an assignment to do in class while I worked with the beginners and then giving the beginners an assignment while I worked with the advanced. You could do something similar (only having the groups self-select into the group they wanted to be in). Prepare some extra material for the more advanced ones and you are off to the races.
Another strategy is to keep everything at the beginner level, but offer the more advanced students some other material to do for extra credit (or even as substitution for some of the simpler tasks you require of the beginners). Discuss the more advanced assignments with them outside of class or individually while the class is working on practical work in the lab.
Keeping the lectures interesting with plenty of real world examples is helpful too. I tended to lecture as little as possible though and present the material more through class discussion and practical exercises and through asking leading questions. Making them find the information to answer your questions (and class participation was part of the grade) will make them pay more attention.
I also ended each semester with a course project that I only described what they had to do in order to get a B. An A would involve doing work beyond that including work in an area not covered in class. The more advanced students can then really shine by looking for really cool new things to do and even the beginners usually find a way to do something not covered by the course. It's amazing how much extra effort they will go to when they don't know how much more they have to do to get an A. Other instructors would be amazed at the quality of the end of the course projects I got and several of them started using the same method.
It may be better to break up a few areas of concern with what some would call, "Introductory Programming":
1) Introduction to personal computers and modern computing. Assuming that the course's software runs on windows, there may be some that need to cover the basics of a computer, e.g. what is a hard drive, keyboard, mouse, monitor, CPU, motherboard, etc. Note that this has nothing to do with even one line of code other than naming operating systems potentially. For some people this may be new to them and thus having a course that covers the basics, may well be worth it. Also in this course would be ways to use a mouse and all its various buttons, what are the various kinds of cables and connections people have, what are drivers, what are patches, what are parts of a network, e.g. firewall, router, load balancers, etc. The idea here isn't to get into how to configure a firewall perfectly, but rather that the person understands what various hardware components are for and possibly how to configure a home wireless network as the most complicated concepts taught.
2) Principles of programming. This would start with the idea of what are the steps are there to execute a sequence of commands. Things like printing and performing Mathematical operations, e.g. converting from Imperial to metric,would be covered with possibly sorting being the most complicated example, viewed from a variety of different algorithms and an understanding at a basic level of big-O notation.
3) Introduction to Data Structures and Advanced Programming. Now, let's introduce the concept of a relational database and how databases work in general and have projects with real world application, e.g. have each student take a list of something they have like DVDs or CDs and put these into a database schema to efficiently store all this data. Also, the idea of floating point arithmetic and its limitations, e.g. that a computer doesn't store the whole value of pi but rather an approximation that should be good enough in most cases.
4) Introduction to Parallel Programming and Operating Systems. Here you would have some in depth work in building an Operating System and handling how to write code that can run concurrently or in Parallel and how efficient are various programs under different circumstances.
That is how I could see someone breaking up programming so that it isn't where someone can learn in a week enough to pass the final without looking at anything else.
I have frequently been in this situation, first on the student side of things, and then on the teaching side.
Most schools force those sort of courses and their curriculum. This is silly, but such is life. If your school does allow it, I would suggest offering students attendance waiver if they pass an early screening test. It is in your interest and the interest of the freshmen to not sit in a class where a significant portion of the population is bored. Even being in a room with tons of people starting at their laptops harms discourse. Everyone is required to attend tests and submit assignments, but they at least don't have to show up.
Once you work with the novices, figure out if they're majors or nonmajors. Nonmajors will resent being in a CS course, you have to try and make it approachable for them. E.g., use examples from physics or chemistry or math rather than from building an interactive gui system.
If they're CS majors, they'd better damned be interested :)
My opinion is that teaching sample programs is dead-boring for most people. Searching, sorting, classification of 7-bit ascii input, using unix & make, opening a file, writing a file...
These are boring problems. Regardless of their importance/usefulness, these are tools. Unfortunately, tools are what's taught in intro courses, not problems.
But you need tools to be able to solve a problem. So it's a kind of chicken-egg problem.
Real world examples of code the student can imagine themselves doing out of their free time.
I remember a teacher telling me to use const values it was the tax of something. I only had to use the value in two places. She asked what if i need to change it i said its only in two places and i'll change it by hand also i couldnt imagine the gov ever changing the tax %.
I cant think of an non complex example where i would use a const so i wouldnt try teaching them to use that but for arrays i would simply write a guessing game then when the player wins the game, it plays back all the guesses in the same order to them. There is no easy way to do that w/o arrays and i could see how keeping track of someones steps/guesses would be useful (bragging rights to how quickly a person guessed it).
On the first day give the syllabus (what they will learn) and required basic knowlege (things you must know or else not take this class) and stick with it. After these all you can do is teach well (explain things well, answer questions, give a joke or two now and then etc). Caring who attends class, whether or not the field is boring, whether student lied about pre-requisites or not, who listens and the other yada yada is beyond your controls. Besides, you should expect adults to be adults. If students skip class and ace test, maybe that is best for them. If they skip class and bomb tests, well maybe they are in the wrong place.
I hated when professors had this mentality when I was in college. Now as a working professional I understand it.
Center the programming exercises around either sports or movies.