Tell me a book ( or resources) for creating a good terminal based workflow (for building, debugging) for c++ based project development

Do it in two steps: There are resources for each part.

Start by learning how to compile, link, run code, and launch the debugger, from the command line.
Then learn how to write make files.

You should also read Recursive Make Considered Harmful by Peter Miller. It should direct you away from a lot of common bad practice. When I applied what I learnt from it, to re-right a make file, with the intention to make it simpler, so that it would be easier to add to. It also became twice as fast (but that is not the reason to read this).


How to explain combinatorical principles like the rule of product to students who "just don't get it"?

Yes, there are. For the rule of product, one can use nested for loops. For example, when one has to choose from 5 pairs of jeans and 7 shirts, you could use a loop like the following to list all the options:

for (Jeans j : jeans) {
    for (Shirt s : shirt) {
        print(j, s);
    }
}

You can then ask how often the inner loop loops and how often the outer one loops. The student then usually understands he should multiply to get the total number of printed pairs.

I do not know of a programming analogy for the power case (ideas welcome), but as this is an extension of the rule of product it is usually explained rather easily: the $n=2$ case relates to the for loops above, so we would have $p\cdot p$. For $n=3$, we would add another loop, hence $p\cdot p\cdot p$. For $n=4$, we would get $p^4$, etc.


I think you might be underselling your sessions a bit -- understanding how to effectively independently learn is a non-trivial skill that not everybody has mastered, and just being available to facilitate things and answer questions can be very valuable to your students. Having regular sessions that impose some structure and providing a small community of peers who share similar interests can also be helpful.

In any case, one idea is that you could perhaps try and help guide your students towards working on their own, independent projects. I've found that students (especially ones who are self-teaching) often have difficulty applying what they've learned to build programs on their own -- it seems making the jump from working on guided exercises to fully independent projects is non-trivial for many people.

What you could do is try and make sure your students all make it over that "jump" in some fashion. One idea for doing this might be to slowly start weening students off Khan Academy and have them work on a mini-project.

In particular, here are some of the things I've found seem to make that "jump" hard for beginners (and so are things you can help with):

Idea formation: beginners often find it difficult to imagine what's even possible with code (if statements and loops feel very far removed from websites, mobile apps, games, etc to a novice), and to understand how to connect their existing interests to code. (If a student is interested in games, sure, that's an obvious connection, but seeing how to write code to do things related to music, English, politics, knitting, sports, etc can be non-obvious.)

What you can do here is provide example project ideas, help students brainstorm, and perhaps do some preliminary research yourself so you can point students in interesting directions.
Project planning and problem decomposition: your students will likely need help scoping out a project and creating a realistic timeline appropriate to their level of progress and the amount of time they have. You can help them identify how to break up their idea into smaller, more manageable sub-goals, suggest some initial tasks, help them outline their overall program structure, etc...
Setup: most projects will need students to install libraries and setup their dev environment in more sophisticated ways then most tutorials cover. They will definitely need your help here -- setup can be incredibly frustrating, even for experienced devs!
Independent learning: Learning how to work through tutorials, read documentation, and compose effective google queries are all skills that more or less need to be trained. This usually happens implicitly through experience, but just being available to answer questions, give impromptu mini-lectures on related topics, etc can make things go much more smoothly for the students.
Debugging: Same sort of thing; debugging is hard, you can teach them strategies, help prevent them from being frustrated...

That said, you'll have to plan this carefully to avoid overloading your students. It's very likely that many of them practice coding only during your sessions and weren't planning on coding in their spare time (since it's the summer, after all!). Ideally, you should try and motivate them to work outside your sessions, but you should prepare contingency plans if that doesn't end up happening. Trying to complete even a small project in only 4 to 5 sessions will likely be a bit of a stretch, depending on how long your sessions are.

You can perhaps partially solve this by talking to your current students about these concerns to try and get buy-in if you're planning on having your next sessions be a continuation, or to directly state your expectations when advertising your sessions or something.


Platform recommendation for an online competitive programming school

My first instinct is that any LMS is overkill.  LMSs manage classrooms, it's true, but they also are designed to help manage schools, and most of the administrative end (and most of the features outside of the literal classroom aspects, and even many of the features within the classrooms) of any LMS would be completely useless to you.  Busing, medical designations, learning disability plans, school lunch designations, guidance counselor assignments, etc, etc, etc, etc, etc, are all beyond what you need for such a small program.
I'm assuming that most of what you're looking for is a way to distribute and receive assignments.  If this is, indeed, the case, I actually recommend using GitHub.
At the start, kids can simply use your repo as a way to download files through the web interface, and can submit early assignments through Discord, just as you've already done.  After they're comfortable with the GitHub interface for downloading, you can start having them fork projects.  Introduce git functionality slowly, and keep supporting them with Discord in the meantime.
You'll get two big big benefits out of this approach:

You don't have to get into anything nearly as heavyweight as an LMS.
The students will slowly become familiar and comfortable with basic git actions.


Supplementing Curriculum with Online Resources

How, if at all, do you integrate these or similar resources into
  particular areas of your curriculum? Does this integration work well
  for increasing student learning?

I teach Python in a "Further Education" course- not university level but the modules compare well with many first-year BSc modules.  Students tend to have little or no background in programming.

I learned a lot from completing MOOCs, and it is somewhat problematic that there is no single source of good materials...but, some of the materials are excellent.  Unfortunately, not all learners find MOOCs to be a suitable format for learning.

I encourage students to try out a MOOC from EdX, Coursera, Udemy or Udacity, or another site. One assignment this coming year will be to document the "use cases" involved with a MOOC.  Both of the assignments I set are variations from assignments on a Rice course and the fantastic CS50 given by David Malen.

For each lesson given, consider a "Further resources" section that allows a learner to view:

Videos
Tutorials
Notes
Examples

to cater to different learning styles.  Consider setting a formative assessment to test learning, and perhaps hints to the solution are in the resources provided?

At the end of each class, use a minute paper, and it may provide an opportunity to clear up any points of confusion.

I use Moodle as my LMS, and for each part of the curriculum, I provide notes (in a folder) code and links, including videos, other courses, online discussions and tutorials.

Ultimately, it depends on the individual learner- you can lead a horse to water...etc.


Beginner Javascript course - recommended books

A great resource to learn JavaScript is Eloquent JavaScript by Marijn Haverbeke: https://eloquentjavascript.net/.

You can download the pdf for free, or you can read it online, and this is probably a better choice since you can take advantage of the code sandbox.

It is definitely suitable for beginners but a wide range of topics is covered, included Node.js (chapter 20). However, with regards to your requests, HTML and CSS are introduced but you will probably need supplementary material about them.


How would you explain what is a race condition to a five years old

A lot of race conditions result from improper or unexpected interleaving of processes. Someone that age can probably understand the fable of the Turtle and the Hare.

Give the Hare a ball with instructions to run to a table, some distance away, and leave the ball on the table and return.

Tell the Turtle to go to the table, pick up the ball, and return with it.

Start the two "running" at the same time.

The Turtle has no instructions about waiting, since the proper interleaving is obvious.

Of course, if the Turtle gets to the table first then the process fails.

I'll note that Dining Philosophers isn't a lot more difficult than the above, but probably not accessible to a five year old. Certainly open to one a few years older, though.


On studying Computer Science vs. Software Engineering to become a proficient coder

You can find a fair amount of information about accredited programs in the US here, including links to schools that have one or the other programs.

In general, Software Engineering is more directed at the processes involved in creating software, and Computer Science is more generally focused on the underlying theory.

But, I'd suggest that both programs have a focus beyond just programming. In fact, you don't need any formal education to be a programmer, so either sort of program will help you develop programming skills. But that isn't the actual main focus of either. For example, an individual programmer may have little need to know about large scale software process so long as they can do their part in the larger scheme of things. He or she may be able to build things while having little understanding of the theory.

I'll also say that a "career" as a coder isn't going to be especially rewarding, either in pay or in responsibility. Many people start out there, but it is much more important, in any field, to know what should be built rather than how to build things. A degree program will give you some insight into the more important problem (though more is needed). But an entry level job after a degree may require programming but if it is the end point then your education was really wasted.

I, myself, sometimes do a lot of coding, but it is never the main thing. It is just a tool that can be used for the realization of something important. Focus on that last part, not the actual coding.

Note that Tim Cook of Apple has recently said that you don't need a degree to be a coder. Actually, though, he meant more than just "coder".


What is good age to start learning programming?

Let me urge a bit of caution if you try to combine teaching of youngsters with their parents. Before you decide, you should look at the work of Piaget on the stages of development. Adults and teens from about 12 can learn abstractly, but those younger probably haven't yet developed the changes in the brain (including physical changes) that make that possible. Starting from around 7 kids can learn things like computing, but only very concretely.

I bring this up so that you don't wind up with classes that serve no one very well and frustrate everyone. Some programming environments stress the concrete and are good for youngsters (Scratch, Logo, and other visual systems) but adults learn very differently.

If your goal is primarily to have the parents help their younger kids to learn while learning just a bit themselves, then, I think you can be successful. Just keep it concrete and probably visual. But if you are asking more of the parents, then they might not be so satisfied and you will be inundated with questions that come from their deeper way of thinking and that won't have answers that the kids can grok.

On the other hand, if you want to start with teens and older you should have a group that is much more uniform in their mental structure and abilities so it would make a wider variety of techniques possible.


Are there companies that allow to be free when learning and teaching?

What you describe is pretty close to a university professorship. We are paid to learn and teach. We go to conferences and present our work there, as well as work with colleagues. We don't normally have strict no-compete clauses, though teaching for two different universities isn't normally allowed. Courses we develop can be used by others in many cases, online or otherwise.

You would need to pick your field, however, since technology in itself is a pretty narrow subject. Study for a doctorate is normally quite theoretical in most fields, but there are programs, likely in engineering, that focus more on technology.

Companies in industry have different rules. Normally they want to create a product and are focused on that. There are education-focused companies of course. However, most such companies have strict no-compete rules, some of them attempting to bind you for life. This is especially true if you learn proprietary material as part of your job. Also, the "normal" work day has expanded to the point where you likely just want to have a life in the time that you aren't "on the job".

University professors, too, are always at work, but the work they are always at is normally thinking.

Locally, you might want to visit Arts et Métiers ParisTech, and talk to one or more of the professors there.


How can I show the value of best practices?

I've faced resistance too. Here are some ideas:

Students would not turn in an assignment to an English teacher that was not properly punctuated and proofread, even if that teacher will be the only reader. They should not turn in an assignment to a CS teacher that is not properly formatted, documented, and tested.
Companies want to hire programmers capable of writing scalable programs. I can write a much stronger letter of recommendation for students who do well at this. (Adapt to college letters of recommendation for high school students.)
Rhetorically ask why people try their best when practicing CPR on a dummy.
When I interviewed job candidates for Google, I asked questions about testing. It would be hard for candidates to answer well without having practiced writing tests.
Give prizes for and share examples of student code that follows best practices. (Get a student's permission before sharing their code.)
Show them disastrous bugs that came from not following best practices, such as this one.


Is CS50 AP available for new teachers for 2020-2021?

I just noticed that CS50 AP has just come back to life at https://cs50.harvard.edu/ap/2021/ with new access information and so on, so I'm all set.


Study the book "Computer Architecture- A quantitative approach" (3rd Edition) for the first time

I think you first need to decide what your goals are. Are you interested in computer architecture because:

You want to design computer hardware and so need to understand it at a fundamental level?
Or because you want to write software whose performance is enhanced by an above-average understanding of computer architecture?
Or because you are just mildly curious about how computer architecture works?

In the preface to the 3rd addition, the authors talk about why they selected the material they did, and they give this warning:

  To allow for this new material, we reduced the extent of introductory material, assuming the knowledge of the concepts in our introductory text, Computer Organization and Design: The Hardware/Software Interface.

So my advice is to start with that introductory text. If all you're interested in is a passing understanding of how the architecture works so you can write better software, or because you're just curious, then you can probably stop at that point.

The introductory text (at least the 4th edition of it) also includes a chart at the beginning listing which sections of the book should be read for a hardware focus or software focus, which should be read carefully, which can be glossed over, and which are just interesting but not necessary.

If you really want to understand modern computer architecture at a fundamental level, then after finishing the introductory text, you should probably get a later edition of the advanced text.

The fourth edition added coverage of multicore chips, which is a pretty fundamental aspect of modern computer hardware. The fifth edition has some pretty significant changes and adds an emphasis on mobile device architecture.

As for what order to cover the chapters, each edition is a bit different, but the the preface of each one contains suggested reading paths depending on what your goals are. The later editions go into more detail on this (by section rather than by chapter).


What are the "intangibles" that distinguish one university's CS program from another?

Fair warning, I am not intimately familiar with the programs, and my answers are based in some stereotypes of the institutions and the CS programs.  However, given that my answer is based on student selection, institutional reputation may not be a bad way to think about it.

While Yale is, by any measure, a top-tier institution, CMU is (at least by reputation) possibly the top computer science program in the world, and at an institution that is otherwise ranked lower than Yale.  I would expect, then, that self-selection among students would play a huge part in this. The sort of student who would aim for CMU for CS would be doing it because the opportunities for CS at CMU particularly appeal to them.

By contrast, the sort of student who would aim for a CS degree at Yale would be the sort of student who is aiming at Yale first, and also wants to major in CS.


Choosing Java-like language for teaching web development

I would recommend:

Starting by teaching students just plain HTML, CSS, and perhaps JavaScript and focus on teaching the frontend first.
Once students are ready for the backend, switch to using a minimalist framework such as Spark. Have them first construct HTML using plain old string concatenation, make a big deal over how sucky that is, then switch to using a templating engine (any one will do, so it's probably best to pick one with the best documentation).

Teaching the front-end first does require you to make a "clean break" and switch away from Java, but I do think it's for the best for several reasons:

It's essential context for the students to have. Many backend tutorials will assume you already have a good understanding of the frontend, so it'll likely be more confusing if you don't start with the frontend.
Starting from the frontend lets students get instant gratification.
Starting from the frontend lets you move from simplicity to complexity: you start with static websites and gradually progress to something more complex (dynamic page generation, AJAX hijinkery, etc...).

I like using micro-frameworks such as Spark (for Java) or Flask (for Python) for teaching the backend. There's minimal ceremony, and micro-frameworks tend to closely mirror the HTTP request-response model, minimizing conceptual overhead. And since Spark is Java, you don't need to spend unnecessary time teaching a similar language.

In fact, there's even an argument to be made that the best thing to do is to ditch even micro-frameworks and start with just plain CGI or something: you literally manipulate strings, and that's it. Then, time permitting, you have students write their own framework/templating engine/what-have-you on top of that.

Basically, I view web development as one giant exercise in working with abstractions, and I feel one of the best ways to make students understand an abstraction is to have them build it from the ground-up/start without the abstraction. Web frameworks and trends come and go at a ludicrously fast pace, so I think it's particularly important in web development to focus on the fundamentals rather then trends. (You can see more about this philosophy here)

In particular, I like emphasizing that web frameworks are just complex ways of processing and sending strings: I think it helps demystify a lot of things, and gives students a concrete footing to help build their understanding of these abstractions.

(Tangent: you can work in all kinds of interesting CS topics depending on how much you want to commit to this "build everything yourself" model. For example, you can talk about compilers, parsers, and DSLs if you have students build their own templating engine; you can talk about NFAs, DFAs, regexes and such if you have students build their own regex engine to match routes... This is all probably overkill if your focus is just on teaching web development though.)


Order of learning formal languages, automata, compilers and parsing

I'm happy to stand corrected if someone else comes in with a more experienced answer, but automata and formal languages are typically taught together as two aspects of computational theory, since different sorts of automata represent different sorts of languages.  Among other reasons, it's hard to have a discussion about the computing power of modified automata without having the languages to refer to.

As for compilers and parsers, if the goal of a compilers course is to show a student how written code can be translated into machine code, how could you approach one without the other?  "This compiler takes a... tree... and turns it into machine code." The topics are significantly enough interrelated that I would have trouble imagining a sequence where they don't get mixed in together.

I believe (though I have not done a thorough search of course sequences to back this up) that compilers is typically taught sometime after computational theory, since it helps to be at least nominally familiar with the notion of a grammar before you begin.


Why do educators not set an upper bound for the amount of times we're allowed to compile code?

Because it's a meaningless obstacle

Putting an upper limit on compilations is like telling a car manufacturer that they must build a new supercar, but are only allowed to test drive it a few times.

This means that you're pushing your developers/mechanics to theorize about whether something would or wouldn't work, instead of actually finding out.

Theories are really just educated guesses; so do you genuinely think that guessing more often will achieve a better result than testing more often?

Because that's not the purpose of education

Especially in a hands-on field such as software development, the goal to learning programming is to keep trying until you stop failing. That inherently means that failing (and thus needed another compilation in the future) is an inevitable step in the process.

You seem to think that compiling often is indicative of a "bad" programmer. It isn't, but let's explore that assumption.
What exactly is your perceived problem with compiling more often? If a "bad" programmer is able to deliver the same end result in the same amount of time as a "good" programmer, does it really matter whether they compiled often or not?

Clients/managers tend to not care about how a programmer achieves their goal, they only care that they achieve it within the set parameters. If anything, I'd be more willing to hire the programmer who continually fact-checks himself (by compiling), compared to the programmer who assumes they know what they're doing (rarely compiling) and thus will get stuck needing to retrace their steps afterwards.

What you're suggesting is the equivalent of not permitting students to redo their calculations on a math exam. You're trying to teach them the exact opposite behavior of what you should be teaching them.

Because that's not how it works in a professional environment

Once you get to the stage of being a self-sufficient developer, there is still much to learn. One thing that junior developers often do wrong is down the problem into sufficiently small and simple parts.

In short, it is better to build something with 50 simple components than it is to build it with 10 moderately complex components.

Cleverness can be damning as a developer. When you're developing something, you understand the ins and outs, and you might find a very clever trick/workaround that may seem counterintuitive at first but actually solves your problem nicely. This can manifest itself in different ways: overly terse syntax, lack of accurate naming, an overly complex algorithm, lack of self-documentation, requiring specialized knowledge of a particular tool/library, ...

However, your cleverness can be your undoing when you (or someone else) needs to reevaluate this code in the future. If there's a bug, it will be hell to find out where the bug is located.
But even when there is no bug, e.g. if the requirements change, you will need to be able to pull the existing logic apart to introduce your changes.

Putting a hard limit on # of compilations wrongly incentivizes developers to only compile (and thus test) large changesets. When anything goes wrong, it's very hard to pinpoint where exactly it went wrong.

However, if you compile (and thus test) small changesets, it's very easy to see where it went wrong, as there is only a limited amount of changes that have occurred between the last (working) version and the current (failing) version.

This is the core argument for using unit testing and continuous integration. Developers are urged to take the smallest possible incremental steps, so that their code can be tested every step of the way, thus making it easier to find the source of a bug/error.

Since there is no purpose to retesting without recompiling; if you want to test often, you must therefore also compile often.

  I've developed a pretty bad habit of programming by permutation/shotgun debugging and in my first few months of Programming and even after 1.5+ years I still fall back to it sometimes.

When all else fails, shotgun programming is the most reliable method of figuring things out.

That is not to say that shotgun programming should be your primary development approach, as it can lead to time wastage. But when all your clever logging and theorizing fails to solve the problem at hand, shotgun debugging pretty much guarantees that you can take (admittedly slow) steps towards finding the solution.

As much as I am pro-shotgun (in certain cases), I do concede that wanton shotgun debugging can be used as a way to brute force a solution and avoiding having to understand the problem, which is counterproductive in an educational context. But this is part of a bigger issue that is not easily preventable.

For example, some students may rely on StackOverflow as a snippet repository and avoid having to understand the snippet or why it works.
To be clear: as a software developer I use it as a snippet repository as well, but I use it as a shortcut or not having to reinvent the water, not as a way to avoid having to learn the core skills required.

The issues of students writing code that works but they do not understand why (regardless of whether it's copy/pasting or brute forcing a solution) is not something you can address with a simple test. This is where oral exams are most useful, because you can very quickly gauge the difference between a student who found the right snippet, and a student who understands the core problem and how to approach solving it.


Is there a Java library for testing command line applications?

There is expect. It is designed to test interactive command-line systems. For non-interactive programs it is easier.
expect is not java, but as pointed out in the comments. The language is irrelevant, as the testing is done from the outside.


Actually, there are two questions here. I'll answer the obvious one first. You can fairly easily solve the perverse incentive problem by having two due dates: one for the first 89% and a later one for the rest. If you have ideas about what they should do for the second part, don't reveal them until they turn in the first part. You needn't necessarily even mark the work after the first deadline, but you can, if desired.

After the first deadline you have a version of the project. You can compare it with the second version to see what changes/enhancements have been made. In situations like this, I usually have students turn in work on paper and in the second version, mark changes (highlight markers) so that those changes are obvious.

The second question is how much you want to encourage student "creativity" anyway. It isn't always good to let students loose without specific direction. There are two kinds of creativity: the what and the how. In the real world, it isn't normally the programmer who is responsible for the what. That is up to the Customer/Client/Boss/Organization. The creativity on what belongs to them. On the other hand, creativity (i.e. excellence) on the how is the key attribute of a good developer. For most assignments that is what you should be looking for. Do they understand the algorithms? Can they implement them efficiently? Is the code clear and maintainable? Is it tested and correct?

So, I worry that if you just give an incomplete specification of the work and expect them to use their own creativity around what should be done, that they will get the wrong ideas about building things. As others have said in answer to other questions here, going outside your charter can be seen as a problem, not a blessing. See this, for example: https://cseducators.stackexchange.com/a/4539/1293

On the other hand, teaching creativity is also a goal of education and there should probably be one or more courses, or at least projects, where students do get to conceptualize, design, and build something interesting. But don't let them get confused.

Caveat. Those who work at startups that define their own product have a different view. There, it is often the case that programmers participate in defining the product, but that isn't the common case.


Are there any resources out there to continue developing my students' programming skills after Code Combat

You could try the Bootstrap curriculum, the materials are free and can integrate with existing curriculum instead of being electives. A talk about the design of the program, and how to design highschool computer science curriculum in general is given here by one of the Co-directors of Bootstrap, Professor Shriram Krishnamurthi from Brown University.


There are a lot of reasons this hasn't happened, and probably won't. The first is that the exercise would need to be published somewhere that was effectively searchable. Some instructors will post exercises online, but not all. Many, in fact, want to keep them private so that they can reuse them in the future. Posting them online often leads to bad behavior, such as searching for solutions, rather than actually doing the exercise as intended.

Another problem would be the establishment of a consistent set of tags. For a small site such as this one, it can be done, even if imperfectly. For the entire world wide web it would be a much harder (impossible?) task.

But if you have done all of the exercises in your course textbook and yearn for more, you can often find books of exercises on various topics. I think this used to be more common than now, but for some subjects they can be found. I remember Schaum's outline series in the past. The still seem to be in print.

Your course instructor can, perhaps, loan you another textbook with even more exercises.


Shallow, broad and general introduction to programming

The purpose is to interest them in learning programming. More specifically, to give them a taste of some aspects of various languages, hoping that each will find something they like and, being naturally curious, they might pursue the subjects they liked a bit more.

Comparison of programming languages doesn't make sense until they've first mastered the basic concepts, so two weeks doesn't seem like enough time to get onto this. I think you'd be better off taking one language which supports functional and OOP styles, covering both, and then maybe doing a small Rosetta Code presentation in the last day or two, with a handout which they can refer to after the course has finished.

I'm also not convinced that the students' curiosity will work that way ("This idea of first class functions is fun: what can I do with it?"). I think that the hook should be that programming lets you do things which are fun and/or useful. The difficulty with coming up with examples is that no two students will agree 100% on what things are fun and/or useful. Games are a good bet for fun, although graphics tend to be complicated and you risk needing to dedicate lots of time to teaching/revising trigonometry and quadrature. I'm not sure whether today's youth would find text adventures fun. The concept of databases as useful is another reasonable bet: most people will collect something or follow a sport, and you can build and query structured data to enhance both of those. Pick a language which has easy serialisation and you don't need to bother with "real" databases (although maybe mention them in the handout).

Although I've never used it myself, Swift looks like a reasonable teaching language if you want compile-time typing. From looking at examples on Rosetta Code it seems to have clean syntax and support imperative, functional, or OOP styles.


How far do you take modular expressions?

A specific example that I've used the mod operator before for (and have seen it used in production code this way) is to represent a higher dimensional array (usually 2D, but higher is possible) as a one dimensional array, and then use some modular arithmetic to retrieve the higher dimensional structure. The reason one might want to do this is if your array structure is a substructure of a more complex object, it might be simpler to implement it one dimensionally, and then add more complexity onto that.

I've seen this done when one is "tiling" some 2D space, where each tile maps to some properties, and where each tile's properties may change in time. This could end up being a very complex structure: potentially, a mapping from time, to the first dimension of the tile, to the second dimension of the tile, to each of the properties of the tile. In such a case, the geometric "2D"-ness of the tiling may not be that important (except for perhaps the display), and so the implementation of the internal model of these tiles could be one dimensional instead, simplifying our model.

Here's a simple 2D array example. Say one has a 3 by 3 array, where the "property" is represented by some integer:

1 4 9

0 2 7

5 6 4

Our 2d array may be indexed with [row, column] as follows:

[0,0] [0,1] [0,2]

[1,0] [1,1] [1,2]

[2,0] [2,1] [2,2]

However, we can represent it with only a single parameter as:

0 1 2

3 4 5

6 7 8

(left to right, then top to bottom is just a convention of course)

Now, how do we retrieve the row and column numbers given one of these indices? This shows some nice symmetry between the / operator (that is, truncated division on integers) and the % operator.

If we're indexing rows and columns as in my first example, the "row number" of an index i above is given by i / 3 (again, truncated), and the "column number" of an index i above is given by i % 3.

In general, if you have an n by n array, and you index it as I did above, the row number is given by i / n and the column number is given by i % n.

Another example, and this one gets closer to the intuition you're trying to achieve, is simplifying computations for cyclic functions. If your functions are over the integers, then your operator % is good enough. However, this wouldn't work for continuous functions. Nicely enough, one can take your discrete cyclic model and make it continuous in programming languages by using fmod or an equivalent.

Specifically, for students with enough background in Calculus that have some familiarity with Taylor series, one can think of how one would write a trig function like cosine. One might realize that the 6th degree Taylor polynomial approximation is "close enough" in the range between $- \pi/2$ to $\pi/2$. Then, one can "mirror" that to get one complete cycle of the cosine curve between $-\pi/2$ and $3\pi/2$ (for example.) Then, with this, one might ask how one would compute the value of $cosine$ for any real number, and the answer is quickly obtained by using some modular arithmetic to get your number in that range, and then use our restricted cosine function for that translated number.

This use of mod also relates to Guy Coder's answer: thinking of taking the mod of a number as involving several subtractions is precisely how one might implement the continuous fmod function (however, whereas a discrete mod function's usual "remainder" intuition may be lost here, the intuition regarding the cyclical nature of mod should be strengthened).

In general, I like to think that the kind of mental modeling required to think about mods is going to help these students regardless of whether they literally use them later on in their programming careers.


Would it be beneficial to learn computer science (or other computer related stuff) from 5-6 year old material?

For many things it is possible, even advantageous, to learn from older books and materials. But it also depends on your goals. Computer Science, like any field, has some things that are fundamental and the fundamentals change only very slowly. The major programming paradigms, for example, were all created in the previous century. The fundamentals of compiling programs haven't changed in a long time.

Also, while some areas have shiny-bright new stuff, a beginning student isn't going to study those first, but only after gaining some background in things that haven't changed in a long time.

So, if you are a student, seeking a broad understanding of the field, then older materials won't be a handicap, though at some point you will want/need to learn the newer bells and whistles.

But if you have a specific need, such as learning some specific technology at the expense of other things, then you should probably go with recent materials, even knowing that some of the details you learn will, themselves, change in a few years.

Even networking has a lot of fundamental ideas that need to be understood before you can grasp the details of the latest networking protocols.

Let me give an example. Recent versions of Java have introduced "exciting" new capabilities, including function abstraction. The beginning student won't study those things at the beginning, however, but will be more concerned with creating good OO programs. If you study Java from older materials, but also study something of functional programming (say Scheme or Haskell), also from old books, the new features of Java won't be a surprise to you. On the other hand, if you are faced with an eventual exam (such as the Advanced Placement CS-A) exam, then you need to study from materials that will prepare you for the questions that will be on that exam - likely newer books.

But in general, many of the older books are true classics that will give you a deep understanding of fundamental things that make it possible for you to move easily into new things as they are introduced. Learn what is important. It is even enlightening to adapt old ideas, such as top-down-program-decomposition, to newer frameworks and to understand why things change. But that also requires background in the fundamentals.

Since you also mention online courses, you should note that a course from a few years ago is almost certainly still relevant. This is partly due to the fact that the creators of such courses are generally highly skilled and also value the newest ideas. It is very likely that the courses were very current at the time of creation, as well as being grounded in fundamental knowledge.

As a final note, it is also sadly true that some of the older books have not been updated and the key, deep, ideas in them are not readily available elsewhere. The newer books may not incorporate the ideas of the older books so you may even lose something by only learning from the latest materials. I have one example of a book that had a truly excellent first edition (a Java textbook). The second edition, however, left out many of the parts that made the first so excellent, however. This is due to the unfortunate practice of book publishers to emphasize new editions whether they are an improvement over the old or not.


Once implicit/inferred typing is introduced, how can I impress upon students the importance of not abusing it?

Then I inevitably have students who abandon the good habits they had
  formed and want to make everything an Object, or declare everything as
  var.

These are very different situations. As you observe, the use of var in C# is controversial, but using object as the type of all variables (and then needing to cast any time you want to actually use the variable) is not controversial: it's just wrong.

The first page of answers on the linked SO question about var in C# is incomplete. It doesn't mention that using var can avoid bugs due to typing in one edge case: foreach (var foo in foos) vs foreach (Foo foo in foos). For legacy reasons, if foos is a System.Collections.IEnumerable but not a System.Collections.IEnumerable<> the latter is equivalent to foreach (Foo foo in foos.Cast<Foo>()), which is not especially obvious. (In fact I misremembered and was corrected in comments, which reinforces the advantage of using var here).

TL;DR: blanket prohibitions on var are almost certainly going too far.

  My question is, since these students are still learning, and since it
  is my classroom after all, should I emphatically require that they
  always explicitly specify types unless absolutely necessary? ...
  And, if I do require it, how can I explain the (in my opinion)
  sloppiness they sometimes see in online communities?

var is far from the only controversial subject in programming praxis. The solution in industry is the style guide: whether as a formal written document or as an informal internalised set of opinions which are imparted to new team members by word of mouth when they submit changes which violate the house style. If you're explicitly preparing your students for industry, it is perfectly reasonable to dedicate a bit of time to explaining the concept of the house style, and then when you introduce new material to explain the house style you will enforce for that feature.

The really heavy-duty approach would be to prepare a full industry-style style guide and then to produce a series of increasingly large subsets so that every couple of weeks you can give them a link to an updated style document which specifies how to use the new features you just introduced, or the new features you're about to introduce, and highlights the additions from the previous one.


AP Computer Science Principles and Unity

Unity has a "Create with Code" curriculum that is aligned to ISTE standards:

  Most importantly, Create with Code is designed to work in the classroom. Aligned to ISTE Standards for computer science education, educators can leverage the free course curriculum to support instruction inside and outside of class. Flexible teaching materials are provided in addition to the learner-facing instructional videos...

The above site has an ISTE standards alignment document, as well as a scope and sequence, set of lesson plans, and a course syllabus. Many of the ISTE standards map pretty well to to AP CSP standards.

AP CSP is pretty flexible in terms of which set of tools you use, so I think you'd be safe with Unity:


Explaining Event-Driven Programming in the context of the Structured Programming Theorem

I don't see that there's anything to explain, because there's no apparent contradiction between a set of language constructs being "all you need", and a language having more constructs than are "needed". Languages are designed to have constructs that are useful for human programmers to easily and concisely express what a program should do, not just a minimal set of constructs for it to be possible to express programs.

It's not even necessary to explain that event-driven languages are implemented using hidden conditional statements and loops; and as Buffy notes in the comments, they may not actually be implemented that way anyway. If you want to tell your students that they could be, then I see no problem with that. But consider this:

Untyped lambda calculus is Turing complete, so "all you need" is function definitions and function application. Does that imply that conditional statements and loops must be implemented with hidden function definitions and hidden function applications? Well, no, it doesn't imply that.
The logical NAND operation is functionally complete, so "all you need" is NAND gates. Does that imply that computers are made only of NAND gates? Again, no, it doesn't.
As shown in this paper and amusingly demonstrated in this compiler, the x86 mov instruction is "all you need", i.e. any C program can be compiled to a sequence of unconditional writes to memory (at addresses read from memory). But the rest of the x86 instruction set is, of course, not implemented that way.

What I will suggest is that if you do want to mention that sequence, conditional statements and loops are "all you need", then you should add that real programming languages have more control-flow constructs than just those, because the additional ones (e.g. subroutines/function calls and return, try/catch, event loops…) are convenient.


Is it possible to teach selection (`if`) before variables

From a practical standpoint, rather than a theoretical one, there are at least two pedagogically defensible ways to do this. Spiral curriculum, and Scaffolding

Use a Spiral Approach

I won't assume that you never mention variables early with this approach, but you just don't teach all that needs to be known at the first introduction of variables (or any other topic). To teach like this you mention things that need to be known deeply early on, partly to introduce terminology, but partly to permit simple uses in which deep knowledge isn't needed. Then, for example, variables but without reassignment could be used in setting up some sort of selection or iteration as your lecture focuses on those ideas rather than the variables. At any given point in time students know a little about a few things and a lot about some other things. Then, in the next cycle you go a bit deeper in some topics but also introduce, very lightly, other topics.

The implication is that a student never needs to completely understand any given topic the first time it is presented as it will be seen again. Everything is reviewed constantly in such a course.

For purposes of this particular question, a variable could be initialized somehow and then used within a selection structure. The student need only have the idea that the variable refers to a value and can be thought of as a temporary name for that value.

Teaching a course in a spiral way requires some pre-planning, of course. It isn't enough to put each important topic into the syllabus only once. Neither is it enough to expect that every student will get a lot out of the first introduction and you don't, therefore, need to obsess that everyone is on the same page before moving to the next topic.

Use Scaffolding

An independent way of teaching is to have students first programming experiences done within a pre-defined richly endowed virtual world. The world is constructed so that interesting things can be done early without necessarily building up everything from the beginning. Often these world are simulations. For example, in Karel the Robot and its successors, programs consist first of writing sequences of statements to direct an existing robot. The robot's capabilities are built in and the student simply invokes existing functions/methods to achieve some complex effect. Next the student learns to write methods or functions as just abstractions over some sequence of such pre-build actions and other actions already built by the student. In this way it is functional abstraction that is the first real topic of importance. You can introduce variables or not, and you will certainly do so when you want several robots acting together. But these variables are just object references and little needs to be known about them, including whether they can be reassigned or not. Selection is certainly a reasonable topic in such a world, as is iteration, polymorphism, recursion, or whatever you need to teach.

However, careful thought needs to be given to the characteristics of the simulation world. How rich is the environment. It can be simple, for example, and still be Turing Complete.

Some teachers might choose this path with a single simulated virtual world, and others might choose to use several worlds of increasing sophistication and, perhaps, increasing complexity. I'll note that Greenfoot was built precisely to provide an environment in which such simulations and virtual worlds would be easy to build.

Both of these techniques are very powerful and have been used by many instructors over a long period of time. Of course, they may be combined to good effect.


How do I teach about inequity in computing resources?

This seems to me to be the sort of topic that is best covered with an assignment such as
Write a paper, citing resources, on the topic of XYZ.
There are a number of other things that can be addressed this way. One advantage of such an assignment is that students have to write using natural language, which often gets too little attention in technical fields.
Another advantage is that you can have the work done in pairs or teams.
Another advantage is that you can follow up with class discussion, seeking consensus on the problem.
You can, of course, provide them with an initial set of resources so that they are forced to look beyond Wikipedia and other easily found resources.
You can also ask for critique of the resources that they find, not just reporting. You can even have a debate. Lots of possibilities since the topic is both serious and open ended.


How do I convince students to use Boolean algebra?

Well, for one, computing a truth table doesn't scale: generating one takes exponential time, with respect to the number of variables you're using.

You can perhaps "subtly" drive this idea home by asking your students to manipulate some proposition that contains 7 or 8 variables (which would require creating a truth table with 128 or 256 rows). That would require an exhausting amount of work -- the benefits of using algebra should hopefully be more obvious, then.

To make the problem more tractable for the people who are using algebra, you could perhaps engineer the original statement so some of the variables end up "vanishing" (e.g. they simplify into something like p || !p).

I think it would also be worth explaining why it's useful to be able to systematically simplify or manipulate boolean expressions in the first place -- for example, you could explain that when you're designing circuits, you have a vested interest in minimizing the number of gates used to keep costs down (as well as potentially minimizing the number of unique gates used).

And finally, another idea is to just simply tell your students why you're asking them to learn this material in the first place. For example, you could say that you're trying to prepare them to write proofs later on in the course (assuming that's what you're doing). After all, a large part of writing proofs is about correctly manipulating and applying definitions, and that's exactly what you're asking the students to do now.

Generally, I think sharing your gameplan is a good way of getting students on-board (albeit sometimes reluctantly).


What is the closest pair problem useful for?

Rosen, Discrete Mathematics and its Applications, Sec. 8.3, says:

  This problem arises in many applications such as determining the
  closest pair of airplanes in the air space at a particular altitude
  being managed by an air traffic controller.


Which non-programming skills help make a good programmer?

I don't think this question can be answered in any meaningful way. There isn't a finite list of skills that you need to be a programmer, or that make you a better programmer.

Computer science is a huge field encompassing just about every job you can imagine, and each of those jobs requires a different skillset. No matter what your interests are, chances are you can find a place for yourself in the industry somewhere.

Skills that make one person a good programmer won't necessarily benefit another programmer. One programming job might require an artistic background, whereas another job might require a mathematics background, or a managerial background.

The best answer to this question is going to be very broad.

  So, what makes a good programmer?

The ability to learn. Most programming is not actually writing code. Most programming is reading tutorials, running example code, and looking stuff up in documentation. Programming is more of a craft than people realize.

The ability to break things down into smaller pieces. Again, programmers don't sit down to code as soon as they're given a task. They have to spend a significant amount of time breaking the task down into smaller steps, and then taking those steps on one at a time.

The ability to ask questions. This might mean looking stuff up in the documentation, or on Google, or on Stack Overflow. It might mean asking a colleage or even a rubber duck.

The best software teams are comprised of a bunch of different people from a bunch of different backgrounds, with a bunch of different skills. Instead of trying to focus on a particular set of skills your students need, I'd recommend looking at the skills your students already have and helping them explore those skills in a computer science setting. Have a student who likes art? Cool, teach them about creative coding. Have a student interested in statistics? Teach them about data visualization. Have a student interested in mechanics? Teach them about robotics.

Don't ask what skills you need for computer science; ask what computer science you can do with your skills.


Using physical activity to explain the nested for loop

Your pupils are already be doing nested loops.

foreach week {
   foreach weekday{
      wake up
      clean teeth
      eat breakfast
      goto school
      foreach period{
         goto class
         do lesson
      }
      go home
      do evening stuff
   }
   do saterday stuff
   do sunday stuff
}

What about some formulaic music.

Music has a lot of repetition, could you get them to play some music based on a nested loop algorithm. I am thinking drumming on tables, and a lot of shouting.

e.g. something like

Repeat 4 times:

Teacher says: “say yo 3 times”.
Teacher says: “clap 4 times”
Teacher says: “…”

Sorting algorithms — dance, or just moving about.

Get pupils to act out sorting algorithms. And identify the loops.
Here is how to do it in the form of dance http://youtube.com/watch?v=lyZQPjUT5B4


The problem you describe doesn't exactly fit this answer, but it might be useful to some with a similar problem.

In some such labs it has been observed (and filmed) that students working alone at a station get into some difficulty and raise their hand for help. If the instructor and/or assistant is busy with another at the time, the student with the new problem waits. Then maybe another, and two are waiting, etc.

The solution to this is to have students always working in pairs in the lab, doing things like pair programming, pair research, pair writing (very creative), etc. This has been observed to reduce the waiting to essentially zero as the students solve their own problems. When one student gets "stuck" it is unlikely that the partner is stuck in exactly the same way so they can move on. This is a well known effect in professional pair programming also.

You still need to wander about asking if you are needed, as a pair will sometimes queue a question till you come around while they work elsewhere.

Sorry, I don't have a link to the study on this. I assume it came out of the Agile Community's educator forum.


Introducing image processing - Should I teach the math

I would tread lightly here for a few reasons:

The math is not strictly necessary.
The students signed up for an image processing workshop in the context of programming.  The core skill that they expect to come out with is the ability to program graphics manipulations.  Spending a substantial portion of this time learning about the underlying math, certainly important in a full semester's undergraduate or graduate coursework, only moves very slowly towards what they (presumably think) they signed up for.

Some kids get turned off by math.
One of the unstated goals of every course is to both show the value of the field, and hope that the student wants to go on with the material and learn further.  That means that we want them to like it.  Using a voluntary summer workshop to emphasize the more abstract parts of the material may turn many of them away from graphical processing entirely.

So, don't do any math then?
Actually, I would not say that.  I would touch on a some of the underlying mathematics, but briefly, and (because it is a summer workshop) with the simple goal of illustrating that there is important material that isn't too difficult to tackle if they eventually want to go further into the topic.


What are the pedagogical methods for teaching programming?

I'm not sure this is what you are looking for, but from personal experience (and probably in no way 'official' educational paths) :

I gave each approach a name in order to be able to seperate them in case users want to discuss them.

Frontal Theory: Speak in-class about constructs and syntax, students code at home (exercises).
Collaborative: students and teacher code together in-class
Guide-and-Release: Introduce them to the topic of coding in-class, then let them complete online-courses (there are lots of websites which provide virtual classrooms with a "control" function for the teacher observing the students' progress.)
Project based: Each student / group of students decide in the beginning what kind of software (scale is up to them/teacher) they want to write / rebuild (e.g. a blogging site / a tic tac toe game in the command console). The teacher helps students research what is necessary for it, how to approach it. Learning progress happens throughout the development.

@Project based: example for the tic tac toe game: we need input, output, a way to store values, loops. Then start with researching&learning how input/output works in the chosen language. Gradually build up knowledge until the game can be implemented. (Probably my favorite approach, as it focuses on learning how to analzye/break down a problem, solve small instances one at a time and then put components / partial solutions together -  which is coding at its core in my opinion)

Edit: Removed the following approach from above, as it is rather a didactical approach and not on the same "educational level" the previously mentioned - but for completeness, here you go:

Free Style: Students learn by themselves in-class, the teacher is only available as a "helping hand" if problems come up. (No solution on a silver platter, but rather giving points on where a solution can be found - stackoverflow, documentations etc.)


If you haven't used Pair Programming (PP) before but want to introduce it, there are two additional books you should read for background. They aren't textbooks for your class, but put PP into context. Extreme Programming Explained gives the complete context of PP in the agile development process. Pair Programming is one of the "small scale" practices of  Agile Development - a personal practice, that is used in most agile methodologies.

The second book Pair Programming Illuminated focuses more on PP itself.

Since students may do much of their work outside your view, they need to be convinced that it gives them something or they won't use it. The alternatives seem too enticing to them (e.g. splitting the work...). So the classroom demo suggested here (points 3 and 4) is probably necessary: Techniques for encouraging pair programming.

The problem is that they already have programming habits and they will fall back on those in a pinch unless they see a compelling reason to do something different and develop new habits. The classroom demo can help with that. But you have to play navigator yourself, not just driver, in your demo.

The wisdom of the profession on PP is that the driver takes a microscopic view of the project at hand. If the navigator is behaving correctly he/she will take a broader view, thinking about how what the driver is doing fits into the whole of the app being developed. When you work alone you only get the micro view, which often enough leads you astray.

The navigator is not just an after the fact reviewer, but an active participant. That takes practice. This is the key to making PP productive. You have two minds on the problem and each has a slightly different perspective.

Another advantage is that single programmers often get stuck and have to think for a while about how to proceed. But two programmers seldom get stuck at exactly the same point. That is the time to switch roles. The navigator notices a change in the pace and, perhaps, takes over the driver role for a while.

I have a picture in my head of 10 programmers, each working alone in a cubicle, and each stuck on something, making no progress, but the person in the next cubicle having the key to continue.

Another good practice, if you are always using test first programming (TDD = Test Driven Development) is that one person writes a test, which fails. The other person builds enough of the app to make that test pass and then writes the next (failing) test. The first person takes over to make that test pass, etc. Back and Forth. Clockwork.

To understand when and why the driver and navigator roles should switch, think about what a solo programmer does quite naturally. You are programming and have been for a while. You are in the grove. Things are flowing. You are focused like a laser on your work. The solutions are coming naturally. And then... suddenly you hit an obstacle. The next thing isn't obvious. At that point, you naturally widen your focus and look at the wider picture. You eventually "get it" and move back in to continue. Or, perhaps, you take a break.

On the other hand. Consider what is natural for someone looking over your shoulder as you work, making occasional comments on things like naming, or structure. Perhaps reminding you of some method or tool you might employ rather than building something new. They are taking a wider view since they don't have responsibility for the progress. And then, suddenly, they notice a change in the pitch. You aren't making progress and seem puzzled. At that moment, their instinct is to focus more closely on what you are doing to try to resolve the issue.

So, one person widens focus and the other tightens it. That is generally the moment to swap roles as the role is determined by this level of focus.

If you try to switch roles by some arbitrary means, such as time, you will likely lose the advantage of the "dual focus" view of the project. The most likely outcome is either (a) the navigator becomes disengaged altogether or (b) both take the laser view, losing the broader, overall, view of the program.


I find conferences are good for learning in new fields. Most of them cater to academics but many industry researchers present at them as well. For example Microsoft Research sends people to a lot of mostly academic conferences. ACM and IEEE Computer Society both have conferences. Besides the papers that are presented, often including more material and details than the written papers, there is the opportunity to discuss recent developments with practitioners.


What are effective ways to prepare students for the AP CS Principles Exam?

Personal disclaimer: the best preparation for the exam is first to ensure that students master course content. If you have an AP CSP-aligned curriculum, then every day is a day of exam preparation. This touches on the biggest struggle I felt as a first-year AP teacher: am I teaching them computer science, or am I preparing them for a computer science exam? The ideal situation for me -- and the personal resolution I reached -- is that quality instruction, assessment and feedback, and student engagement with a rigorous curriculum (CS50 AP in my case) are the key elements to focus on for ensuring student success on the AP Exam.

That said, I did utilize a number of resources throughout the year:

The full-length sample exam provided through AP Course Audit (a secure document)
The 22 sample questions from the course description
The prep book Fast Track to a 5
The online paid resource Albert.io

I'll enumerate how I used each of them and for simplicity refer to them by the number listed above.

I pulled questions from #1 throughout the year. The first unit covered a basic intro to binary, so as a short formative assessment, I gave students the four sample questions they could answer having studied the basics of base systems. This was within the first two weeks, so right away we could talk about exam-style questions, specifically the ones that required selecting two right answers. I used sample questions a few more times during the first semester, but I didn't make it a priority (see disclaimer above). However, on the last day of class in the fall, I gave students a modified exam. We had studied three of the six Big Ideas tested on the multiple-choice exam in depth, so I selected questions equivalent to half the exam (enough for the allotted time and perfect for matching the pace of the real exam) and surprised them with this practice exam. There was no warning; students just had to trust what they had learned up to that point. We started the second semester going over this exam. I did an item analysis over break, so I could hone in on strengths and weaknesses and address them in the spring.

In the second semester, I started to use #3 at certain sporadic moments. Since The Internet is arguably the most fact-driven of the Big Ideas, I used it as a resource for designing an exam on my Internet unit. Students were encouraged to buy it, but it was not a requirement. So much time in the second semester is taken up by Explore and Create that the multiple choice test is a lower priority until after spring break. Based on this year's Easter timing and AP schedule, I had two weeks of classes to devote strictly to exam preparation. This amount of time was more than adequate to build students' confidence and familiarity with the exam format.

During these final two weeks of prep, I went through each question from #2, discussing how each Big Idea could be assessed. As a class we went through each Big Idea on the exam and connected the learning objectives to potential exam questions. The sample questions were great talking points for reviewing course content. I also gave an in-class exam using all the questions from #1 that didn't make it on the first practice exam. I paced it such that students had the same time/question that they would have on the exam. I wanted to make sure students had seen every official practice question and had the opportunity to ask about each one, especially the ones from the secure document that they couldn't take out of the classroom.

The last big exam review I did was an optional exam review the Saturday before the exam. I had >50% attendance, and by the end the students felt more than prepared for the exam, and I felt confident I had done enough to get them ready for it. That day (and the following week) I made heavy use from #3 and #4. We basically went Big Idea by Big Idea, gaining more practice and focusing on particular tips and tricks for each. In particular, we went through a number of the robot questions and those questions that required analyzing segments of code.

At the end of the course, I asked students how prepared the felt for the multiple choice. To a person they said that we had done ample review and that they felt confident in how they had done. (Now I will know more about specific students later this week when the scores come out for teachers, but I do value this piece of student feedback.)

Bottom line: trust the quality of your instruction and your curriculum. Extra resources are nice, but the College Board's official practice is sufficient for getting students ready. A little exposure in the first semester and a week or two of focused multiple-choice review is plenty. Given that students will also prepare for the exam in the work they do for Explore and Create, they will be plenty prepared by course end. Also, the more students read, write, and understand code on whatever language you use, the stronger they will be come exam time; there is no substitute for this.


How do you teach when your students have wildly different backgrounds?

I don't know what options are open to you, so I'll hope you have a free hand. I certainly did as I got farther along in my career, but a newcomer might think this is risky. In fact it is well proven:

I'd suggest that you base much of the grading on the work of groups rather than individuals and I would flip the classroom. This gives you the advantage of observing the groups in almost all of their activities. The "material" and "content" of the course is obtained through readings and video, not through lectures. What happens when the students are face to face is that they work in groups to produce something, perhaps ultimately a web site in such a course as you have.

But this might not work if you scale is huge.

I think you should also create the teams yourself and assure a variety of levels and types of experience in each team. A simple questionnaire for each student on the first day can help you decide how to divide up the teams. The teams should be small, to enable simple communication, but probably at least four per team.

In such a course you also need to have the students do "peer evaluations", perhaps periodically. If you manage this well you can also achieve a fairly high degree of the better, more experienced students aiding the others. But to do peer evaluations successfully, it has to feel safe. It should be entirely positive based. In a group of five, I would ask students "Who were the two most helpful members of your group? Why? What was their contribution?"

You can modify the above to suit your course, and you can also tell the students that being seen by team mates as helpful will give a grading bonus. Don't ask students to evaluate everyone, but just to give positive comments when appropriate.

But you also need to employ "self evaluation" in any such scheme. "What was your own chief contribution to the team's work?"

The goal is to get a spirit of cooperation going, rather than competition. This means, of course, that you need to make it possible for everyone to get full marks. Therefore "grading on the curve" will ruin it, since it is a fundamentally competitive zero-sum situation.

In team based work, I also required teams to present their work to the class at the end of the course. I also required each teammate to participate in some way in the presentation. This was a bit hard on introverts, but it was a skill that they need to develop in any case if they are to have a career. Even if the career is outside CS.

Note that Peer Assessment is a wider topic than what I suggest here. I don't necessarily suggest all of that, but do suggest that peers focus on positive aspects only. This makes it "safer" and, I think, more honest. I once had to upgrade a student who I thought was slacking based on the fact that his teammates (who I knew were working hard) praised his contributions.


I am teaching part of a Maths module that includes boolean logic- the assessment included creating digital circuits, labelling each point to derive the final expression, applying boolean logic (De Morgens etc) to the expression to minimise the term (which is by far the most difficult part for learners), creating the truth table, SOP and POS, creating the K-Map and deriving the expressions, and creating the minified circuit.
After explaining the logic of each of the gates, they build some circuits using an emulator of sorts. As it happens two of the circuits are equivalent, and they result in an XOR function.  Learning point 1- XOR is useful as it can replace a bunch of other gates.
As an aside, XOR could be used to rebuild a drive bit level
HD1: 0110
HD2: 1100
HD3: 1010 (HD1 Xor HD2)

so if any one drive is destroyed, the data can be rebuilt- e.g. HD2 gets fried- rebuild new drive H4
HD1: 0110
HD3: 1010
HD4: 1100

It's an interesting and pretty cool application of XOR.
In practise XOR can yield some nice circuit reduction but learners do tend to find it difficult using XOR in minimising.
In terms of the importance if minimising, I look at the reduction in complexity and the real-life reduction in cost- number of gates and thus the number of chips, board space and layout time.
Here is a completed labelled circ from a previous assignment completed in Logisim:

Now, this can be reduced to 2 NOT gates and one OR. I should 'warn' that Logisim can generate the minified (SOP or POS) term, the K-Map and terms and generate circuits as well- which might be more than you want it to do.  At worst you could use it for creating some useful examples.

Here's a board from the 1970s. It's hard to make out any gates but there is a 74LD274 (3-input NOR gates) on there- hard to read. Given that the hardware "is" the software to a large degree here, the importance of reducing complexity and chip count was important. As already pointed out- it's not as important these days, but application of logical thought is just as important in software design.  An appreciation of the complexity implemented in hardware design is important, I think.
I hope this might help with linking these elements together with K-Maps, since I suspect that you also cover these other topics.  As to how much focus you place on each part, you'll have to decide how much importance you place on each.  I think the outline of sub-topics is pretty good.


Detailed lecture series for automata theory or theory of computation

In the course I co-teach on Automata, Computability and Complexity Theory we use the excellent videos by Harry Porter to replace our classical lectures, and use our contact hours instead to practice with the material together with the students.

Porter follows the book "Introduction to the Theory of Computation" by Sipser.


Best Way to Explain Distinction Between Void vs. Return Functions in JavaScript

A function to perform a procedure often has a void return type. For example:

function foo(a, b, s)
{
    // tell sphero s to go one direction a, another b
}

You are executing a procedure as a side effect and are not returning a computed value.


What evaluation methods can be used that don't involve testing but are adaptable to online courses

As part of an algorithms module (first-year undergraduate level), I got students to choose a computational problem from a list of options I provided, write an algorithm to solve it, and write a 750-word report explaining:

The problem in their own words,
How their algorithm works (with code), and
How they tested it.

Students had a few weeks to complete this task, worked in their own time, and then submitted their report to the university's Moodle site; so this kind of assessment could work equally well in a non-face-to-face course.

The idea behind asking students to explain their algorithm came from the fact that interviewees for software jobs often have to solve a problem during the interview and explain how their solution works. Being able to explain how one's code works is also important for many other things a programmer might do, like rubber-duck debugging, code review, or writing good answers on Stack Overflow.

Your question doesn't dwell on it, but one of the key differences between in-person and online assessments is the opportunity for cheating and the difficulty of detecting it. As a convenient side-effect of having students explain the problem and their solution in their own words, suspected cheaters can be identified in two ways:

A student who is unable to write the code themselves is usually also unable to adequately explain how the code works.
A student who also copies the explanation (or parts of it) can be detected by standard tools such as TurnItIn, so you don't need a more sophisticated tool for comparing code similarity.

In the former case, a poor explanation deserves a low grade anyway, whether or not they cheated. In the latter case, my experience of running the assessment over two years with ~250 students each year is that TurnItIn works well enough for catching students who copy from an online source or from each other. With fewer students, you can group the assessment submissions by which problem they attempted, and probably notice any collusion yourself even without a tool like TurnItIn.


How can Chatbots be useful in CS education?

I'm using chatbots to discuss a variety of topics with 14 to 16-year-old high school students.

By "using" I mean that they are the subject of instruction, not a study aid / instrument for the students to use to get automated answers to frequent questions and things like that. So that's probably not what the book you mentioned talks about, but I'll go on anyway because your title asks the more open

  How can chatbots be useful in CS education

Chatbots are a great topic in computer science education because

Everybody knows about them - teenagers know what chatting is and have first-hand experience of doing it, and most students have either encountered a chatbot already or they've heard about Siri and compatriots, which can be framed as chatbots for the purposes at hand.
There are chatbots who try to mimick humans, so you can use them to discuss the Turing Test with your students
Simple chat bots which simply look for some combination of words in the input phrase are easy to build using scripting languages such as Python, and therefore can be used to give the students a first feeling for what needs to be done in order for a computer to correctly identify the meaning of a sentence in a human language. This can easily be extended into a discussion about whether computers can "understand" us.
Coding simple chat bots is easy enough so that it can serve as a first small project for beginners learning to program
In my classroom experience, teenagers love spending some time writing simple chat bots and getting them to provide (often somewhat rude) answers to things their peers type in, so it's a fun topic, too.

I agree with Buffy that using chatbots as a study aid is much, much harder to get right, and I wouldn't try that unless the domain was very, very well specified.


Where can I find high-quality editable slides for teaching git?

I know of no freely/commercially available presentations, but I do know of a site that feels a lot like a presentation as you use it: Learn Git Branching. It's interactive and gives a hands-on intro to the most basic git features as it explains them. Plus, everything is visualized in real-time, so you and your students get instant feedback on what the command did to the pretend repo.
My thought is that you could either use that site in front of your students (or perhaps just use git itself and some sample files), or you could have your students use the site and follow along with you.
Honestly, from my own experience, that site (along with using git on small practice projects) was exponentially more educational/memorable than any presentation I've seen so far at my university, or found online. I don't just agree that making your own presentation would be a waste of your time, but I think you should consider a different format all together. Git, just like programming, is better learned through doing.


How do you encourage students to take criticism of their code constructively?

Here a few techniques I use in my class when giving feedback on student code:

Use a rubric. CS50 has a clear grading approach: code is assessed along the four axes of scope, correctness, design, and style. Within style for example, I might focus particularly on readability vis-à-vis indentation. If a student is marked down on this item, she knows exactly what she missed and why she may have lost points. The clearer the criteria of evaluation, the better the student response to being assessed on said criteria. I also think it's valuable to share rubrics in advance. Only seeing it after the fact can make students feel like how they were being graded was being kept a secret, which can lead to resentment of feedback.
Avoid "you" statements. This is something I caught myself doing and tried to correct as the year went on. Let's say I'm reviewing a student's code, and I'm commenting on the naming of variables. I might be tempted to say, "You have unclear variable names here." That frames it as an assessment of the student, not of the code, which does not set the right dynamic. I try to make sure I say something like this now: "Your program has unclear variable names here" or "to improve your code, make your program's variable names more precise." The goal is give feedback on the code, not the coder, so language should reflect that focus. (Side note: with how personally code reviews can be taken, I think how we frame the language of assessment is essential to building proper classroom culture when it comes to grades and feedback.)
Reward revision. This one is possibly more applicable at the high school level, but I think it does matter in terms of building a culture of receptiveness to code review feedback. Allowing students to revise their work gave me the ability to see students improve their work based on my commentary. In my mind this is what education is all about: inspiring a continual learning process. The pragmatics will vary from context to context, but requiring some sort of revision or reflection or allowing students to "recover" some/all lost points communicates to them that at the end of the day, you want them to be better programmers. Grades take a backseat to learning. Again, this might make less sense for university students, but in my class this approach goes a long way in terms of students constantly working on improving their craft.


Most beneficial CodingBat problems for AP CS A FRQs

They've got an AP-1 category which is based on past FRQs. Not the whole question, but pieces. I'd make sure you hit every one in that category during the year. The String-2 and Array-2 are also good.

I use CodingBat and similar questions as warm-ups all year long. We start pretty much as soon as students are able to fill in a method.

Pretty much anything that involves looping through strings or arrays will help them with the test in May. Usually 2 or 3 of the FRQs involve iterating through some type of list structure and doing something with the values. I try to get my students to a point where they really don't have to think about loops, they just type on when they need it.


I will attempt to break down your query as best I can:

MOOC open source that I could install on my servers to provision education: Canvas, Sakai or Moodle, BUT the downside of having these on your own servers are that you have to complete the updates yourself and many institutions do a "fresh install" each Summer during break.  It is worth considering a cloud version (LMS): you can get a Moodle account on Moodlecloud.com or try out canvaslms.com; Depending on your specific use-case, would Google Classroom work as an option?
ready to use CMS (content management system) type of software...  course content management, I used to upload all of my content to the LMS- these days I structure all my notes, exercises, files, presentations etc. into a folder in my DropBox/OneDrive/GoogleDrive.  I can folders of notes as a link in the LMS.  The advantage is that I can:

Add/Remove notes
Update content

all without having to delete old notes/upload new notes.  I can simply manipulate files on my computer which will synch with the online drive- the LMS acts as a repository of links and the content is elsewhere, and more easily managed.

This is a setup I suggested for a company that are planning to introduce an LMS where I also suggested hosting all the links on a thinklink as well- very little is actually in the LMS, but it's used as a repository.  The advantage (imho) is that is allows you to rebuild your course and use resources in other courses more easily, so you can update once in one location, and the "linked resource" is updated wherever it is used:

watch lectures, and interact with TAs.  All LMS allow you to embed videos (better to embed from YouTube or similar rather than upload large videos to your own server) and provide a chat or forum feature.  If the forum-type/chat in the LMS does not suit you, you will find something like Disqus that you can embed into the course.
students could run pieces of code.  This is the trickiest.  I sometimes write tests that the students can download and run to test their own code. It gives them a chance to look at "test code" and if they take the time to figure out what the code is doing, they will learn something.

It is much more easy to use a MCQ quiz to autograde.  Cloze question types have words missing so this could work in a quiz format.

Another option is to use peer grading and to give each student a rubric to mark peers- often used in many MOOCs and I've done it in Moodle in the past.

Use a site like Rosalind or CoCodingBat for exercises and grading

If you want to write your own specific test conditions, then CodeHS might just give you the features and flexibility that you want.  Because these code graders are not (afaik) integrated into the more popular LMS, you could have the student post a screenshot of their code passing the tests (or not).

If you want something that will return the grade to the LMS gradebook, then there may be something that complies with the (relatively new) Common Cartridge but I am unaware of a tool to meet your requirements at this time.

Hope that this helps answer your question, and that it is of some benefit to you.

Sean.


What are effective approaches for teaching dynamic programming?

I think it's really about breaking down the concepts into smaller pieces. First a student needs to understand recursion well, then they can understand memoization and dynamic programming. It's hard to just jump into  e.g. the knapsack problem without first having worked through simpler problems. After one gets practice with the basic concepts, dynamic programming isn't inherently so difficult. Here's a basic way one can break it down:

Recursion

As an alternative to loops
Binary search
Divide and conquer
Backtracking

Memoization

Backtracking can be inefficient. Why not cache the results as you go through them?
Simple problems, such as reaching a specific sum with certain coins.
Can then consider harder problems, where a 2D array is required.

Dynamic programming (DP)

Consider the coin sum problem again. How would one be solve it manually for the numbers 1 - 10? Can this "build-up" solution be put into code?
Solving more advanced problems with dynamic programming instead of recursion/memoization.
Identifying problems for DP approaches - Partially this comes with experience of solving a few different problems. But there's a standard pattern one can recognize - if a recursive solution can be used to get a solution very inefficiently (by repeatedly searching through the same subproblems), then memoization and DP can be used to make it more efficient.

(If you're interested, I also created a free tutorial on Recursion that breaks it down as above with programming challenges.)


I'm going to clean this up later, but am posting the verbatim work of the CSTA members so others can chime in with additional bullets. I'm aiming to have one resource per bullet: Resources name, link, annotation, example ideas for projects

How about CSV Data Sets at https://vincentarelbundock.github.io/Rdatasets/datasets.html
Maybe there’s something there which would appeal to MS kids. (Joe Kmoch)
Look at the Mondial database, supposedly based on the CIA's World Fact Book. (https://www.dbis.informatik.uni-goettingen.de/Mondial/) It's in various  formats other than CSV (various relational databases, XML, etc)  but should easily be exported to CSV form ( see http://www.convertcsv.com/sql-to-csv.htm) . It's got dozens of relations, and is sizable enough so that you really do need to query it via a program to answer questions. (Doug H)
There are some links on my BigData webpage ( under #4.) that could be a lot of fun
https://sites.google.com/a/pgcps.org/livecode/big-data/bigdata---projects (Cyril Pruszko PGCPS)
I had fun in the past using First Fleet. See firstfleet.uow.edu.au (Andrew Williams and Simon Carter)
Titanic passenger lists (Simon Carter)
Census at School asks lots of different questions of hundreds of thousands of U.S. students and has data by grade and state. My students have used the data for linear regression and chi-square tests. (Andrea DePaolo)CensusAtSchool data works well with middle schoolers. I had 7th graders measure their height and armspan and add their own data to the CensusAtSchool's set using a googlesheet. (BB)
In the UK, publicly accessible historic weather data is useful and offers some lovely cross curricular links to science, maths and geography: http://www.metoffice.gov.uk/public/weather/climate-historic/
I think something rather more comprehensive in the US is available here: https://www.ncdc.noaa.gov/cdo-web/datasets (Miles Berry)
https://www.data.gov/  (Ty Davis)
Wikipedia has some extractable data https://www.tableau.com/about/blog/2016/2/excavating-data-gems-wikipedia-50966
(Ken Price in Tasmania)
Tuva labs tuvalabs.com (Jon Mannion) is an entire data exploration environment with curriculum and a browser-based interface that allows students to drag various variables from a data set onto axes, akin to SPSS or Fathom.
http://stats.oecd.org/ has some OECD datasets
(Ken Price in Tasmania)
Google also has a Public Data Directory at https://www.google.com/publicdata/directory and a data exploring tool.
(Ken Price in Tasmania)
What about Bart, A. C., Whitcomb, R., Kafura, D., Shaffer, C. A., & Tilevich, E. (2017, March). Computing with CORGIS: Diverse, Real-world Datasets for Introductory Computing. In Proceedings of the 2017 ACM SIGCSE Technical Symposium on Computer Science Education (pp. 57-62). ACM.
CORGIS Datasets Project
https://think.cs.vt.edu/corgis/  (Francesco Maiorana)

Here are some additional links from my bookmarks

The KDD Cup is an ~annual competition for the public, aimed at grad students and professionals. Past year's competitions are on the website, usually with the data, and middle schoolers could use the data for easier tasks than the KDD Cup challenge posed.
Kaggle is akin to and overlapping the KDD Cup.
Teenagers like music. The Million Song Data set could be used to compare song length by artist, for example.
An image makes for a nice large data set and motivates students to understand nested loops, conditionals, the accumulator pattern, and the best-so-far pattern. I have students pick their own image and decide upon their own task for data analysis (e.g., range of brightness or number of pixels that meet a color criterion) and manipulation (e.g. change brightish yellows to magenta.)
CODAP, the Common Online Data Analysis Platform. A project of the Concord Consortium, led by the person who led development of Fathom, a stats software for K-12.
I wish there was a women's basketball version of this set of links:

NFL plays in CSV: http://archive.advancedfootballanalytics.com/2010/04/play-by-play-data.html
News article about Big Data in sports, reading across the curriculum: https://blogs.wsj.com/cio/2013/02/06/big-data-in-big-sports/
Programmers' discussion thread about handling football data: https://news.ycombinator.com/item?id=5002974

The Social Security Administration offers CSV files of name frequencies by birth gender and year. State-level files are also available by gender and year.
The UC Irvine Center for Machine Learning and Intelligent Systems has the Motherlode Machine learning repository of datasets. You can search by domain (e.g. life science), by the data set size, or by the type of task students would typically do with that data.
GapMinder has raw data files of World Health Organization data as well as an online tool for exploring the data along with interesting examples.
Exoplanets databases
The Current Population Survey (CPS) asks 60,000 U.S. households each  month about income and employment. You can download CPS data tables and can create your own table with the CPS table creator
A similar question on Quora
Earthquakes From USGS, https://earthquake.usgs.gov/earthquakes/map/ allows the user to filter earthquakes by location, date, and magnitude and download a CSV. The website has built-in geographic visualization. (Contributed to PLTW CS Principles course by Nathan Nolte)


NodeJS and Javascript libraries are overwhelming students

Summary

Node.js has an unusually complex ecosystem which you don't get in some other languages.
Your students spending time to intelligently pick the best libraries is great, but you might need to stop them from being bogged down.
If time is really a problem, simply take away the choice, but keep in mind that you take away a powerful (and necessary) learning experience.
Remember that not every problem needs a library; it's fine to re-implement simple things yourself!

Node.js (and the JavaScript world in general) seems particularly prone to short-lived, highly popular libraries and frameworks which re-invent existing features in different ways. You need only see the Stack Overflow blog which illustrates this trend well enough:

I've developed web applications in the past where I've agonised over the choice of libraries for hours — even days — trying to find that perfect combination which will avoid all these potential future issues... issues which, it turned out, weren't likely in the first place at the scale I was working at.

Initially, I heard great things about React, so I decided to add that to my project. Then I need a 'Flux framework' too so I can handle events in a React way. So I pick one like Redux. But React doesn't degrade so well for clients without JavaScript — oh no! Luckily, there's already a solution for that — server-side rendering. So I plan to use that too. I'm sending a lot of assets at once now, which is starting to get slow, so for HTTP clients I want to bundle my assets with Webpack. But I don't want to do that for HTTP/2 clients because that's actually slower again.

That's not even the end of the story, but you're starting to get the picture of just how many pieces exist in the JavaScript world. I honestly don't know many other languages that are so chaotic vibrant with their library ecosystem.

Honestly, your suggestion of just going by the download counts seems unwise in some respects. While popularity does probably offer a good indication of maturity and stability, it doesn't tell you whether the library actually does what you want, in the way you want.

Let's take my React example again. Yes, it's popular, and indeed, it is a front-end framework, but it requires a lot of 'buy-in' — you have to deliberately design your pages around React to get much out of it. jQuery might fit my use-case perfectly, despite being a little less popular, but by just picking the popular library, I'm stuck with even more work.

As an analogy, how do you pick which car you want to buy? You probably don't buy a Ford Fiesta just because everyone else did. You probably take a look at the specifications, fuel economy, and perhaps give it a test drive.

Putting that investment in and learning a little about the popular libraries is well worth it. You only have to do it once to learn the philosophy and the goals of that project, and once it's done, you know when you want to pick that library above the others.

You can try and tell them metrics to look at... or you can accept that you need to dedicate time to trying the popular libraries, and getting that 'test drive'. Spend a lesson trying React, and get your students to tell you what they think. Going beyond the trivial 'Hello world' might be helpful (I hear the TodoMVC example is fashionable and more complex).

Or, if you can't afford the time, I think you'll simply have to tell your students which library you want them to use. What your students are doing now is great, if a little inefficient. You can help by prodding them in the right direction — share what you know, and give them a nudge if they start burying themselves in too many libraries.

Sometimes, I think all that's needed is a little poke to say that not all JavaScript projects need to handle every possible future concern, and to Keep it Simple, Stupid.