Programming curriculum for elderly students

If the students in this course are the same ones, or similarly educated, that finished the last course, you could be over thinking the issue. They don't yet have the exposure to know they want to become programmers.

Design the next course as an Introduction to Programming. To borrow from the course catalog for KCTCS pg. 253:

  Computational Thinking

  Promotes understanding of computer programming and
  logic by teaching students to think like a computer. Covers
  skills needed to develop and design language-independent
  solutions to solve computer-related problems. Covers
  development and design basics including use of variables,
  control and data structures, and principles of command-
  line and object-oriented languages.

That should give the enough knowledge to choose programming as a second career if they want. As an alternative, you could do web page development. That gives a faster return on their work, and allows you to also cover programming using JavaScript. Web page creation is something that more of your audience can potentially utilize in personal life, without having to make a career out of it.

As a third course you could get into the theory and "nitty-gritty" of programming.


What are good resources for self learning Finite Mathematics for a CS Student?

John Kemeny et all have published a set of books on Finite Mathematics that are classics. They have lots of exercises but no solutions in the books themselves. However, the solutions guide may be available for some of them online or especially at eBay with a suitable search.

One of the classics is Finite Mathematics with Business Applications. Don't let the title fool you. It is serious mathematics.

Another, more common and possibly lighter weight book is Introduction to Finite Mathematics

These books are both old and out of print, but readily available. I think the latter one is available as a PDF online (but without answers).


Actually, the similarities between C++ and Java are fairly shallow and the differences are very deep. The syntax of both is derived from C, but the underlying ideas are very different.

The biggest difference is that an "object" in C++ is built on the stack, like a struct, not on the heap. It takes additional work and a lot of understanding to become comfortable with the differences. If you do create objects on the heap (with new) you need to understand the differences between pointers and references and these can be the source of hard to debug errors. And you need to be absolutely pure with deallocation. Every object needs a known lifetime to the programmer, whereas Java handles all of that automatically.

C++ has no garbage collector for heap objects, so the memory management problem needs to be solved for every application, unlike Java where it is solved once by the run-time system automatically. Smart pointers in C++ can help a bit with this but are not a complete solution. Memory leakage for non-trivial applications is a serious issue.

The visibility of things is also fundamentally different, with "friend" classes complicating the mental models of complex systems.

Don't underestimate the difficulties. You will likely have a lot of work to do to get the students comfortable with quite different mental models and with practices and idioms that keep them safe.

James Gosling once described Java as C++ without the guns, knives and clubs. You will be trying to program with all of those pitfalls, when the students, coming from Java, have little experience with them.

Their experience with C, if deep enough, will help with the memory management issue, but not with the complex (i.e. dual) object model of C++. You should become familiar with good memory management tools and practices if you want to do non-trivial things in C++.

I was once stopped dead in a C++ project by a deallocation error for 24 hours. The solution required a 1 character change in a file. One character of progress per day is very bad, though I was an experienced programmer and actually knew why it was failing.

Your own experience with C++ seems shallow from the statement of your question. I'd suggest that you work hard on that before you attempt to teach such a course. Especially, build something that requires sophisticated memory management and test everything as you go. You can't think of C++ as just mis-spelled Java, nor Java as just mis-spelled C++. The conceptual differences are many and deep.

My own experience as a programmer (and author)` is that Java helps me program correctly, but C++ fights me constantly for every inch of ground. I could build some beautiful things, but the fight was constant and brutal.


Undergrad level computer architecture course

My go-to answer for this topic is Nand2Tetris.

There are 2 Coursera courses (Part I and Part II) that match the curriculum of the program. The first course does not require any programming background. Its focus is on computer architecture (logic gates, half-adders, full-adders, ALUs, RAM, ROM). The second focuses on a virtual machine and a compiler for a high-level, Java-like language (and thus does require some programming knowledge). The essence is that you understand every level of a computer from the NAND gate up to a "hello, world" program in a Java-like language.

In addition to the Coursera courses, there's a companion textbook and a full suite of software. The list of topics is below:

Boolean Logic
Boolean Arithmetic
Sequential Logic
Machine Language
Computer Architecture
Assembler
VM I: Stack Arithmetic
VM II: Program Control
High-Level Language
Compiler I: Syntax Analysis
Compiler II: Code Generation
Operating System

The course is typically a lower-division, one-semester, university course. The site contains a sample syllabus, which might help justify it being rewarded with some form of academic credit.


How to share solutions in a way they won't get uploaded

I don't have real answers, and I suspect there are none.  I also reuse prompts, if only because good ones are almost absurdly hard to come up with, write-ups and supporting code take time, etc, etc, etc.
I've taken a series of steps to mitigate the cheating.  Some of these are peculiar to my own situation, and may not translate directly to another context, but they also illustrate the type of thinking I use when I consider this particular (and particularly intractable) problem.
The first is to not weigh labs heavily in the grading.  This sucks, because they are a huge portion of both the work and the learning in the class, but they are not trustworthy as high-stakes assessments if you do your assessment at the end by looking at the final result. (There is genuinely no getting around this fact.)
I explain this to my students, and encourage them, then, to use the labs as learning opportunities. The brunt of their grade comes from tests and quizzes. The labs help them to prepare.
Next I talk about plagiarism.  I require them to keep in comments links to stackoverflow, indications of where friends have helped them, and any other sources they used.  I point out that even very veteran software developers use stack overflow regularly, and I assure them that this sort of help is not cheating as long as it is cited.
Next, I make sure that my lab write-ups are extremely clear.  Cheating typically centers around nervousness more than laziness. When students feel like they are not quite sure how to be successful, but nevertheless fear the consequences of failure, cheating is a natural outcome.
Then I have in-class working sessions where I go around and observe how the students are doing, and help them get un-stuck.  This allows me to see regular progress, and helps the students to learn from the labs.
Finally, I grade some of the labs as code-review interviews, and award a harsh, current grade, and a second, more generous grade for once the required refactoring is complete.
I don't believe myself in thinking that this entirely nips the problem in the bud, but I have reason to believe that the outright copying is minimal in this setup.


How to explain the int() function to a beginner

First the reason for the failure. Function int wants either a number or a string that represents an int (from the Python 3 docs). The first part covers your first two examples and the second part covers your third.

However '5.5' isn't a "string that represents an int", hence the failure. It is, of course, a string that represents a number, but that isn't the same thing.

But

int(eval('5.5'))

will return 5 since eval will return a number that int will be able to work with.

Now, how to explain it. There are two options (at least). The first (worst) is just to tell the kid that the world isn't magic and int only works for some things, but doesn't handle everything.

But it makes more sense to treat it as an exercise in careful reading of specifications. Read what the specification does say and what it doesn't say. Specifications are meant to be precise.

You can make it a lesson about reading the manual when you get confused, or writing test cases to explore the range of possibilities.

You can make it an lesson about searching for an alternate solution (i.e. eval) when something you try fails.

You can make it a lesson about "when you are older and get to design things, spend some time getting it right." I haven't explored whether there is logic behind the decision to not include such a case as your fourth example, but I doubt that it was an oversight.

See the note by @ctrl-alt-delor. Function eval permits the evaluation of arbitrary code, not just simple expressions. It shouldn't be used, for example, with unexamined user input strings. It is safe, however, provided that you have control over the argument in some way.


When mentoring individuals, teach clean coding and simple/effective thinking or let them do it their way?

As someone who has now taught CS for many years, let me first reassure you that teaching clear, clean coding is entirely worthwhile. I think this is especially true for those who will not go off into software professionally, because editing, and being able to express ideas in a clean, clear manner is a skill that serves people well in any field.  (I've written a bit about my approach to teaching good coding style before on this site.
Now, USACO is something a bit different. These competitive programming situations are designed for coding speed, program speed, and correct output.  You get no points for maintainable code, clear thinking, or reasonable variable names.  These contests can be great learning experience as long as the student understands that they are getting intense (and good!) practice on only one small piece of a larger puzzle.  I would definitely try to contextualize this for the student, though I caution you that you may never win over this particular student. He may have already become somewhat set in his thinking.
Here's something silly you can do to attempt to demonstrate the value of clean code to the student: take some nice, clean code for a USACO-style problem and introduce an obvious edge-case bug that crashes the program (an array out of bounds or somesuch).  Refactor it to give it USACO-style names, like m and pf. Shove everything into main.  Make sure that there are no strings to make obvious what the program is supposed to do.  Reverse loop styles to make them less appropriate (i.e. switch for and while).  Screw up the indentation. Generally make a mess of it.  Have fun!
Print out your spaghetti onto physical paper and ask the kid to find the bug. You can even tell him the type of bug. Tell him he had 10 minutes.  At the end, ask him what the whole thing does.
Then give him the original version, with clean names, good use of functions, comments to explain what the functions do, and generally clean design. Ask him to find the bug again, and ask him what the code does.
Now tell him that he's just been hired to maintain hundreds of thousands of lines of buggy code that someone else made.  If the code all looked like the first example, how long would he give it before he quit that job?


Dealing with students who are underly-motivated

You've mentioned before that your students are adults who are attempting to make a career change to a programming role. With that in mind, I think the best thing you can do is show them how what you're teaching helps them achieve that goal.

Think about it from their perspective: I'm an (older?) adult, who has had a "real job" for the last X years. Now I'm trying to change careers. I want to know how to get a new job, and how to perform the tasks of that new job. So it's hard for me to sit in a classroom and memorize stuff from a textbook and from lecture slides.

You and I know that memorizing that stuff will help them in their new careers, but that's not always obvious to students- especially novice programmers.

So my suggestion is to always make sure that your lessons directly tie into their goals. Find out what kinds of applications they plan on working on. Make the first assignment a very basic version of that. With each lesson, build on that assignment so that every step gets them closer to a "real life" end product.

Instead of saying "okay now you have to memorize that" and pointing to some lecture slides or a textbook chapter, ask "how can we improve our product?" and then show them concrete things they can do to make those improvements. The lectures and the textbook become references that help get them to their end goal, which I think is easier for professionals to digest.

For a concrete example, let's say your goal application is a point of sale system. Maybe your first application is a command-line program that mimics a basic transaction. Then the next assignment introduces variables by having different items with different costs. Then maybe the next assignment introduces if statements that apply coupons. Then you could have a lesson on creating a basic GUI, or using for loops to repeat actions, etc.

That's just a dumb example off the top of my head, but you get the idea: use your students' goals as a motivator, and tie your lessons directly into those goals. At the end of your course, students should have specific concrete usable information and a newfound ability to accomplish their goals.


What does a certification program for CS high school teachers need to include?

The College of St. Scholastica in Minnesota has a Computer Science Education graduate certificate program. It is a four-course sequence designed to add a CS endorsement to a high school teaching certificate, though no state-issued endorsement exists yet in Minnesota. The courses:

Computational Thinking and Standards for the K-12 Teacher
CS Principles, covering the AP CS Principles course description with additional material covering pedagogy and CS pedagogical content knowledge
Programming and Teaching Java, a Java-based course covering the AP CS A course description with additional material covering pedagogy and CS pedagogical content knowledge
CS Methods and Capstone, covering pedagogy and CS pedagogical content knowledge, CS education research, and development of a CS curriculum unit


I will draw on and supplement my answer pointed to in a comment.
The main things you need to create for a course are

A syllabus, listing topics and how much time (approximately) you will spend on each one.

A list of student activities (exercises and projects) that they will be required to do to learn the material. This is the most important element.

A way to give individual feedback to each student on their work. This can be hard, depending on scale, and may require assistants at large scale.

A way to get feedback from the students on their learning and on their perception of the course.

Some mechanism for delivering the content of the course. This can be lecture, books, notes, videos, online materials, etc. Don't assume that lecture is the only possibility.

When creating the first draft of the syllabus, it is helpful to have more material than you can likely cover. But it is essential that you know which topics are critical for the students and which might be dropped when time becomes an issue. Students can learn some things on their own, of course. Make sure you have a timeline that will include the critical topics.
When creating the student activities, make sure that you emphasize the critical topics. And, for a first time teacher, realize that people learn through reinforcement and feedback. Nobody learns much on first seeing or hearing it. You need to actively engage the brain. This normally implies some repetition, both in exercise and in lecture. But feedback is also necessary so that students don't somehow draw the wrong conclusions from what the see, hear, and do. A simple grade on an exercise is not sufficient. Individual face to face discussion is best, but usually infeasible. Written comments are the normal compromise.
To obtain student feedback I always found that an anonymous channel was useful. In fact, though it feels scary, a public but anonymous channel. If a student said that the course was terrible in some way, but it wasn't, other students would correct the writer. I didn't ever need to respond. Students often do course evaluations at the end, but that isn't sufficient to let you make corrections if necessary. A periodic questionnaire is one mechanism.
Some things to consider about course structure.
The main thing to look at is how you use face to face session. Do you "broadcast" material via lecture or otherwise or do the students use that time as a laboratory. If the latter, then content is made available to them at other times, through videos or written material. This is called a flipped classroom and a lot has been written about it. You can also do a hybrid, with some course sessions devoted to lecture, some to questions, some to lab work, etc.
One advantage of the flipped classroom, especially with young students, is that you get to be present to monitor their learning in real time. But you will need a way to make sure that they actually study the content. A short daily quiz is one possibility if it becomes an issue. Another is requiring a one page written summary of the material studied.
The next important thing to look at is how much collaboration and group work you will permit and require. For some things it is useful for students to be required to work strictly alone. If that is the case, make sure that you have made the rules explicit. But in computing, especially, group work is very valuable and so, at some point, it should be permitted. At some point it should be encouraged. At some point it should be required.
For group work you need to decide who defines the groups and how. Self chosen groups sometimes works, but not always. There are advantages for instructor chosen groups as well as for self chosen ones. One interesting way to choose teams is for the instructor to choose team "captains" and for the captains to choose team members in rotation, as is done in forming "sandlot sports teams". The captains can serve as communication conduits with the instructor, but are not, explicitly, team managers.
For group work, also, it is best to discourage (or forbid) "simply" dividing up the work between members. This is almost always a failure with novices. They don't realize that it adds a complex step of integrating their individual work and often fail at it. Likewise any underperforming member can end the success of the whole group.
It should be obvious that communication is essential in education as it is done today. I find it useful to find a mechanism in which students can always get their questions answered, either by myself or by another student. For this I provide a mailing list to which every student is subscribed. Students are encouraged to ask and answer questions, but also adhere to any sharing rules in place (no posting code...). I found this more useful, being asynchronous, than group chats, though I also used those on occasion, posting a transcript after the chat finished. This might be less essential in a flipped classroom, however.
Some things to consider when delivering the course for the first time.
You will most likely have too much in the syllabus and will almost assuredly try to do too much. Not an absolute, of course, but pretty common for a new teacher. So be prepared to be especially flexible with everything, including grading. Focus especially on the student tasks and on their progress, not on your own activities (lectures,...). If they have a good experience, then they will be encouraged to continue their studies.  If not, they may decide to leave the field unnecessarily. That doesn't mean being "easy". You can be demanding, but you have to be fair. You have to be reasonable.
I'll note, in particular, that a large project in a course can be a "success" even if no student or group completes it.
You also need to be aware, especially at novice levels, that the students may not be experienced learners. Many students find things easy for many years and don't learn how to apply themselves. But then, they hit a block and don't have any skills to carry them past it. This is one reason we require that exercises be done as homework or otherwise.
But students also may not know, and likely don't, how to take notes effectively and extract key ideas from readings. You may need to teach them how to do this and require it. Again, repetition is key. Taking notes and never looking at them again is not especially effective. Making summaries of your notes is much better (reinforcement).
And don't forget to make notes for yourself about each student. This goes beyond grades. A note-card for each student is useful, noting any blocks you see or any special requirements. Dating each interaction can be useful if conflicts ever occur.
Finally
Do a retrospective after the course to set an initial plan for the next time you do this course or something similar. What works. What needs to be improved. Keep notes for yourself.
Keep in mind that the course is a success if the students learn something useful. You can feel like it is a failure, but it isn't if the students succeed. Sometimes stumbling when answering questions and not knowing the answer, immediately, to a question is a good thing. Some things are hard and it doesn't do the students any good if they get the misconception that they are always supposed to be easy. When that happens they can feel like failures, when things are really just hard.


How can I maintain interest in front end?

As Choirbean noted, this is fundamentally a question of motivation. I don't think it's about making something more "exciting." That is, the secret is not in something extrinsic, which is what makes this such a challenging issue whether it be front-end development or really any topic.

I draw on Daniel Pink's TED Talk whenever I think about getting students to do something. The gist is that there are "three elements of true motivation -- autonomy, mastery, and purpose." The key to start is autonomy; students need that freedom of choice to get personally invested and be motivated by more than a grade.

I can speak to autonomy with front-end development based on a project I did this year. I assign two HTML/CSS assignments. For each, they can make anything they want the subject of their pages: a travel destination, a TV show, a sports team, anything. That was the key. They were so excited about describing something they loved that they were invested enough in the topic to work on the HTML/CSS.

The requirements of the first assignment were the following:

DOCTYPE
html tags
head tags
body tags
title element
header element
paragraph element
proper filename
bonus: comment with HTML definition

As you can see, it was elementary. That way they had mastery of HTML basics (i.e. the DOM) and could then grow to build something more sophisticated and aesthetically pleasing. With the second, they had to include the following:

table
link to external website
button
two divs (with div IDs)
list
heading
paragraph
three images
text not left-aligned
two fonts
three colors
additional HTML feature
additional CSS feature

Nowhere did I grade the subject matter of their sites. Rather, I focused on the skills they needed to demonstrate competency in and let them prove to me -- in whatever form they liked -- that they were indeed competent in them. That freedom, to me, made the difference in motivating students to want to complete this work.


You could extend (heh) your lesson to include custom painting.

Basically, you do this by extending JComponent or JPanel and overriding the paintComponent() function. This is how "real" Swing components draw themselves, and it gives students a window into how everything works behind the scenes. You could have them draw  basic scenes, animations, or even games. Or you could have them create custom components like circular buttons (disclaimer: I wrote this example).

If you have enough time, you might want to split this into multiple lessons: start with basic Swing, then do a lesson on input listeners, then do a lesson on custom painting. At the end of those lessons they'll have enough knowledge to create some pretty fun programs.

I'd also urge you to stick with functional GUIs instead of using a non-functional chat application. Make a fun calculator that does something like convert dog years, or create a basic game that plays rock-paper-scissors. Encourage students to make these as interesting as possible. IMHO this is much more engaging than a non-functional example gui.


Best way to pass on the problem solving experience

In places that use the ideas of agile software development, the usual way is to just let the newcomers pair with the more experienced members in all tasks. In your case it would consist of a lot of pair programming. But you would need to do it correctly. It isn't one person programming and the other person watching. Both participate, but in different ways. See Pair Programming Illuminated for a specific description or Extreme Programming Explained for a more complete description of the whole process.

The experience of agile shops is that pairs produce about as much as people working individually (there is research to that effect) but with higher quality. (Specifically, the hypothesis that individuals produce more in total is not supported).

But more so, the newcomer is immediately introduced to the local process in an active way and can start to be productive much sooner. However, the experienced member of the pair will need to turn the keyboard over to the novice frequently (roles switch every several minutes, not hours), and both will need to learn to adopt to the individual roles of "driver" and "navigator".

Pairing combined with faithful use of test first development is especially productive of high quality software, but you need to actually practice the skills, not just talk about them.


I highly recommend checking out a language called Processing. Processing is designed for novices, and makes it easy to create visual and interactive programs without a ton of boilerplate.

Here's an example Processing sketch:

void draw() {
  ellipse(mouseX, mouseY, 25, 25);
}

This is a full program that draws a circle wherever the mouse is, 60 times per second.

Related:

Using Processing as an entry point in an Introductory Course
Programming languages specifically designed for beginners
The order of subjects in beginner's curriculum
Order to Teach Topics in an Intro Programming Class
Make it easier, and quicker to get to the start

Shameless self-promotion: I wrote a series of tutorials for Processing available here. I'd love to talk more about using these in a curriculum.


Feedback request: an assignment on programming a research paper

With regards to your setup, one concern that I have is that the steps might not make a lot of sense, at least as written.  It would be very useful if you provided one exemplar of what you mean for a summary to look like, and what you would like an algorithm "run by hand" to look like.  For the first part, a summary could mean two sentences, or it could mean a few pages with diagrams that break down the activity.  As for the second, I am not sure what is meant by "run by hand", and it would not surprise me in the least if others also find it confusing.
Now, there is the question you didn't ask.  Structurally, a course with 88% of the grade as a final exam is, for all functional purposes, a course with 100% of the grade as a final exam.  Why devalue all of the work, and permit a single bad day to destroy a student's entire semester (and possibly put their entire academic career at risk?)
I once had a student come into an exam several hours after her mother and brother died in a catastrophic car accident.  She didn't say anything, sat for the exam, worked on only two of the problems, turned it in and walked out of the room.  This was not for a super-high-stakes final, just for a regular quiz!
I only found out several days later what had happened.  I quietly threw out the quiz, and gave her a new one after she returned and had had some time to pull her academic life back in order.
I have had students come in after catastrophes, I've had them come in sick, I've had them come in after relationship breakups... none of these were students that came in at my request.  They just showed up.  These experiences have made me very wary of single-entry, "do or die" exams.
Why not three exams at 22%, 22%, and 44%?  This softens the "bad day" problem, and also gives students at least some feedback along the way to help them right the ship if they think that they're in better shape than they really are.
Remember that we don't teach topics, we teach people.  They are our charges, and we are ultimately there to help them.


Yes, from my experience it can.

Regarding modular programming: Vue is rather similar to React in this matter.

Components can be created and treated rather similarly to the way one treats React.Component objects. While the two frameworks are different, the mindset for dealing with components is essentially the same.

This means that user interactions are also somewhat identical. I'm not entirely sure what you mean by "complex", but these Vue components can handle events (such as clicking etc.)

As for unit testing, well: Their guide page does a better job at explaining than I do. Essentially, one can use Jasmine or other UnitTest frameworks, and the Vue instance is the mediator between regular ol' javascript, and the components you want to test.

This mediation by the Vue instance brings me to the final point: Vue doesn't exactly separate concerns in this regard. Most things are channeled through this instance. I haven't looked into it enough to be sure, but my guess is that it's more like a factory than a container for other things.
This would make it much more concern-separated. But again, Vue.js knows better than I do. A more in-depth explanation can be found in this medium.com post

So, while Vue might seem more shallow at first, I find that it isn't. It's just somewhat different than the other two, but more similar to React.


A lambda is an anonymous function.  Java handles lambdas via a feat of type inference.  What you have done is to assign a lambda to a variable of interface type. You may only do this if the interface is a functional interface, i.e., it is an interface that specifies exactly one [non-defaullt] method.

When you do this assignment, the compiler assumes that the lambda is the method specified by the interface that is they type of the variable.  It is here that type inference occurs.  An object of unnamed type implementing the interface is crated and your variable now points at it.  The compiler will reject your code if the argument list or return type of the lambda is incompatible with the interface.

You will find lambdas to be splendid if you are doing event-driven programming.  In fact the JavaFX framework takes big advantage of this feature.


Some real practical example to teach object-oriented concepts and programming (in python)

I expect to update this a few times and hope to eventually have a long answer.
But let me start by explaining some things that you may already be aware of, but other readers may not.
First, OO programming is not, fundamentally, about inheritance and too many books and authors fail to understand that. Moreover, they use inheritance in a dreadful way that makes software hard to understand and harder to maintain.
For example, note that the Linnaeus style hierarchy of the biological world is almost entirely one of "interfaces" and not even "abstract classes", much less concrete classes. There are no instantiated "mammals", for example. It is only at the leave of the hierarchy that things actually exist, other than as ideas. There is some genetic continuity, of course.
Second, there are some principles that can guide you in writing and teaching OO design, but they require discipline. And part of that discipline is to control the situations in which you "break" the rules.
My first advice for anyone wanting to be an OO programmer is not to think in terms of inheritance, but, rather, of composition. Complex things (objects) are composed of other things (objects) that are a bit simpler than the containing object and provide it some essential service. If you write classes where all (or even most) of your instance variables are language primitives, then you don't really get it. And if those instance variables (objects or primitive) have a lot of getters and setters, then you aren't doing OO Programming at all.
In fact, making the above mistakes, requires that the programmer keep track of all details at all points of the program where OO is designed to capture decisions so that they needn't be "checked" again. Set it and forget it, so to speak.
So, if you want to build an automobile, don't think of it as a subclass of vehicle (which gains you nothing: a personal drone and a battleship are both vehicles). Think of it instead of being composed of various parts: engine, transmission, controls, accommodations, etc. And those parts are, themselves, composed of parts. An engine has igniters and pistons, exhaust, etc. Many of those are composed of parts also. It is only at the lowest, simplest level that you build with primitives.
Two of the principles that are worth keeping in mind and following almost always are the Liskov Substitution Principle and the Law of Demeter.
The first suggests that if you extend a class with a subclass you don't also extend the public interface of the subclass. Then all subclass objects are substitutable, differing in behavior but not in interface. Demeter, on the other hand, forces you to write more explicit code that makes relationships clear to a reader. Of course it also forces you to introduce more name, and if they are intention revealing names then your code is clearer.
The Liskov principle, of course is one of the elements of SOLID which you also need to incorporate into your thinking.
In my own programming I'm very faithful to Liskov, also defining Interfaces for most things before I write classes. I'm less faithful to Demeter in the heat of battle, cascading messages. But then I sometimes also need to unravel those a.b.c.d sorts of cascades to figure out what I really mean.
One goal I have in writing OO code is to seek to write only very short methods with a minimum of structure. In other words I try to minimize Cyclomatic Complexity. My palms start to get itchy after the fourth statement in a method of if the complexity level reaches three. I can't always get away with that, but it is a goal. The solution is to refactor complexity mercilessly. Factor out methods, of course, but also "parts", creating new classes to manage the complexity. Even if many of those classes are Singletons the code is usually improved and having the goal in mind from the start, means that the refactoring step is less needed.
Design patters are tools that you need to be an effective programmer in most OO languages. Especially helpful ones are Strategy, Decorator, Observer, and Iterator. Most of these are actually used to build the various Java libraries.

Now, to get to the actual question asked here. But note that a lot of learning can take place even if the students never reach completion of the project in the allotted time. An agile approach (Extreme Programming, say, with you as "Customer") to development leaves them with some functionality even if not all specifications are implemented.
Dungeon Game
Build a text based dungeon game. The main objects are characters (people), places, and things. The places are organized in some sort of map, maze, or grid. Things happen when characters enter places. Characters find and carry things. The things have actions, depending on the kind of thing. A "spell" is a "thing" whose action might depend on context. A "transporter" object might work differently in different rooms (strategy objects).
Note that the classic board game Chutes (or Snakes) and Ladders is a simplified version of this. A text based version avoids a lot of complexity.
Calculator
A calculator has parts such as keys and the display. Less visible are the internal memory, possibly a stack. Even the operations can be objects. The behavior of the keys changes, depending on the state of the computation (Strategy pattern). It is possible to build a simple calculator without a single IF statement, actually.
Abstract Computer with an Assembly language
A Stack Based computer processor simulation is pretty straightforward. There may be accumulators and such, but a single stack on which all operations are done is simple and complete. The operations can be objects (parts). One advantage of this example is that most of the necessary methods can be very short. A program can be read with a Java Scanner object. It needs a program counter at least and possibly a frame pointer if the language is to support subroutines.
Sticky Notes (I haven't tried this)
An application that lets users keep notes and cross reference and organize them. Some classes might be Notes, Keywords, Connections, Lists.
Jeopardy
A simulator for the jeopardy game from TV. Categories, Answers, Questions, Teams, Scores.
(Back soon, maybe).


Is there a compilation of AP CSP scores by curriculum?

I work for UTeach CSP and as far as I understand, the College Board released has results to endorsed providers from 2017-2018 (meaning projects like CS50 and CodeHS aren't included because they were approved after the beginning of the year). They are not planning to release the scores themselves, but leaving it up to providers to share. Below are links to provider score publications that I have seen. There may be information for BJC and PLTW, but I haven't seen them.

UTeach: UTeach Computer Science Principles and Underrepresented Students

Code.org: 73% of Code.org students passed the AP exam!

Mobile CSP: 78% of Mobile CSP Students Passed AP Exam


How to prevent organization/OS students from becoming premature optimizers?

I'm honestly not that I would address this problem at all within my own courses, but if it is to be faced, I suspect that the solution would be something like this:

Immerse students in their current layer.
Really teach the metaphor and thought-process of the layer that they are currently in, and only accept code that utilizes that model of thinking.
Warn students about the dangers of premature optimizing
Show students how to use a profiler in order to figure out what is actually slowing their code down.  Tell students to address their efforts here.


Understanding people better can enable you to more effectively teach them.

Taken as axiomatic, this can be a helpful thought. It can also be a distraction. The value depends on how it's applied. When trying to understand "people", you can aim to understand people as a collective of unknown size, from unknown backgrounds, and unknown individualities; something you cannot ever "know" or understand. Conversely, you can aim to know the 35 students in your classroom, with backgrounds, experience, limitations, and gifts which you can know, and whom you can begin to understand. At least with respect to how that information affects their performance within your subject matter.

I have no links to research into motivation, and can only suggest that if any were found it would be inefficient to read it, or the conclusions drawn from it. The results would be extrapolations of an imperfect model using statistical analysis gathered by researchers with some pet theory to prove, or disprove. The 'repulsive' statement you found is merely one example of many which can be "concluded" from some observation. While, within the experience of the writer that statement might be true, it could be also be untrue in others' experience. What's left out of the statement are the conditions which define "fail", what consequences there are for failure, what is expected to be gained by success, and how much effort is required to achieve what "change".

If I will be passed over for a promotion unless I gain 6 inches on my biceps and increase my bench-press limit by 100 pounds, and the promotion has a net increase of 15% in pay, I'd personally be willing to "fail" rather than change. Given a different set of conditions, 3% pay increase for learning a new Java framework, I might not consider "failure" as an option.  (I don't know Java, so I'd have to learn that first.) In the second case, to me, the change is more desirable, even though the consequence of failure is one-fifth that of the first.

People, as an amorphous mass, can be classified, categorized, and "pigeon-holed" neatly by any study or research project. People, as one-on-one real individual humans, seldom fit into any neat "system," no matter how well researched, or refined it may be. If a system were ever developed that could classify people, manufacturing lines could be reduced to producing the one version that fit the needs, and wants, of everyone. We would have the 'one' computer system, with the 'one' OS that everyone could use to do everything they needed. The 'perfect' automobile could be made in the correct color, black according to the legend of Mr. Ford, and the Big-Four would be out of business. And, in your case, you could write to last, perfect, syllabus and lesson plan for each course you teach. (I'll not hold my breath for any of these things.)

Interestingly enough, I did have some college classes, and I somehow match part of what you described. I did not know what I wanted to major in. I never did manage to "focus" on the core courses. Nor have I managed to collect so much as an Associate's in anything, despite having nearly 150 semester credit hours collected. (I did manage to earn, by accident, a "certificate" for Linux Professional, which surprised me when it came in the mail after I failed to collect it from the office.) I've been connected to computing, and electronics, for decades, and will always be doing something within those areas. Yet I was not sure that should be my major. Perhaps it would be better to major in business, and use my computer skill within that arena? Of course, it didn't help much that I viewed computers as "fun" either. When ever I do "work" with computers it feels like being paid to play, and I almost feel guilty collecting the check.

The "motivation" you seek to understand exists in everyone. It remains individual as to what can activate, or trigger that motivation, or which subject(s) it might be applied to. The target of motivation may not even be a goal, it could be a journey. Some may be motivated to achieve some tangible reward, or to avoid some imagined consequence. Others could be motivated by the "rush" of doing something, or of experiencing the stillness of doing nothing.

That you don't see, or recognize, the motivation of another does not mean it does not exist. "Absence of evidence is not evidence of absence." (And there ends a 3 hour tour into the rabbit hole of The Demon-Haunted World: Science as a Candle in the Dark.)


You could: Try some online classes/tutorials, e.g., on YouTube, read textbooks recommended by university classes (at your level), or buy the highest ranked textbooks on Amazon.


Research On Teaching A Second Programming Language/Paradigm

I don't have research on it, but some experience. In this case it was teaching functional to those with some other background as part of a language principles course.

I'm a terrible Lisp/Scheme programmer so I was as outside my comfort zone as the students were. I did two things. First, I used Standard ML instead of Scheme. I can program effectively in ML, though I realize that the concrete syntax is a crutch. I need that crutch but also used it to teach students who were used to programming with such actual keywords and such. Thus, I used syntax to keep them closer to their own comfort zone.

The second thing, was comfort zone breaking. I taught by focusing specifically on the functional thought process, rather than teaching the language as if it were something fresh. "This is how you have to conceptualize the program!" "Yes, they call them variables, but they are really constants! Deal with it." "You are used to thinking this way. Now you need to think that way."

Functional programs also have a number of design patterns that are pretty ubiquitous. These patterns are part of the programmer's tool kit because if you aren't careful you can write some terrifically inefficient programs with lists if you don't know the patterns (tricks, if you will). An example is appending one list to another. It is a linear time problem, but a naive program is probably quadratic. This is probably hard at first sight for any new functional programming novice, but what is obvious to an imperative programmer just doesn't work efficiently. So, the instructor needs to know those patterns as much as they know the paradigm.

A pedagogical trick you can use, especially for manipulating lists, is to simulate the operations/algorithms using students as values and building up a list (a lineup of students). They walk through an algorithm and see how values are manipulated.

But, teaching novices with no background at all (do they still exist?) is a bit simpler. Start with simple things that build confidence for more complex things, never leaving the paradigm.

But as response to your observation that it is probably different teaching novices and others is yes. Otherwise the experienced programmers will assume too much that turns out to be wrong. The novices have fewer assumptions to make.

I'm pretty sure I've said this before here, but paradigms (consistent ways of thinking) are difficult to change. My go-to example is the change over from highly trained knights on horseback, typically noblemen, to mass armies of lightly trained peasant infantry. The Battle of Agincourt was in 1415 and proved decisively that knights were obsolete as the French army (and much of the nobility) was destroyed by an army of English longbowmen. But in about 1500, Henry VIII (1491-1547) started his training as a knight. He was the last English king who went through the complete training. So, it took about 100 years to recognize that a paradigm had died and been replaced with another. Even in England, which won at Agincourt. Henry's armor (and I think that of his horse) can be seen in the White Tower within the Tower of London.


Engage CS Edu (https://www.engage-csedu.org/) is another repository, which, like Nifty Assignments, is curated by peer review.


How to effectively teach strings and string literal constants?

Perhaps the place to start is with a discussion of variables and making the distinction between a "thing" and a "name for the thing."

A pretty good place to start that conversation is with the a poem from Through The Looking Glass, the sequel to Lewis Carroll's Alice in Wonderland.

The song's name is called Haddocks' Eyes
The song's name is The Aged Aged Man
The song is called Ways and Means
The song is A-sitting on a Gate

See wikipedia for a discussion and background as well as the poem itself.

In programming we don't normally use the first of these four distinctions, but the others are important. The second is how we think of a variable - a name for a thing. The fourth is the thing itself. The third can be an alias or alternate name for the thing, though that analogy isn't perfect.

But once the distinction between the name and the thing is made, you have a better chance of winning. But you still need to be clear.

"foo" is a thing (a String thing)
s = "foo" establishes s as a name for that thing.

"s" is a different (String) thing.

But "/the/path/to/the/file" is simultaneously a thing (String) but also a complicated name for another thing (a File). The open method needs a name for the file to be opened.

Note that much of the above was copied from an essay I wrote in meta.


Examples of innocent looking faulty code for shock effect

My advice to all of these problems is the same. Your students do not know how to draw out memory. This is a basic technique that most people who have been programming for a while do mentally, but that nearly all students need to be explicitly taught and shown on paper.

How to Draw Memory

There is a good chance that you have seen something like this before. Maybe when you were learning to program, or maybe when watching another instructor teach a beginner class. Drawing memory is about physically (with pencil or chalk) drawing a diagram of the state of the program's memory. For beginner programmers, some things are typically abstracted away, such as the idea of a register and the specifics about how memory is loaded and stored.

I am going to create a short video tutorial, showing how I personally draw memory, including how I draw loops and functions, but here are some basics in text form:

Variable is declared => I write the name of the variable and draw a box with a slash through it to signal that it is Null.
The Variable is defined => I erase the slash and write the value in the box. If the variable is ever reassigned, the value is erased, and the new value is written in its place.
The Variable is a pointer => the box contains an arrow to another, larger box that holds the data.
Loop => I draw loops (and other smaller scope constructs) as circles or "bubbles." At the top are the condition and an iterator value if it's a for loop (the iterator value is drawn like any other variable). An arrow points from the bottom of the loop to the condition. All locally scoped values are drawn inside the circle, and the whole thing is erased once the loop finishes.
Function => I draw functions as large blocks. At the very top, any parameter values are placed in their own box that is linked with an arrow. All locally scoped values, loops, etc. are drawn inside the function block, and the output is linked to the bottom of the box. I typically do not erase function boxes since they are likely to be used again, but you can if you wish.
Print Statements => I find it helpful to have a three-board view when drawing memory. One display contains the code, which we will go through line-by-line. The next display contains my drawing, an abstract representation of what the program "knows." The third contains the text output. This helps students visualize the distinction between what is happening and what is displayed to the console.

How to Teach Drawing Memory

In lecture, you should draw memory constantly. Any time you review what a piece of code does, you should draw it out with and for your students.

Since your students already sort-of know some basics, you will likely need to go back and explicitly teach them how to draw. Talk to them about why it's important to understand what the program knows at any given time and how it flows through lines of code, and ask them to brainstorm some ways to keep track of that.

Then, show them the basics for a very simple program that they understand. Something that declares and defines two variables and uses an if statement. Have them practice the drawing structure in small groups or pairs on a slightly different problem. Switch gears back to your normal lecture topic. The next lecture, have your students tell you how to draw yet another variant on the same few lines of code. If they can do that, introduce the next drawing construct, maybe a while loop. Repeat this slow and methodical process over the course of several lectures until your students are able to draw anything they can code. Then, when you introduce a new concept, you should show them how to draw and visualize it as part of the initial learning.

The goal is to make drawing second nature so that they do it when they hit a bug or look at code that is not their own. Tell them that eventually, they will be good enough at drawing that they can do it in their heads, but that for now, they should always do it on paper or a board so that they can practice. Until they are at least intermediate programmers, you should encourage or even mandate that your students draw the state of memory every time they approach a problem.

As you teach them this important skill, you should have them practice on code that works and on code that does not work. Give them something with a bug- a one-off error, or a logical issue. Tell them to draw it out or do it with them on the board. Once they are done, ask them to tell you what the issue is and how to fix it. Have them draw it again once it's fixed.

Once they know how to draw, you can ask them to do so in all sorts of situations. Put it on a quiz or test. Require a memory drawing before helping with a bug in their projects. Make sure your TAs do the same. Have them continue to draw memory during class, and encourage them to draw out tricky parts of assignments as they work on them.

How Drawing Solves Your Students' Confusion

You gave three specific examples of holes in understanding. Drawing solves all three.

  They are convinced that for (i=0; i<5; i++) return i is going to return 5 results. They are obviously so much confused in thinking that they're doing a minor variation of for (i=0; i<5; i++) printf("%d\n", i).

A drawing of a function only has one return value, and it is at the bottom. They will see clearly that once a value is returned, the function is over. Since they won't reach the return statement until the end, they will return once, the final value of i. Due to erasing past values, they will only see the most recent assignment.

  Given a function that needs X as input they constantly point out to me that somewhere in the first lines we need to read X from somewhere, they just ignore that we can add another argument as needed.

A drawing of a function has input values included. In practicing drawing, you will demonstrate that those inputs can be used as defined variables.

  They cannot trace the execution of a for loop, they don't check the loop condition: to them it's just "I do the body N times", I don't yet know what do they think of the index used in the loop besides that it magically happens to take the values 0..N-1.

Drawing the loop involves updating the iterator each time through. They will never forget again after drawing out a loop that updates 10+ times.

I hope this helps, I will try to upload a rough video tutorial in the next few days and will update my answer with a link.


Ideas for introducing databases to Android development students

SQlite is small and as the name suggest "lite" is great for storing data for mobile applications. Apart from that It can easily be used for other small scale web applications without hiccups (100k or more rows).

Resources

The official guide is great. Also checkout the reference of the sqlite package once you are comfortable with using SQlite.
Here's a tutorial that provides step-by-step guide.
Also the sqlite page have some docs for Android Bindings.

That said, SQlite is one of the most tested(tests are larger than code itself) and have a brilliant code base which makes it very suitable for mobile applications.


What are "general purpose programming skills"?

General Purpose Programming Skills
General purpose programming skills can also be called Computational Thinking. Computational thinking has four cornerstones¹:

Decomposition - breaking down a complex problem or system into smaller, more manageable parts
Pattern recognition (data representation) – looking for similarities among and within problems
Generalization (abstraction) – focusing on the important information only, ignoring irrelevant detail
Algorithms - developing a step-by-step solution to the problem, or the rules to follow to solve the problem

Computational Thinking: What It Is, and Isn't
Jeannette Wing, formerly head of the Computer Science at Carnegie Mellon Univ., Pittsburgh, PA, USA published an article in Communications of the ACM where she covers, rather nicely, the ideas of computational thinking, and how it differs from computer programming.²

Conceptualizing, not programming. Computer science is not computer programming. Thinking like a computer scientist means more than being able to program a computer. It requires thinking at multiple levels of abstraction;
Fundamental, not rote skill. A fundamental skill is something every human being must know to function in modern society. Rote means a mechanical routine. Ironically, not until computer science solves the AI Grand Challenge of making computers think like humans will thinking be rote;
A way that humans, not computers, think. Computational thinking is a way humans solve problems; it is not trying to get humans to think like computers. Computers are dull and boring; humans are clever and imaginative. We humans make computers exciting. Equipped with computing devices, we use our cleverness to tackle problems we would not dare take on before the age of computing and build systems with functionality limited only by our imaginations;
Complements and combines mathematical and engineering thinking. Computer science inherently draws on mathematical thinking, given that, like all sciences, its formal foundations rest on mathematics. Computer science inherently draws on engineering thinking, given that we build systems that interact with the real world. The constraints of the underlying computing device force computer scientists to think computationally, not just mathematically. Being free to build virtual worlds enables us to engineer systems beyond the physical world;
Ideas, not artifacts. It’s not just the software and hardware artifacts we produce that will be physically present everywhere and touch our lives all the time, it will be the computational concepts we use to approach and solve problems, manage our daily lives, and communicate and interact with other people; and
For everyone, everywhere. Computational thinking will be a reality when it is so integral to human endeavors it disappears as an explicit philosophy.

1: Source: BBC Bitesize - KS3 Computer Science - Introduction to computational thinking
2: Source: Jeannette M. Wing "Computational Thinking" Communications of the ACM. 49 (3): 33.


If you are struggling with "design" and "beautiful" and artistic mumbojumbo, you can still teach CSS while avoiding trying to turn them into pro designers.

The simplest example task I can think of is having your students create a simple website with a basic style and another style for the visually impaired (and a button to change between the two styles).

If that is done, you can have a contest/assignment: you create a simple website (2-3 pages, few images, a menu), and they all have to create 2-3 designs for it in CSS. Then the class can vote for their favourite. Another upside is that finally it won't be the geeks but the artists in the class that shine.

As for teaching design and creativity, why not ask the help of the art teacher? Maybe you can put together a curriculum for a few classes together? You are a programmer, not a designer, and it is OK to admit it.


How can I prepare for DASCA Data Science certification if I am in UG?

I'm going to rephrase your question a bit:
"Is it worth preparing for the DASCA Data Science certification, and if not, what should I do instead?"
I teach data science and counsel with a lot of students looking for jobs, as well as employers looking for people to hire. I've also worked as a data science consultant for a few years.
I have never heard of this certification. I've talked to a few other data scientists that I know, and they also haven't heard of this certification.
In the world of data science, there are largely two credentials that count:

A degree in something from a major university. These days, that something can be:

data science
computer science
software engineering
statistics
in some cases, a degree specific to the problem domain you're interested in. (Economics or foreign policy are common examples)

Actual data science experience. This can be real-world experience, such as an undergraduate research project, a senior project / capstone class that you design yourself, personal projects that you document, Kaggle competition results, etc...

The employers I've talked to in my capacity as a teacher and as a consultant typically don't give much stock to certificates on their own.
They've found that people who focus on certificates either have too little real project experience (e.g. they know how to solve a couple of specific, clearly defined problems), lack the ability to do data pre-processing (which is the what data scientists spend the vast majority of their time doing), or lack experience working with a team.
There are of course exceptions to this, but by and large, you'll have a much better time if you focus on getting real project experience.
What to do instead
Unless there's a very compelling reason for you to get this particular certification, (you love collecting certificates for fun, someone is paying you for it, or there's a particular job you want that lists this certificate as an explicit requirement), here's what I would recommend you do instead:

Finish your UG degree, making sure that you take steps necessary to have as many meaningful data science projects as you can, preferably ones where you work with a team of people. Use the resources of your UG program to help you network with people in the industries you're interested in, find a good internship, visit career fairs, etc...

Look for personal projects you can do that will show you have explored different aspects of data science, especially data preprocessing. This can be things you just decide to do on your own, UCI datasets you explore for fun, Kaggle competitions or explorations, etc... Treat these like real research / business problems.

Make sure you document these results somewhere public, such as GitHub or Kaggle via Jupyter notebooks, or in some other way that makes it easy for you to share them with potential employers. This should go beyond just "here's my regression result", but a discussion of the choices you made, how they impacted the results, and caveats about your conclusions. This Jupyter notebook on Kaggle is a great example of what I'm talking about.


Should I teach modern web development in an introductory programming course? How?

If you want to teach students programming concepts along with web-development (HTML/CSS/JS) you should consider lacing programming examples or lessons with examples of HTML/CSS/JS or similar concepts in both. You could also have HTML/CSS/JS as an extra credit assignment or something the class can do if they're ahead of schedule. This will keep the class motivated to learn HTML/CSS/JS, which you probably shouldn't grade as it's an extra addition to the curriculum. This will teach the class the necessary topics along with them not being bored out of their mind, studying for programming AND web development.


I would recommend a mixed strategy. There are two sorts of books that are appropriate for e-books, I think. The first category is books that you need now, but wouldn't intend to keep. This includes books in subjects that are less important to your main objectives. In the US, at the undergraduate level, it might mean books that are required in subjects other than your major subject. The second category of books suitable for e-books is those that you expect to always be available in some form over time. Great literature and philosophy are in this category. But if you would intend to discard a book after a year or two, the cheapest alternative is likely appropriate.

I don't have faith that the e-book formats and their readers will continue to be available in an upgradeable way. Suppose you have a very important e-book that depends on some particular format or device and the company supporting that format decides to abandon it. You may not have access to those bits in 20 years or so. That is especially the case for those with DRM "protection."

So, the category of books that you should consider getting on paper are those that are most important to your goals. If you study CS, that would mean the books in the core areas at least. If you later want to refresh your memory those books will still be on your shelf (with reasonable care, of course). You will be familiar with them. Perhaps you have personal annotations in them. For e-books it may be easy (should be easy) to annotate in place, but I don't think that is universally done at this time. So your notes may be separate from the text and it is up to you to keep them synchronized and harder for you to review.

Of course, for such important books, you might consider having both formats, an e-book you can carry on your daily commute and paper for serious study. Some books that you purchase on paper also give you automatic access to an electronic version, or at least to additional electronic resources at no cost.

Note that one advantage of e-books is that some of them at least are updated with corrected versions and new editions. Some of these are at no cost, I've noticed. That is an advantage you don't get with paper.

On the other hand, I still have, and occasionally reference, important books I used as an undergraduate in the 1960s. I also have some of my hand written notes from then and through graduate school. I haven't had to worry about obsolescence of format or device. Some of those books are classics that went out of print and the replacements are not of the same caliber.

You should note that the paper text books you get from established publishers in technical fields will probably only be published for a few years. Text book publishers value the new over the old. If that happens to e-books then you become especially dependent on the devices you now own, but which you will likely want to replace in a few years. It isn't especially costly for a publisher to continue to make old e-books available, but they need to take the trouble to do so - as well as the trouble to update formats as they change.


What are the benefits/uses of a SMART Board in CS education (or are there none)?

I've been in rooms with smartboards that aren't dry erase marker safe which means if the smartboard goes down the board space is lost.

I've never used a smartboard but think I get the most bang for the buck with a projector onto a whiteboard. We can project sites, code, etc and also annotate by writing on the board directly (although the annotations can't easily be saved other than by taking a picture).


is there any good specific pedagogy research to teach spreadsheets?

While I've never taught spreadsheets to anyone other than myself, I don't think there is any unique magic here. In fact, since a spreadsheet is its own metaphor, the pedagogy should be fairly straight forward. It is like learning any other skill, even swimming.
Lots of practice. Lots of feedback.
What I'd do is create a list of short instructions (lectures or other) followed by a lot of exercises using what was in the recent instructions. The instructions can become increasingly complex as can the exercises. Feedback to students is required for the exercises, perhaps by grading, and perhaps by distributing correct (and maybe incorrect) solutions. The incorrect "solutions" can illustrate common mistakes so as to make them explicit in the minds of the students, thus making them recognizable when they occur in practice.
One sort of exercise you might consider is a "fixer-upper" which is an example of a design pattern of the same name. A Fixer Upper is a partial solution to be completed by the students, or it is a complete solution that has had specific errors introduced that should be found and corrected. It is possible to combine these in a more sophisticated version, though simpler examples should be given at the start.
I would also make sure that the students have access to the documentation of the spreadsheet program and are tested on their understanding of it. This can come by giving exercises that have not had prior instruction other than to point them to the details in the documentation.
For the first exercises it is probably best to test single features, such as summing a column. For later ones, combinations should be introduced.
And if you want to go to extremes, note that some spreadsheet systems are Turing Complete, so it is possible to do arbitrary programming within them. In particular, recursive programs are possible.


How to teach operating systems development nowadays?

Implementing a whole OS may not be the best approach if you want your students to learn operating system concepts. This is specially true if your students are not proficient in C and Assembly, since major parts like booting, context switching and virtual memory need to be coded in Assembly. This might be daunting for students that have experience only with Python.

An alternative approach is presented in Computer Systems: A programmers perspective. It is a very in depth book, but instead of implementing everything the authors decided to study the System Calls in the POSIX specification as a way to illustrate Operating System Concepts. IMHO it maintains a very good balance between the abstract concepts and their concrete implementations.


What Notation for Teaching Boolean Logic?

If your students were a bit older, I'd be more comfortable with the following, but suggest it anyway.

There is an advantage for a student to know that the concepts exist independent of any notation and that historically  notations have differed based on use and context.

I would, myself, provide them with a handout giving names to the concepts and various notations used for each. Then, I'd use the various symbols as naturally as possible, responding to the inevitable questions.

The only caveat would be that you don't mix the different systems in any given lecture/conversation. You should also suggest that the students be consistent as well.

The rationale here is that students will likely see different symbols sooner rather than later if they do any reading or research outside your instruction. It is better that they have some preparation and at least a hint that the terminology isn't entirely consistent or standardized.

Some of the terminology, by the way, such as + for "or" is actually tied to the concepts in interesting ways. For example, the similar shape of ∧ and ∩ help students understand the relationship between logic and set theory. Some of the symbols, on the other hand, were chosen for no better reason than that they exist on common input devices such as keyboards.


Assessing programming skills of students under 18 years

There are four places I would suggest looking if your concern is the K-12 environment:

ISTE Standards (Note: there are standards here for multiple audiences, including students, teachers, and computer science educators)
CSTA Standards
AP CS Principles Course Description (Revised for 2017-18)
AP CS A Course Description

These would probably be the best places to start. I suggest working your way from the top down since the standards as listed progress in what I see as an increasing order of complexity/rigor.


Looking for a block-based programming language for AP CS P

You will probably want to look into Snap!. It was built upon Scratch and would probably meet your needs. This is from its About page:

  Snap! (formerly BYOB) is a visual, drag-and-drop programming language.
  It is an extended reimplementation of Scratch (a project of the
  Lifelong Kindergarten Group at the MIT Media Lab) that allows you to
  Build Your Own Blocks. It also features first class lists, first
  class procedures, and continuations. These added capabilities make
  it suitable for a serious introduction to computer science for high
  school or college students.

Additionally, I asked a question a few weeks ago about the differences between Scratch and Snap!. You might find this discussion helpful: "What can Snap! do that Scratch cannot?"

Edit: In the context of AP CS Principles, it may also be helpful to know there is a full curriculum available from Berkeley that utilizes Snap!. It is called The Beauty and Joy of Computing.


How does one create a balanced AI curriculum in light of the popularity of Deep Learning?

I suppose the design of the curriculum revolves around the goal.

If the objective is to prepare students to enter the field as researchers, then the balance needs to favor the research that's active (and probably employable.) Where that fits into the AI picture as a whole is helpful. What limitations it has, and the missing pieces it doesn't solve are important to recognize, but have less weight than the targeted areas.

If the objective is to provide an overview, or survey, of the AI field, then deep learning and machine learning are only promising avenues to solve part of the puzzle. A balance in this case should include the history as well. Including the previous "promising avenues" that didn't deliver all they were supposed to deliver. Temper enthusiasm with reason and perspective.

Showing how the lesser-known areas are important, as well as their resistance to current approaches can help too. Even if the students will enter ML, a big-picture view will help them know where they're going.


Dealing with students who are overly motivated

I don't think this is really a CS problem - though of course some individuals do get "addicted" to computing.

The root of the problem is that these students don't know how to study - and ironically, it's quite likely that the education system they are progressing through has never even tried to teach them that basic skill. But you don't have time to teach them that, and teach the contents of your CS course as well.

Students who have found everything "easy" since the start of their education are often the worst sufferers - eventually they hit the brick wall where just listening to the teacher and "getting it" with no effort doesn't work any more, and then they are completely lost.

The best solution would be to try to get a general "how to study" course into the curriculum for every student - or at the least, start your course by giving them some guidelines (including notes to refer back to!) on the study strategies that work, and those that don't.

But you can only lead the horse to the water - as somebody once said, "Homo sapiens has a fundamental design defect: most members of the species can learn, but none of them can be taught."


Do some websites block school building/classroom IP networks because they mistake us for possible DDOS?

Yes.  I have a web development class.  If more than 5 people connect to the free hosting site, it stops anyone else from connecting via FTP, since we appear to all have the same IP address.  Multiple connections from the same site can be a script running, and most users will not appear to have multiple connections.
I do: Demo using the FTP client, go through some of the issues with connecting (error messages etc.) and then, because of this restriction, I will either:

1) Manage the class in groups (if a small class) or

2) Give them a task (ftp their site) to perform at home for review at the next class

It is annoying, but as indicated above, it is likely to detect DOS or other malevolent connections.


A loaf of bread, a knife, a jar of peanut butter and a jar of jelly.  Write an algorithm to build a PB&J.  Have one of the kids follow the literal direction written by a different kid.  This project have been a favorite starter for algorithms for 30 years.


Ways to imagine a computer program for a student without photographic visualisation

This may sidestep the question a bit, but perhaps you can have the student make physical drafts of what they want their program to do at first, kind of like making multiple drafts of essays.
As an undergraduate, I sometimes joked that I used an awful lot of paper for a computer science student. I found that dumping everything from my head or even the problem statement onto pieces of paper (more portable) or a very large whiteboard helped me to organize my thoughts and eventually figure out what I wanted to do for my harder programming assignments as well as the problem sets in my algorithms class. I also did this when I was just starting out in CS and programming, just on a smaller scale and not for very long. This was especially helpful when I was learning about recursion.
I also found this helpful for helping students when I was a TA for the CS department's discrete mathematics course, which was taught in two different styles: paper and pencil, and with a theorem prover language (Lean) (a lot of students felt like it was programming). It especially helped for the latter style, as students sometimes knew what they wanted to do in a proof but couldn't figure out how to express the proof in Lean because they didn't understand how they were supposed to understand the syntax. Based on what some of those students said, I think drawing everything out for them helped them to eventually visualize on their own.
If the student is just starting out with programming, the drafts shouldn't be too complex yet, so hopefully they won't be too taxing and they can be a stepping stone to eventually being able to getting mental images of program structures.


Since your students are getting the beginning of Boolean from you, you have the advantage of being able to lay the proper groundwork to work within. To begin with, hopefully, you will be stressing the point that Boolean logic is two-state. You can use the word binary if you choose, as long as they are not predisposed to think binary = computer, since while Boolean logic is handy for computers to deal with, it is not just for computers.

To connect the symbols, meanings and math together, make it explicit, and demonstrate. Start with the concept that FALSE is the same as nothing and TRUE is the same as something. "I have an apple in my hand" is FALSE if you have no apples in your hand, even if you have an orange, or a pencil. The same statement is TRUE if you do have an apple in your hand. It is not, however, more TRUE if you have two apples, or twenty apples, in your hand, however, it is still just TRUE.

Zero, as a number, represents nothing as well - zero apples is no apples. Therefore, it makes sense (dare I say it is logical?) to use the number 0 to represent FALSE. Using the previous demonstrative phrase, it only takes one apple to make the statement TRUE, and at least one is something. Five is also something, but that would leave out everything from one to four as maybe, and Boolean logic has no MAYBE, so that creates a problem. If some starts at one then there is not need for a MAYBE. Using 1 for something, and therefore TRUE, gives two symbols to use instead of the words TRUE and FALSE, which can get quite long to write in a very short while.

The next step is to introduce the symbols for OR and AND. Here I will, marginally, disagree with how and why your are using center dot • for AND. I am not opposed to that usage, only the reasoning behind the choice. The students have not had algebra yet, so it seems a safer choice than ✖. You can tell the students you have chosen • for AND because it is what they are most likely to encounter later. They should also be told that it can also be written as ✖, and that both can also be used for multiplication ins algebra. The same way that 0 means FALSE for this class, and will mean zero in mathematics (and origin in rectangular coordinates). Likewise using ✚ for OR in your class, while it will mean addition in mathematics. Rather than shelter them now, only to create confusion later, deal with the reality that we only have so many different symbols we can use, and many times they will have different meanings in different places, and knowing when, and when not, to use ✚ as AND is part of learning about Boolean logic.

We need to toss in one more symbol here as well. Replacing the word is with the symbol = (or symbol of your choice) also comes in real handy.

Since the students have not had algebra the next step might be difficult. Connecting the Boolean operators with the mathematical functions. Connecting the addition to OR first, because it is easier to apprehend, you can give the samples FALSE OR FALSE is FALSE, TRUE OR FALSE is TRUE, and TRUE OR TRUE is TRUE. Rewrite them in symbols as 0 ✚ 0 = 0, 1 ✚ 0 = 1 and 1 ✚ 1 = 1. The first two will be obvious, make sense, and get no questions. The third will start them thinking and should get some questions about "why not 1 ✚ 1 = 2?" Return to the apples: zero apples made the statement false while any apples, one, two, or a dozen, made the statement true. So, any number other than zero is true. You can call it part of being a two-state system - either it is zero, or it is other than zero. Therefore, the last of the three samples can be expanded to:

1 ✚ 1 = 2
        2 ≝ some (it isn't "none", our only other choice in Boolean algebra)
1 ✚ 1 = some
        some ≝ TRUE (the apple demonstration)
1 ✚ 1 = TRUE
        TRUE ≝ 1 (our definition of the symbols to use in Boolean algebra)
1 ✚ 1 = 1 (Final answer)

Doing the same thing with multiplication for AND is easier, if they understand that anything multiplied by zero is zero. If they do not have that concept mastered, then it can become more difficult. Finding a demonstration for that can be dicey, but it is possible. One option could be to use unit pricing. Say it costs 8 dollars (or your local currency) for a pizza. if you get one pizza, that's 8 ✖ 1 = 8. If you get four pizzas, that's 8 ✖ 4 = 32. Now, if you get no pizzas, that's the same as zero pizzas, so 8 ✖ 0 = ? The answer, of course, is nothing. What if the price of pizza goes up to 12 dollars, how much for no pizzas? 12 ✖ 0 = 0; still. No matter how much pizza costs, the total price for zero pizzas is zero dollars. Anything else could be used instead, such as speed and time for distance, or wage rate and hours for pay checks, etc.

With the multiplication by zero concept under control, it's time to connect AND with multiplication. Using the same three setups from above gets three samples of the conversion. FALSE AND FALSE is FALSE, TRUE AND FALSE is FALSE. Converting to symbols gives us 0 ✖ 0 = 0, 1 ✖ 0 = 0, and 1 ✖ 1 = 1.

You can expand that into the distributive property, if you wish. [Again, the rule of only two values comes into play with the OR operator.]

TRUE  AND (FALSE OR FALSE) ⇒ (TRUE  AND FALSE) OR (TRUE  AND FALSE) ⇒ FALSE OR FALSE  = FALSE
 1     ✖  ( 0    ✚    0  ) ⇒ (  1    ✖   0   ) ✚  (  1    ✖   0   ) ⇒   0    ✚   0    =  0
TRUE  AND (TRUE  OR FALSE) ⇒ (TRUE  AND TRUE ) OR (TRUE  AND FALSE) ⇒ TRUE  OR FALSE  = TRUE
 1     ✖  ( 1    ✚    0  ) ⇒ (  1    ✖   1   ) ✚  (  1    ✖   0   ) ⇒   1    ✚   0    =  1
TRUE  AND (TRUE  OR TRUE ) ⇒ (TRUE  AND TRUE ) OR (TRUE  AND TRUE ) ⇒ TRUE  OR TRUE   = TRUE
 1     ✖  ( 1    ✚    1  ) ⇒ (  1    ✖   1   ) ✚  (  1    ✖   1   ) ⇒   1    ✚   1    =  2 ≝ 1
FALSE AND (FALSE OR FALSE) ⇒ (FALSE AND FALSE) OR (FALSE AND FALSE) ⇒ FALSE OR FALSE  = FALSE
 0     ✖  ( 0    ✚    0  ) ⇒ (  0    ✖   0   ) ✚  (  0    ✖   0   ) ⇒   0    ✚   0    =  0
FALSE AND (TRUE  OR FALSE) ⇒ (FALSE AND TRUE ) OR (FALSE AND FALSE) ⇒ TRUE  OR FALSE  = TRUE
 0     ✖  ( 1    ✚    0  ) ⇒ (  0    ✖   1   ) ✚  (  0    ✖   0   ) ⇒   1    ✚   0    =  1
FALSE AND (TRUE  OR TRUE ) ⇒ (FALSE AND TRUE ) OR (FALSE AND TRUE ) ⇒ TRUE  OR TRUE   = TRUE
 0     ✖  ( 1    ✚    1  ) ⇒ (  0    ✖   1   ) ✚  (  0    ✖   1   ) ⇒   1    ✚   1    =  2 ≝ 1

TRUE  OR (FALSE AND FALSE) ⇒ (TRUE  OR FALSE) AND (TRUE  OR FALSE ) ⇒ FALSE AND TRUE  = FALSE
 1    ✚  (  0    ✖    0  ) ⇒ (  1   ✚    0  )  ✖  (  1   ✚    0   ) ⇒   0    ✖   1    =  0
TRUE  OR (TRUE  AND FALSE) ⇒ (TRUE  OR TRUE ) AND (TRUE  OR FALSE ) ⇒ TRUE  AND TRUE  = TRUE
 1    ✚  (  1    ✖    0  ) ⇒ (  1   ✚    1  )  ✖  (  1   ✚    0   ) ⇒   1    ✖   1    =  1
TRUE  OR (TRUE  AND TRUE ) ⇒ (TRUE  OR TRUE ) AND (TRUE  OR TRUE  ) ⇒ TRUE  AND TRUE  = TRUE
 1    ✚  (  1    ✖    1  ) ⇒ (  1   ✚    1  )  ✖  (  1   ✚    1   ) ⇒   1    ✖   1    =  1
FALSE OR (FALSE AND FALSE) ⇒ (FALSE OR FALSE) AND (FALSE OR FALSE ) ⇒ FALSE AND FALSE = FALSE
 0    ✚  (  0    ✖    0  ) ⇒ (  0   ✚    0  )  ✖  (  0   ✚    0   ) ⇒   0    ✖   0    =  0
FALSE OR (TRUE  AND FALSE) ⇒ (FALSE OR TRUE ) AND (FALSE OR FALSE ) ⇒ TRUE  AND FALSE = FALSE
 0    ✚  (  1    ✖    0  ) ⇒ (  0   ✚    1  )  ✖  (  0   ✚    0   ) ⇒   1    ✖   0    =  0
FALSE OR (TRUE  AND TRUE ) ⇒ (FALSE OR TRUE ) AND (FALSE OR TRUE  ) ⇒ TRUE  AND TRUE  = TRUE
 0    ✚  (  1    ✖    1  ) ⇒ (  0   ✚    1  )  ✖  (  1   ✚    1   ) ⇒   1    ✖   1    =  1


how to motivate student that programming will give bright future to them?

This might be a mistake, actually. Everyone is different. People like doing different things. Programming isn't for everyone, nor is the wider world of Computer Science as a whole. My daughter, for example, is perfectly happy as a Philosopher. My son is perfectly happy outside academia.

Convincing someone to do something (a kind of advertising) may do them harm in the long run. People spend millions of dollars convincing people to consume sugary drinks, to their detriment.

If you make the classes interesting, with interesting problems to solve, those who want to do it will stay. Wish the others well and focus on those who want to work at it. Some of us have found that group work (pair programming) is a motivator, introducing a social aspect to learning as well. On the other hand, it is possible to make learning programming as dull and demotivating as learning multiplication tables.

I'll note that many things are hard. Becoming an olympic athlete is hard. Some people are willing to put in the work to do it. For others, it isn't worth that effort.

Saying the "future is bright" is something you can't honestly predict. Many things could happen that make it less bright. The need for people specializing in CS might decline in future years as some processes become more regularized. This has been the history of the world, actually. One takes a chance on the future no matter what you do, so you might as well follow your own dreams, not those of someone else.


Is asking students to debug existing code better than having them write new code?

I give students targeted debugging exercises to make them aware of common traps that they can fall into while coding, and I believe that this is beneficial to them.  Certain errors come up all of the time, and pointing them out can be a real time-saver for students when they code their own labs.

I also give out small bits of badly-formatted code, with poor variable names, indentation, etc.  But these are always to call attention to the importance of good coding practice.

However, I do not emphasize either of these activities heavily; the ability to conceive of algorithms is still of the utmost importance, and I don't want to halt students' growth along this more important axis.  And switching entirely into debugging might (perversely) not help them learn the most important skill of debugging, which is to test with extreme regularity as you work, since you are providing them with fully implemented (bad) code.

So, yes, by all means, give students limited, carefully targeted debugging exercises.  But don't switch completely over to this activity.  Finding bugs is important, but it is only one skill that a budding developer needs.


How can you efficiently assess students web coding?

Much less detail than the excellent post by Buffy, but directly to the question. Replace unit tests with validations and linters.

Have the students create all content in distinct files: HTML, CSS, and JS. Any styles or JavaScript in the .html file is invalid for the project(s). There are many validators and linters for all three, as well as for any other "code" you choose to use/allow, such as PHP, Ruby, etc.

Since a unit test only gives go/no-go results, a validator is at least as effective. A visual check of the resulting page/site shouldn't take but a few moments as well. If it validates and looks correct, it must be "right."

If you also wish to instill, or enforce, coding standards, comments, indentation, etc., a linter may help.

Running a series of validators and linters, checking the operations of the page/site, and visually scanning the code should take much less time than grading a paper-based exam, so you are still time ahead. If the students are provided access to similar tools, if not the exact ones, or exact settings you use, they can develop the habit of applying the "test" to their own code as part of their development work-flow.

As an extra note, if you need to compare versions/iterations of their code, you can use a system such as git, which need not be based on GitHub, or even use remote repos at all. Each student can be required to create a GPG key for their project work, and sign their commits. With that system, you can use the built-in diff function to see the changes and be certain who committed what.


What are good, practical labs and activities for unnested loops?

Note that the following are intended for the instructor, not always directly for the student. If used well they require some analysis, not just coding, from the student.
Use the fact that the sum of the first n odd numbers is $n^2$ to compute the integer square root of an integer.
Test data should include 63, 64, and 65 to catch edge cases.
This can be extended past the decimal point and optimized in various ways to compute more accurate approximations of square roots.

Notes on the above, but I suggest you try it before peeking:

To make it a bit more obvious, this involves using inverse functions and computing inverses. The loop actually needs to count subtractions and uses facts about perfect squares to compute square roots. That same idea might be exploited for other problems.

Note that $\lfloor$  $\sqrt 65$ $\rfloor$ = 8.

Other simple things:

How many digits does an integer have?

How many bits are required to represent an integer? (Note that the structure is the same as the above)

How many times does zero (for example) appear in the decimal representation of an integer.

Sum of the digits of a given integer.

Is the number of 1 bits in a binary representation of an integer even or odd?

Read a real value x from input. Then read the successive coefficients of a polynomial from input and evaluate the polynomial at x. Note that the stopping condition needs to be specified and by varying it you can have different systems. Reading it from input is one of the obvious variations. Hardcoding it is another. Later on, the coefficients can be in an array, of course.

In teaching loops it is important to also give exercises where the correct number of iterations is zero. For example, give x and y, find the number of multiples of 3 that are larger than x but less than y. Don't exclude the initial condition y < x.

Nested loops: Once you have the solution to "is X prime?", how many primes are there between a given x and y?

A bit harder:
Euclid's algorithm.

Extensions:

Use other similar sums (than the sum of odds) to compute other things.

Look at the Wikipedia article on Taylor Series to get some ideas about how to approximate some interesting functions with sums.

A solution to the square root problem follows, using a personal (executable) pseudocode:

     $ "Computes the integer square root of a non-negative number";
    With
      value; current; count; odd; // integer variables
    Program
      Read value;
      current <- value;
      count <- 0;
      odd <- 1;

      While current >= odd {
          current <- current - odd;
          odd <- odd + 2;
          count <- count + 1;
      }

      Print "The integer square root of ", value, " is ", count;
    End


I think there's a few different skills students need for independence, and they require quite different teaching approaches. Independence is the end result but you can't teach it directly.

Confidence. They need to think it's possible to try out a new toolset and make something. Guiding them prescriptively through a variety of different new tools is a good way to do this, as with @BrDaHa's answer. i.e. Don't teach independence as such but show through example that different and new approaches are possible and not too difficult. Once they've achieved several different projects, even tiny ones, with different technologies they'll be more confident to explore different options rather than use the same thing every time.
Abstract understanding. The hard bit of programming is thinking about problems and solutions in the right way. Once you know conceptually what you want to do it's much less scary to go find a tool to implement that well, and that conceptual understanding will help guide you through using a new tool. Teaching CS generally addresses this, plus a specific focus on systems design.
Ability to learn something they don't already know. Reading documentation, using stack overflow, reading blog posts and books. Students need to learn each of these, they're different skills, and they're often not taught well or at all in CS courses. When you can do these things then approaching a new tech is fun rather than daunting.
Appreciate there's different tools for different jobs. You need to demonstrate, or better have them experience, that some technologies are great for some things and not others. So they know there's worthwhile in exploring different tech. On the one hand, when you have a hammer everything looks like a nail. Conversely though, it's often a lot faster to use a tool you know than learn a whole new one for a small job, even if that tool is 'better'. Negotiating that trade off is an important part of general software development. Part of the fun of being a developer.


Student Teaching Minetest Modding in school as club

You seem to be focused on game development, which is probably the right thing to do since at least some of your student colleagues will also be interested. But there are other possibilities to keep in mind, such as some simple information system that your school might use. Teachers might be able to give you ideas about that.

Since you want the club to continue after you leave, I'll suggest two things. You should probably try to develop one student to take your place and spend more time with him/her to foster a leadership role.

More important, I think, is to pick the right project for your group. If you aim for a large result that can be built in parts and where each added part adds visible value (punch) then you might have something sustainable. You don't want a small project (or set of projects) since continuation means finding more projects. You don't want a project that isn't useful/cool/exciting along the way (but only at the end), since you don't get any psychological reward as you go. Pick a project that is large enough so that it can't be "finished" in the time available. It will then be an inducement to continue in the future.

I'd also suggest that you don't try to lecture, but rather form an Agile Software Development programming team, using some of the practices of Extreme Programming. See Activities and Practices at the last link. There are other possibilities but XP is fairly easy to follow. Use short iterations and small stories. But make sure that each story adds gaming-value: something that will actually affect the play of the game.

The above will also favor collaboration, which is a useful skill. Don't worry about absent students. Work with what you have. If the thing is interesting enough people will want to participate. But it has to be interesting both in its own right and also in the day-to-day activities.

I would also suggest, pretty strongly, that, rather than laying out a curriculum for this, that you explore topics on a need-to-know, just-in-time basis. Making it like a regular course might not be as appealing to others as just keeping it like a club.

Don't exclude newbies, but incorporate them, and their enthusiasm, into the project and enable it with Pair Programming, starting them out as Navigator with one of you "old timers."

Good luck with this, and in your future.


Is it a good idea to teach algorithm courses using pseudocode instead of a real programming language?

Similar to @Vince, I think it's a good practice to do both. I don't really agree with the cooking recipe analogy, though. Pseudocode describes that the algorithm does, without going into detail how you do it.

I think perhaps a better analogy:

Pseudocode: you need to put an egg into the flour mixture
Actual code: pick up an egg, crack it open on the side of the bowl, and drop the egg into the container. Don't forget you need to dispose the egg shell as well.

There are so many ways to accomplish the task, and the actual code just gives the student an example of how to do it.

Presenting only the pseudocode might make some of your students loss. Presenting only the actual code would keep them in the box and get them focused too much on the details. A mixture of both would be my choice.