Setting up a cloud-server SSH login procedure for a class? (AWS)

I believe that using one key for access, even with unique passwords, is inadvisable. Teaching moments aside, each student should have their own, revocable, restrict-able, key pair. However, as I understand the intentions, you should be able to achieve your goal this way.

Short answer

Point 1:

Edit the instance's /etc/ssh/sshd_config file and check that these lines are there:

PubkeyAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords no

Then add this line to require the use of both a key and password to access the instance

AuthenticationMethods publickey,password

Point 2:

Create the one key to rule them all with ssh-keygen or gpg
Copy the private key file to each local machine which will access the EC2 instance
Create user accounts for each student on the EC2 instance
For each user account on the instance add the public key to this file:

/home/$USER/.ssh/authorized_keys

Point 3:

At the beginning of the term/course have each student login to their assigned account on the EC2 instance and set a new password.

Explanations

During the provisioning of the EC2 instance, and probably later as well, you have the option of assigning a key for SSH access. The Amazon EC2 console, Network & Security, Key Pairs is the place to handle the key pair for your access to the EC2 instance. There you can have Amazon create the key pair for you, or import a key pair's public key which you have made locally. The default account, created when the EC2 instance is created, and the key pair you create/import for that account to access the EC2 instance, are the equivalent of root on a local machine, sometimes the username is, in fact root on the EC2 instance. That key pair should be shared with the students as often as you share your password with them. (Can anyone say "never"?).

Point 1 - Password and RSA key required to login

The first three lines control what the SSH host (EC2 instance) will accept. PubkeyAuthentication1 has to be yes (the default) or the host will not even accept keys, valid or not. PasswordAuthentication2 defaults to yes, and could be commented out, or even missing, and it would still work. The caveat here is that thigs will go very bad if it is set to no. (Bad, in this case, means destroying the EC2 instance and creating a new one, as the final settings will require a key and a password, yet no here will prevent the SSH host from asking for one.) The PermitEmptyPasswords3 setting of no just stops the students from accessing their account over SSH with an empty password. It will not prevent them from setting their password to a blank one. If they do, they'll have to get the instructor's assistance to reset the password, and maybe learn a lesson in the process. Lastly, the setting AuthenticationMethods4 specifies what methods are required for authentication.

The EC2 instances are supposed to be operationally equivalent to bare-metal Linux installs. (All be it, without the hardware acquisition and maintenance costs.) Treat yours as such. Each student should have their own, regular Linux, account on the EC2 instance, with all the normal restrictions and settings that you would use if it were a server in your lab room. As the owner of the instance, effectively if not actually root, you can access the student user directories and process/validate/censor them as needed.

The process of creating a new user on an EC2 instance is the same as any other Linux install. sudo adduser new_user_name. As I understand it, newly create user accounts on the EC2 instance will not have the needed directory structure for using SSH access. The process for creating it, and adding the public key at the same time, are fairly short.

sudo adduser new_user_name
sudo su - new_user_name
mkdir .ssh
chmod 700 .ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDcsebwlu3jVUJfPunR8aENmxcRQKva00MDi7aiyeSh7cpzQpCFK/gqTRGmqZvI6H/0QImek5JfPkJDgUkPHfhlawHRKrEzsvCeiPzKuMT1UHs5wASqHuxTJrjklJeR/knFxdCZZ4kyYFFomdFKsLTR5VPLK/2H3c6APs4+XPxE2Q== gypsyspellweaver@cseducators.stackexchange.com" > .ssh/authorized_keys
chmod 0600 .ssh/authorized_keys

Where _new_user_name_ is the name of the user account you wish to create, and the long echo line contains the .pub file contents for the student access key that you've created beforehand. (Description below.) (In this example I used a 1024-bit key just to keep the sample line short. In practice it should be 2048-bit, at least. AWS EC2 does not accept DSA keys, and I don't know if they accept Ed25519 keys.)

Point 2 - One key for all

As mentioned above, the key pair you use to access the EC2 instance gives you root powers. That is not the one key you want the students using. Of course, the key + passphrase setting applies to you as well, once you have set it in the sshd_config file, so even with your key pair, the students would need to know, or guess, your password as well. Still, that's easier than getting the key should be. Making a second key for all the students to use is simple enough, and you can even make it without a passphrase. The command, on a local machine,

ssh-keygen -b 4096 -t rsa -N '' -C student_access@AWS-EC2 -f student_access

will create the key pair, saved in student_access for the private key, and student_access.pub for the public key.

The content of student_access.pub, which is a long single line, is what is quoted in the echo command in the above snippet, to be copied into each students' EC2 home directory structure.

The other file, student_access, is the file which needs to be distributed to each computer, and to each appropriate account on each computer, which is supposed to have access to the EC2 instance. In addition, if the students are expected to have access to the EC2 instance from their personal devices, that same key will have to be made available to them so that it can be imported into their devices. Home computers and laptops are expected. Mobile devices, however, are also possible. I routinely use my cheap Samsung Galaxy J1 to SSH into servers I maintain. It is possible, with more work on your end, to have a different passphrase on each of the distributed copies of the private key. The command above creates one without a passphrase. Removing the -N '' option will cause ssh-keygen to prompt for a passphrase during creation. After the private key is copied to a different computer, of different directory, the command ssh-keygen -p -f student_access will prompt for the old (if one exists) and new passphrases, re saving the private key with that passphrase. Having a passphrase on the key will prompt for it when the key is used, with some caching, causing the SSH access to be double passphrase protected. Of course, knowing the passphrase also allows the student to change it to a blank, also valid, passphrase with no way for you to enforce it having one.

No matter how it is done, with or without passphrases, you could end up having nearly a hundred copies of the private key floating around in student hands. That is per class. In addition, so that they don't loose the key, you can expect that some of the students will email it to themselves, causing it to be even more "distributed" than your original plans.

If, as I do, you prefer to use GnuPG for handling keys, the following snippet will create the key pair, in a soon to be deleted sandbox directory.

mkdir sandbox
pushd sandbox
mkdir -p .keyring/{openpgp-revocs,private-keys-v1}.d
chmod -R 0700 .keyring/
gpg --homedir .keyring --batch --pinentry-mode loopback --passphrase '' --quick-generate-key student_access@AWS-EC2 rsa4096 auth 12m
gpg --homedir .keyring/ --batch --pinentry-mode loopback --passphrase '' --output student_access.gpg --export-secret-key student_access@AWS-EC2
gpg --homedir .keyring/ --output student_access.pub --export-ssh-key student_access@AWS-EC2
popd
mv sandbox/student_access.* .
rm -rf sandbox

The student_access.pub file is, again, the one to use in each user account on the EC2 instance, and looks the same as that created by ssh-keygen above. The student_access.gpg file is copied to each local machine, and account, where the command gpg --import student_access.gpg is used from within that local account, adding it to the user's default keyring.

The option group --batch --pinentry-mode loopback --passphrase '' in two of the commands creates, or uses, a blank passphrase for the key. Removing the entire group results in prompting for the passphrase during creation, and exporting the private key. Alternatively, it is possible to include the passphrase in the commands by placing it inside the single quotes. The command to change the passphrase in this processes is gpg --change-passphrase student_access@AWS-EC2 with a prompt for both the old and new passphrases.

Point 3 - Let students pick their password

This is standard Linux behavior after creating a user for each on the EC2 instance, and takes care of itself. The only protection taken in this setup is to prevent them from making their choosen password as blank. If, as mentioned above, the make that choice, they will be locked out of their account until you issue the command: sudo passwd user_name and enter a new password, which they would be expected to change, to a non-blank version this time.

Alternative setup:

Teaching Linux basics and BASH implies the command line as well. That seems like a good time to also cover some of the aspects of security. The rollout of the provisioning for each term can be included in the corsework. This can include the command line use of ssh-keygen, or GnuPGP (gpg), as the case may be. (Both is also an option.) The inclusion of C in your couse suggests that git could also be included, in which case I would recommend the use of gpg, as that will allow creation of both an authentication key for access to the EC2 instance and a signing key to use on signed commits in the repository. Especially usefull if you have group projects planned.

Teaching about security should also imply that you are doing security with the setup of the students' system. The single RSA key pair seems contrary to that. If a student leaves the course early you would be expected to create a new key pair, and redistribute it all over again. Otherwise that student need only guess another student's password, if it wasn't already shared with them, or they didn't watch it being typed, and have access to a former classmate's account. Of course, that applies even if the student has not left. They could still have learned another's password and then have access to a fellow student's area, and work, on the EC2 instance.

Having a key pair unique to each student can be more complicated. Especially if the local computer situation is such that any student could be using any workstation. It is possible that the use of EC2 instances for the student workarea is the solution to the other problems associated with undesignated workstations in the classroom. Some of the issues can be resovled with roaming profiles for the school network. If that is not something the school has established, however, it isn't any help here either. Using USB thumb drives is also an option, and the SSH key, or GnuPG keyring, could be kept there, either by default as part of the login profile, or manually. The ssh command allows for the identity file to be explicitly named with the -i /path/to/identity/file option, and the gpg command accepts the --homedir /path/to/keyring option as well as the GNUPGHOME=/path/to/keyring environment variable. In both cases the thumbdrive could be the path used.

The other side of the complication can be significantly reduced by using shell scripts for creating and distributing the key pairs, if it is not added as lesson material for hands-on lab work in the course. The first day of class could be built around accessing the EC2 instance prior to public key authentication, where they change their password and create, import, and backup their keys. Use ssh-keygen for the first day. Later, when their corsework has progressed to that point, create, and authorize new keys using gpg, which can be expanded later by adding a signing subkey for git commits, and then an encryption key for other work.

The snippets given above (for creating the keys, and for provisioning the EC2 instance) are well suited for using shell parameters in variables and the entire class could be supplied with keys, and EC2 user accounts, using scripts you create, and cancel the majority of the work you would need to do for each class.

The security issues, in my mind, seem to outweigh the "convenience" of a single key, and scripting can greatly reduce the time and effort involved in using unique key pairs for each student, and even for each device students might have, and wish to use for the class. Android and iOS apps for SSH have either the ability to generate key pairs, or to import them. Some have both options. A few also have the ability to export their private keys for storage.


Curriculum choice for AP Computer Science Principles

TL;DR Teach CS50 AP.

I taught AP CSP this past year, and I cannot speak highly enough for the curriculum that CS50 has written for this course. I'll try to enumerate its strengths as objectively as possible:

It actually feels like a legitimate AP course in the sense that it is a college course (the most popular one at Harvard and I believe the most popular MOOC as well) adapted for high school. The connection to Harvard adds great legitimacy to the curriculum and engages students.
The curriculum scaffolds nicely for beginners or students with a little background (especially Python). The language progression from Scratch to C to Python helps students build a foundation in computational thinking and progress towards more advanced programming constructs, culminating in building engaging web apps.
The resources available are unparalleled. CS50 has every lecture on video from every past iteration of the course. There are video shorts for every important concept along with additional study pages. Plus, there are communities here on SE and on Reddit.
It is about more than programming. CS50's three pillars are "accessibility, rigor, and culture." It brings all students to the table, challenges them, and also creates a classroom environment that stress community over competition. Events like CS50 Puzzle Day set it apart from any other class out there, AP or not.
The teacher support is incredible. I'm a part of a community online of other CS50 AP teachers, and it was invaluable throughout this past year. They constantly reach out and cultivate connections among teachers of the course.
The course stress student growth. As they say on their syllabus, "what ultimately matters in this course is not so much where you end up relative to your classmates but where you, in Week 11, end up relative to yourself in Week 0." This stress on a growth mindset approach is perfect for beginners.
Students are more than prepared for the AP Exam.

I could keep going on and on, but this is sufficient for now. I believe strongly in CS50 and CS50 AP. The edX course CS50 quite literally changed my life. As one of their shirts says, I am "CS50 Proud."


I highly recommend Database: Principles, Programming, and Performance, by O'Neill and O'Neill. Learned from that book for my first database course and loved it.


Do you know online courses with Haskell for Theory of Computation?

This is another not-an-answer that might provide some useful resources. The last is probably the best, but not Haskell related
The two old standards for such a course are:

Introduction to Automata Theory, Languages, and Computation, by Hopcroft, Motwani, and Ullman. Earlier editions were just Hopcroft and Ullman.

Introduction to the Theory of Computation by Sipser.

I don't have the second book, and don't know if it includes any programming exercises, but there might be something in Scheme, knowing Sipser. Amazon's "Look Inside" doesn't seem to work for Sipser.
Two additional books, both very old and hard to get but very highly recommended if you can find them - both short and straightforward with clear explanations are

First Course in Formal Language Theory (Computer science texts)
by V. J. Rayward-Smith, and

First Course in Computability (Computer Science Texts)
by V. J. Rayward-Smith

The final suggestion is a software system with an associated text.
JFlap was created by Susan Rodger and her colleagues at Duke to form the basis of such a course. Students can easily create all sorts of finite automata. The book they wrote to go with this is JFap: An interactive Formal Languages and Automata Package, Rodger and Finley.
Wikipedia has an overview of JFlap.
Note that JFlap writes automata descriptions in XML which should be easy to parse in any language. All of the automata mentioned in the JFLap tutorial are available for download.
I was part of the NSF evaluation of this system and it is really excellent.


How to prevent dictating the solution when tutoring

After I wrote what is below, I realised that most, but not all, of it is for her. Your role is to help her take on this practice, to stop her jumping ahead, and to slowly get her asking herself the questions.
Separate algorithm design and coding.
Help her to separate, designing the algorithms and programming. It is too much to learn a language and to learn to program at the same time (Even if the language is not C++).
To do this try physical and paper activities. E.g. for displaying the world. Walk it out. She is the cursor, see walks the path of the cursor placing sheets of paper (characters), on the floor.
Break the task up

We need a 2d world. I don't know how to do that, but I think I could do a 1D world, and I think I could then build on that to make a 2D world. So I will create a model for a 1D world, and write a display method for it.
Let me change the values in the model, does it display correct?
What if I change the model after it is displayed? it should change the display. So do that.
Now let me try 2D.
That is the display (output part) done.
That next.
…

Ask these questions. On each question don't look ahead (don't try to do too much at a time). Get her asking herself what the next step is.
In general start with the output, then the input, then the process. (on more complex systems, you will not do all of the output first. You would do  repeat { output, input, process }.
The difference between an expert and a novice is not that the expert can keep complex ideas in her head, but that they do one thing at a time, so only keep one thing in their head.
Summary
Repeat this 4 step process

repeat until complete

Thing about what to do next e.g.

First it compiles but does nothing
Second displays 1 line of world.
…

Use a physical activity to design the algorithm e.g.

Embody the cursor.
Use a checkers board, or other objects to model the model.

Decide what done looks like (for this iteration only: e.g.

program compiles,
Computer displays -----*-----)

repeat until done {Write code, test}


What can CS educators do to help teachers of other subjects include computing in their teaching?

Every field has its own key issues and methodologies. History and Literature, for example, are very different from Computer Science.

However, it is in the interest of those in other fields to promote computational thinking. It is a skill that their students need and it can be a tool in their own work. However, to do this two things are necessary:

First is to examine the current working practices in those other fields that use computational techniques in pursuit of their own goals. Literature, Science, Geography, History, Mathematics, the Social Sciences, all use computation for at least part of their normal work. This can be communicated to students and students can and should get practice in their use.
Second, and harder, is that it likely requires some collaboration, up to the level of team teaching, to bring good techniques to the fore for students. In other words, we in CS need to become servants to the other disciplines to help them deal with their own questions.

Computational Thinking is a big deal in the US now. It can start very early in a kid's life. Piaget and The Montessori method took a shot at this long ago, with success. But it needs to go beyond just math, into, say, Algorithmics and Big Data.


How to use CSS diner to teach beginners in CSS

(as promissed in another question, this is my answer)
focus only on the starting exercices (I go from 1 to 11)
first teach the theory .class, #id, tag, and the selectors for and, or and child (ie p .some_child)
Then allow them to to the exercices; and after do them together
You can often solve one exercise in multiple ways. While this does not help the concept the exercise wants to teach, and sometimes is not very semantical (say, for example, selecting all apples inside plates and all pickes inside plates, when you wanted everything inside a plate) it helps reinforce the selectors


Take a look at MOSS from Stanford (https://theory.stanford.edu/~aiken/moss). It is an easy to use free web service that compares files and reports similarities. You set up a free account and submit a request and what is returned is a URL to a report showing the similarities of various files.
I have found that the easiest way to do this is to submit a .tar file structured at the first level as a series of sub directories, each identifying a single student (name, studentID, etc). Beneath each student directory are the file(s) they have submitted. These commonly have exactly the same names as the assignment typically specifies the class names of the Java classes.
For small assignments, you will get a high correlation between students as there is only so much variation possible, but you can look at the "most similar" and get a good feel for whether cheating is likely to have taken place. Depending on how the students actually submit their programs, it may be easy to write a script that automates the process. I'm happy to share details with anyone


Try this as a trivialised example in order to help people get their head around some of the ideas. It's not strictly accurate, but I think it will help with understanding the concept.

Start with a short message (in text) and round up to a multiple of 16 bytes, padding with spaces.
Replace the final space with a non-space character
Take the m5sum of the result, and look only at the last digit. If this is '1', you're done and have finished the block.
If you're not done, go back to step 2, and modify your non-space trailing padding.
After finishing a block, you can append a new message, pad again, and repeat the process of modifying the whole message to achieve the target hash.

In practice, the hash function is expensive to calculate (and will have far fewer collisions meaning many iterations will be required to search for a suitable padding section).

Although a single block could be modified, once the modified block has been wrapped into a subsequent block, a couple of times, the compute cost of re-writing an older message grows significantly.

What this generates is a publicly readable message, which can't be re-written in the future (and everyone can verify the accuracy or an old message).


Should we merge technology departments with the science departments?

Rather than providing experience, let me add a bit to a way you can think about the issue and, perhaps, resolve it.

You are correct that the scientific method, the mathematical method, and the computing sciences method are all distinct. So, experiments in the Chemistry sense are much less important and frequent in CS. However, there are some synergies, and the sciences can provide useful examples for the creation of programs and systems. Also, Computing can be useful in the sciences, handling Big Data, for example or executing theoretical models.

I'd suggest three things to think about.

Is this a bottom up (faculty driven) initiative or top down (administration wanting changes)? The latter is likely to be much less successful.
Are the faculty already knowledgeable cross-discipline? It will be much less successful otherwise.
How important is it to you to have pair-teaching (co-teaching, team-teaching) of several courses in your institution? Especially pair teaching with instructors of different core disciplines. Without that, I wouldn't expect a lot of benefit other than needing fewer "department chairpeople".

Synergy is possible and valuable. But forcing it won't work very well.


Similar to @ncmathsadist, I use both command-line environments and IDEs, and I have only found them enhancing each other.  We do most of our work in IDEs, but a few assignments are done in CLIs every year to ensure that students slowly gain some familiarity with those environments.

Reasons for IDEs:

Convenience
Easy integration with GitHub
Error highlighting (though I have some issues with this)
Ease with packages and project integration

Reasons for CLIs:

There are still plenty of important computing platforms (including both iOS and Windows!) that ultimately reduce down to CLIs.
Good luck explaining the string[] args in public static void main(String[] args) if students don't have any experience in CLIs.
Even a little POSIX familiarity goes a long way.


Textbook or video lectures to develope intuition for solving any unseen Graph Theory problems

I'm writing only a partial answer, because I currently lack time. That means that I'm not properly sourcing everything, and largely working from my own memory.  I don't believe that anything I say below will be wrong, though it is definitely possible that I might be forgetting a few things.  In any case, hopefully this will be enough to get you started / unstuck.
The test does look quite difficult!  I teach several of the topics, and they were largely what I would expect from the end of an undergraduate university degree, but with the added pressure of timing and high stakes.  Ouch!
When attempting to gain fluency (in any topic), you are looking to make a few kinds of connections:

"This is just like..." -- these connections allow you to utilize systems that your brain already understands well.

"These ideas group together" -- this is called "chunking", and it is how we group small ideas into larger and larger pictures.  When you "chunk" ideas together, you are able to manipulate the chunk in your mind instead of all of the small details.

"This system looks like" -- much like #1, this allows you to "see" how systems work in your mind's eye.  Then you can manipulate your visuals.

In essence, you are trying to group and simplify ideas.
To gain fluency, additionally, don't be afraid of memorization (though don't focus on it exclusively, either.)  The purpose of memorization should not be to be able to regurgitate everything, but rather to give you quick enough recall that you can use the idea in a larger system.
Think about it this way: there is a cognitive tax to using any idea that we know.  If the cognitive tax is very high, then using the idea takes nearly all of our focus.  This limits what we can learn, because to really understand larger ideas, we need space in the active, working parts of our brain to encompass all of the smaller ideas that the larger idea needs.  If the smaller ideas are taking up all of our active resources, that becomes impossible.
Thus, the goal of memorization is to reduce cognitive tax.  If you are working hard to memorize beyond that, then you are wasting your efforts - you are not going to gain further fluency through memorization.  You need to instead focus on chunking, visualizing, and relating ideas to one another so that you can see bigger pictures and larger groups.
Also, it is useful to practice on a mix of simple and hard problems.  The first group reinforce and strengthen the patterned connections that you have already made.  The second group force you to stretch those patterns out in new directions, and can help you spot new uses and simplifications.
I have always found that teaching others helps me to gain fluency, as it forces me to make explanations that distill systems for other people.
Good luck!


How do people prefer to learn web development - videos or text?

As a student, I get a lot more from blogs.  Many of the videos I have seen are pretty hit or miss.  With a blog, I can scan it in a minute or so and be able to tell if it holds the answers/info I am looking for or curious about.  With a video, there seems to be a much longer time commitment due to more forwarding, searching and hunting for an overview of the video's quality.

I think it may depend also on what you are trying to do?  Are you trying to relate an entire concept? Or is your approach more targeted towards demonstrating specifics, edge cases, etc?  I think for broader overviews, videos are more helpful from what I have seen with my peers and myself.  Blogs seem to do better with content that has a narrower focus, especially if specific, concrete examples are included.

There may also be the notion of data usage and accessibility to consider.  It is much easier to download a webpage then read it later or offline.  Not much data has to be transferred for that to happen.  Video of course takes much more data to transmit and more room to store.  Those may not be major concerns for everyone but some places I'm sure the difference between the two is enormous.

Whatever you choose, thanks for doing it and helping the rest of us learn, it is appreciated!


Presenting Mapping Reducibility (for P vs NP)

Considering that you teach HS students, many of the reduction examples "off the market" might be conceptually a bit too complex, and can be confusing even for many college students.

I'd suggest that you choose an example between very similar problems, like the (polynomial time) reduction from 4SAT to 3SAT.

So, what are 4SAT and 3SAT? SAT is the Boolean satisfiability problem, or, given a Boolean formula phi, we want to decide if there is a solution to the equation phi = true.

These equations are usually written in conjunctive normal form, or a series of conjunctions of disjunctions, like: "(a or b or c) and (c or d)". When each clause has 3 terms, the problem is called 3SAT. When each clause has 4, it's called 4SAT. Now you might get a sense how one could reduce from 4SAT to 3SAT. One possible reduction (which is extremely simple) is described here on the Math SE.


Learning suggestions for AI and neural networks for a mathematician

The online textbook Neural Networks and Deep Learning by Michael Nielsen is quite good for mathematical content. It assumes the reader understands calculus, but requires no prior knowledge of machine learning. The book's own introduction explains fairly well what the book is about:

  The purpose of this book is to help you master the core concepts of neural networks, including modern techniques for deep learning. ... One conviction underlying the book is that it's better to obtain a solid understanding of the core principles of neural networks and deep learning, rather than a hazy understanding of a long laundry list of ideas. If you've understood the core ideas well, you can rapidly understand other new material.


How do you structure broad, open-ended, freely chosen projects so that students use class time wisely?

The first step is for the students to design their own projects.  I give them a timeframe, and make clear that they will be held accountable (within reason) for finishing the project.  I don't just accept the project proposals blindly - there is a negotiation here.

There's an odd twist to this step, actually: I often have to persuade the students to lower their sights a little bit, because they often have a poor sense of how long their grand idea will actually take.

Any changes after my approval, however, must run through me.

Every other Monday, the students and I negotiate/create biweekly mini-milestones.  They know how many weeks they have to complete the entire project, and they then tell me what they feel they can get done within a week.  It has to be highly specific (so that it can be evaluated), and both the students and I must feel that it would mark sufficient progress towards their overall project goal.  (In my experience, I find that I simply accept their goals directly about 75% of the time, and in the remaining 25%, I have to steer students towards easier goals about as often as harder ones.)

When the actual evaluation takes place, if they have met the goal, then they only need to tell me what they intend to accomplish for the next week.  If they have not met their goal, then we have a more in-depth conversation to figure out how to recover so that the project still reaches completion.

That's the mechanics of it.  A few interesting takeaways:

One of the greatest joys of the entire enterprise is just getting a chance to ask them questions during the weekly check-ins.  I've personally never created a Chrome extention, a Unity game, a Flash game, or an iOS app, so getting to ask questions about the model code they've found, and the changes that they are making, teaches me quite a lot.
Using this structure, I don't have to weight the final project itself as heavily as you might think.  If the mini-milestones are well-formed, then the projects almost always come out very well.  In the few instances where it does not, the mini-milestone structure has ensured good work throughout, and there is typically some external factor that got in the way.  The grading seems to be more fair this way.


How can I integrate teaching source code control (Git/Mercurial/etc) into my introductory CS class?

There are quite a few solutions which allow you to make a VCS part of your teaching.

For example, GitHub Classroom allows you to create assignments with some starter code, then invite your students to work on it and submit their changes through Git. They provide a promotional video here, which shows the workflow with it.

Scaffolding Version Control into the Computer Science Curriculum states:

  VCS and other professional tools are often introduced
  later in the educational curriculum, possibly in a software
  engineering course, generally a second-year or later course,
  and may not be reinforced through repetition and application
  in later classes. This is unfortunate, because powerful
  tools such as VCS can also be difficult for new users and
  especially those new to programming and software in general.
  The power and flexibility of new distributed VCS can
  make them especially challenging, unfriendly, and distracting
  for students already fully engaged in developing core
  competencies required in the computer science curriculum.

They propose GitSubmit as a helpful solution here, describing it as "A Custom Environment for Introducing
VCS to Novice Developers". Clearly, it's helpful here to introduce VCS as soon as possible, to avoid the issues described later in the paper, where higher level students have virtually no experience of using a VCS, despite its importance in industry.

For the pedagogical challenges, the presentation Challenges and Confusions in Learning Version
Control with Git seems interesting. They conclude:

  Introduce authentic/relevant use cases to motivate the use and
  learning of the system
  Authentic practical courses cause students to see the value of
  VCSs
  However, use VCSs throughout the curriculum, as, for instance,
  limited resources available during authentic project courses may
  limit how the system is adopted


Search for a useful interactive programming environment

I am not too worried about language. I am just looking for a nice
  interactive learning environment, that combines the best of REPL and
  editing. Can you tell me of anything that you use or know of?

Runestone Academy has a component called ActiveCode that allows you write Python code and run it. It also has a slider so that you can go back to earlier versions of your source code to review and run.

In addition to activecode, you can also execute Python code with the assistance of a unique visualization tool. This tool, known as codelens, allows you to control the step by step execution of a program. It also lets you see the values of all variables as they are created and modified.

There is a lot more to the web site but is what I use to help others learn Python 3 and the nicest part is that once the students get the hang of the e-books they tend to take off at their own pace.


Differentiating Inclusive from Exclusive Or

Play the “if you have brown hair stand up” game.

For the introductory lesson. We use this to introduce selection (if statements), and a little bit of boolean logic.

  “Stand up if you have got brown hair.”
  “Sit down.” look around “Stand up if you have blue eyes.”
  …
  With out asking them to sit down “Stand up if you …”
  Address why some people are still standing, are they correct [yes], or are the seated people correct [no]. Why? [because I did not ask them to sit].
  …
  “stand up if you have brown hair or you are …” (this is where we start to cover Boolean logic, I have only done and, or, not).

In another lesson you could add xor, nand, nor.

Xor examples

  “if you have blond hair or you have blue eyes stand up”
  “if you have blond hair xor you have blue eyes stand up”


How to make students confident enough to stop copying each other's code assignment?

Growth
You say they copy the intelligent students, so first watch https://www.ted.com/talks/carol_dweck_the_power_of_believing_that_you_can_improve?language=en
Feedback
Then stop with the sumative assessment (Stop grading them). Encourage mistakes: I just heard of a company that has a mistakes wall. They seed it with a few famous quotes about mistakes. Then the leaders (teachers) add some and sign them. If others (students) add to the wall, then the first ones are praised (and awarded prizes), until it becomes the norm.
Help them to get in a situation where they are making small changes, making many small errors, experimenting, learning from feedback as the program runs. Give them code to change. Encourage small changes. Encourage testing after every change.
Programming
Before teaching programming languages, teach them how to program, and before that teach them how to solve problems: That is start unplugged.
Get them to do every problem manually. Teach them to think like a computer. Get them to solve problems like they are a stupid robot.
Then get them to document what they have done. As a set of steps. Get them to test it. Get them to ask their peers to test it. Show them how to test it. Get them to debug/fix it. Show them that you make mistakes. Show them how you fix your own mistakes.
Then when it is working, show them how to translate it, into the chosen programming language.


Uses of selection in programming (if, switch etc)

There are endless examples that illustrate selection. As you know, most useful programs have at least one selection statement. I've found that some students struggle with the concept, so I start small and pick examples that resonate with students, for example:

    if (hungry)
        System.out.println("Eat a sandwich.");

    if (age > 17)
        System.out.println("You can vote.");
    else
        System.out.println("You cannot vote.");

For a switch statement, I like to show some type of menu:

    switch(choice) {
    case 0:
        System.out.println("Balance Inquiry.");
        break;
    case 1:
        System.out.println("Transfer");
        break;
    case 2:
        System.out.println("Withdrawal");
        break;
    case 3:
        System.out.println("Deposit");
        break;
    default:
        System.out.println("Quit");
        break;
    }


How do you teach Big O to high schoolers with varying degrees of math exposure?

One good overall educational strategy is to teach the same thing to students repeatedly, using a Spiral approach, in which each turn of the spiral teaches at a deeper level. Don't expect the students to completely get much of anything at the first mention of it, but reinforce the ideas and deepen the knowledge. You can do this for many things in one course, but you can also do it over a student's career.

As you say, it is a mathematical concept and students may not yet have the tools needed to completely get it, but you can start, and you can give them enough insight so that when Big O comes up later, say in their undergraduate education, they have some prior basis for understanding it more deeply.

However, it is important that you don't oversimplify the topic or to give them false information, leading them to misconceptions that require un-learning later. So, first, be honest: the topic is mathematical, it is a bit deep, we can only scratch the surface a bit.

For young students without a solid algebra background and little exposure to calculus, it might be good to start with a graphing calculator so that students can see what happens to common functions as the independent variable increases. Graphing $log(x)$, $x$, $x^2$, $2^x$ etc is a start. Graphing $1000x + x^2$ can give them the idea that the high order term dominates the growth. If they can see it, you don't need to depend on their knowledge from elsewhere.

Next, you can show them a few algorithms and look at the actual run times, noting that you are only giving them an idea. One of my favorite "tricks" is to ask students who have seen a few sort algorithms, to come up with the most inefficient sort algorithm they can think of. With a good randomizer even repeatedly randomizing an array and then checking to see if it is sorted is an algorithm by the law of large numbers. If they know about permutations they can even calculate the maximum number of iterations needed to sort. If they are not likely to know that from other places, then computing permutations can be an earlier programming exercise.

The problem with teaching the first cycle of a deep knowledge of Big O is that it is easy to give the wrong impression about a lot of things depending on the words and examples you use. If you say that, for example, bubble sort is $O(n^2)$ you are correct, but it may have little meaning. It doesn't mean, however that the "running time" of bubble sort is $n^2$, but (if $n^2$ is the best bound) that it is "proportional to $n^2$ for large values of n." It is easy to forget to say those extra words: "proportional", "large...". It is also easy to forget that Big O is about upper bounds, only. So technically, Bubble Sort is also $O(2^n)$, but it would probably not be wise to stress that in the first cycle of learning outside a mathematics class.

Also, the examples matter. Bubble sort (if unoptimized) always runs in quadratic time and you can see that from the algorithm. It depends only on the size of the data set. But insertion sort is different. The normal program has two nested loops, just like bubble sort, but if the original dataset is already nearly sorted (by some measure of "nearly") then it actually runs in near linear time - or even linear time, for some examples. But it is still a quadratic algorithm, since its worst case behavior is quadratic. So, "worst case" is another important word to keep emphasizing.

You also need to mention, but probably not stress, is that efficiency need not be determined by the size of the data set necessarily. Factoring large numbers is an example. There is only one number to factor, but it is harder to do for larger numbers since (for brute force, anyway), the difficulty is determined by the number of possible solutions, which is itself large (but can be estimated).

A third complication is that it isn't always time complexity that is needed. Space complexity is also often important. How much "scratch" space does an algorithm need for datasets of different sizes (or datasets of different complexity, or ...). A recent (early 2018) experiment(pdf) in Artificial Intelligence, pitted two different AIs against one another. One of them "learned" that it could "win" the competition by forcing the other to use more and more memory space, resulting in a crash of the other.

Another idea to get across is that if the numbers (data set size for example) are small, then using a highly efficient algorithm may be worse than one theoretically more "inefficient". Big O is about asymptotic behavior, of course and the more efficient algorithm may be more complex and actually be worse on small data sets as well as being, perhaps, more likely to be buggy. Some quick sorters, for example, revert to a quadratic algorithm once the split gets the datasets small enough. I once built a product that had an exponential algorithm embedded in it. That worked, since the likelihood of a large dataset was vanishingly small. Integer Programming is actually done by real programs in the real world in spite of the complexity of the problem itself.

Finally you need to note that Big O is about algorithms. That is related to the complexity of problems, but isn't exactly the same thing. There are a lot of array sorting algorithms and they have different exponential behavior. But the problem itself has an inherent complexity. For sorting int or long values (the built in data types) in a computer, the complexity is actually linear (Radix Sort). You need some sort of a BigNum data type before you reach $O(n*log(n))$, since the number of possible values in int is bounded. And for large numbers of arbitrarily large values, you start to run into space problems for most purposes.

Let me note, for completeness, prompted by a "conversation" in comments here with user RiaD, that any algorithm that is $O(n^2)$, such as Bubble Sort, is also $O(n^3)$ and $O(n^4)$ and $O(2^n)$, since all of those other functions dominate $g(n) = n^2$. One normally gives a "good" estimate, but the "worse" estimates for growth apply by default.

tl;dr: Say what's true. It is a complex, mathematical topic. Examples are good. Deep understanding can come later. Completeness isn't essential in the first cycle of understanding. Take that into account when testing.


Reducing bias, from lesson that improves, as taught to a number of classes

tl;dr: My best guess is that your process is fine and you aren't inducing preventable bias (unless the students are in competition with each other)

It may be that you cannot. It may be that your analysis is incorrect. It may be that a solution would be worse than the status quo. It may be that you need not make changes.

One solution would simply be to not improve this week's lesson but use the knowledge about the class to improve next week's lesson or worksheet and hold it fixed until the week following that one. Suboptimal, surely, but "fair" by some definition of "fair.

Your assumption that your sheets improve as you go is only your assumption. It may not, in fact, be accurate. Each of your groups is different and will interpret things in different ways. It may be that your improvement is a distraction or impediment to the next group (see below). It is hard to know until you interact with that group. Every student is different and all are different from you.

If you have thousands of students you can do a statistical analysis, of course, to determine if there is an bias effect.

You don't say whether your students are in some way in competition with each other (a generally poor practice). If they are, you need to worry about "bias", but if they are not then you just need to do the best thing you can for each student.

However, if you really suspect that bias is an issue and that some students are being advantaged and others disadvantaged by your scheme then you need to change, or at least adapt, it. You may need to set some time aside at the start of a lecture to get each group on the "same page" about the current state of things as you understand it. A few minutes of "warm up" at the start of the class can be helpful in any case. I often opened a lecture asking for questions that might have arisen, but you can also use it to make corrections/apologies/give encouragement/add emphasis...

A technical solution, of course, would be to provide some communication channel to all the students so that all can see any updated materials in a timely manner. You could even provide the lecture materials prior to the week's start and warn that they may be updated as the week progresses. Students could then, for example, print them out before class and use them to help follow the lecture. If you have a way to highlight changes to the base document, all the better.

I once taught the same course to three groups in back-to-back periods of about an hour each. I would take questions and use the questions from each group to improve the lecture for the following group so that the same questions needn't be asked. However, I learned (eventually) that the following group might not have the same questions and might have seen the concept clearly already, so I was proactively answering a question that needn't be asked or answered. This accumulated into the third section of course and I found it hard (impossible) to complete the lecture in the third section. Let each group be itself, but if you make a mistake, fix it of course. If you say something dumb early on, you don't need to repeat it to avoid "bias."

A follow up:

While I believe that you need to work to teach every student in every interaction (i.e. each class period for this discussion) it is probably beyond our ability to give each student precisely what he or she needs most at that time. If I am Socrates, teaching one student at a time, or if I'm an Oxford Don, teaching 5 student tutorials, I can probably do that, but with twenty to two-hundred students in front of me all I can hope to do is to make sure that each student can learn something that will advance their learning. Even that is a difficult task with mass education, but it can be achieved. Some students will learn more, because they are primed to do so, and some less, due to factors of their own making or otherwise. Teaching everyone precisely the same thing is not an achievable goal unless the everyones are just robots. Help every student advance. Don't favor anyone arbitrarily.


Best online problem-bank style practice site for Python

I didn't spend a huge amount of time looking over the practiceit resource you linked, but I glanced at a few problems, and they seemed similar to http://codingbat.com, which has exercises in both Java and Python.


Do you use any teaching assistant tool in your CS1 lab classes?

When I was a TA, we used tools to automatically:

Collect submissions and run them against set of predefined test cases
Give instant feedback to students on how they did based on the test cases they passed/failed
Give feedback on the quality of their code
Generate plagiarism reports

For plagiarism, we used MOSS. For everything else, we developed a tool called AutoGradr.


What is a good introductory language for high school?

If Advanced Placement CS is in their future, then Java is probably the best language choice as it is still used in APCS. There are also a lot of resources for Java development that also permit graphics based insight. The course probably wouldn't be about developing for the web, though.

But because of the APCS link there are a lot of resources intended for novice programmer development.

One resource (Java) that is very useful for such students, and has a lot of project ideas built in to it is Greenfoot, which uses a rectangular grid to place visual representations of objects and lets them move an interact according to the student program. There is also a dedicated teacher resource for it: Greenroom. It has additional greenfoot projects and a forum for discussion.

Otherwise, Python is a pretty good choice for beginners. It has less syntactic load. But the set of resources for novices is a bit more scattered.

But any programming that uses some visual metaphor is better for student understanding than just numeric programming. It needn't be web based, but should be graphical. Games are pretty good for this provided that they aren't just textual. Any simple board game can provide a nice way to visualize what a corresponding program needs to do.

But, one way to avoid the two language issue in web development is to have the students build only the back end or only the front end with you providing the other. It also defines a set goal that students can program toward. The part you build can be in a different language than that used by the students, of course.


Constructing a curriculum from multiple resources for complex subjects

At this scale (fewer than 5 students) lectures are a poor choice of educational methodology in any case. Lectures were created as a way to scale up education for the masses. They are driven by economic considerations, not educational ones.

What you have here is precisely the scale of an Oxford University Tutorial in which a few students meet a few times a week with an expert who guides them. Students prepare work in advance. The tutor comments and guides them. He/she can suggest readings, possibly different for each student, and sets new tasks or re-work on existing tasks.

You can also investigate Inquiry Based Learning (Thanks to User skull for proposing that idea in the classroom). This is essentially the same concept as the tutorial, and emphasizes Active Learning.

Thirdly, you also have precisely the scale for a small Agile Software Development team that could be set to a building task using one week iterations that also required that they learn about the language, process, and OO principles as they go. You become both the product customer and the learning Coach. When their code could be improved, show them how in your meetings and have them update it in the next "iteration". With this idea, perhaps combined with the tutorial idea, you can encourage them to teach one another so that not everything they learn comes from you. This can also take Active Learning to the "next level."

As an undergraduate in Maths (shortly after Plato's death), I had at least one course with such a small number of students. One of our tasks was to periodically prepare a topic for presentation to the rest of the class. This might also be possible. Their "lecture" might only require a few minutes and be accompanied by a Q/A session. You can do a wrap-up yourself. This technique can also, over time, helps students overcome their natural reluctance to perform publicly. Many of them will eventually go in to careers in which such performance can be a valuable skill, so you can advance their skill/knowledge on many fronts simultaneously. For some of the students you might need to review their mini-lecture prior to their presentation, both for content and for reassurance.

The real issue is that different people have different ways of learning. You already recognize that and have made adjustments for it, but you may be able to go farther.

I'm not sure that this scales to as many as ten students, however. But some of it might for relatively advanced (i.e. experienced) students.

For a more direct answer to your question (finding resources), you can have the students assist in this. Some sort of computer mediated communication (email list, wiki,...) can be used and students can contribute helpful resources to it. You can reward them for this, also. If it is something like a wiki, you also preserve the resources for the future. You also have a handy way to toss in resources as you come across them and students will have immediate access. Students can also, perhaps, comment on the helpfulness of their peer's contributions, aiding your eventual evaluations.


What language best prepares a high school student for a STEM undergraduate major?

There isn't a best language, other than the language that you know well and can use for modeling things. Python is good. And it is reasonably straightforward for a young beginner.

Don't fall into the trap of thinking that a lot of languages learned superficially is valuable. It isn't and can lead you astray.

But the things you list aren't enough. The big idea of modern computing languages is "abstraction". Object oriented languages like Python do a pretty good job creating values that have sensible behavior that can be composed into programs.

In the US, a CS program is more likely to use Java than other languages, though it isn't universal. Another good language is Scheme, but with a C++ background you might have a harder time teaching the essence of it.

And, don't fall into the trap of teaching Python as if it were C++ with more words. Each language has a mental model that is worth the effort to learn.


Operating System Concepts by Silberschatz and Galvin, how much down the edition timeline can I go to safely understand the core-concept

I don't know this book in particular, but I do know Computer Science text books in general, and offer this advice:
Consider the title: Operating System Concepts. It is about basic and fundamental concepts that underlie operating systems. The basic concepts, the core material of the text, are not going to change much from first edition to the tenth.
You are not being asked to study the text in such detail that you would be able to discover the differences between versions.
Many computer science books do get out of date. If the book was a user manual for Windows or a iMac then having an up to date one might be important, but I suspect not in this case.


How Effective Is "Rosetta Code" as a Teaching Technique?

Here I think the teacher's instinct and experience is the best judgement. You know your own students best. Your worry, of course, is well founded, especially since the two languages are so different.

Learning to think functionally is a big deal and a mind expander. In some ways doing it cold-turkey (with no support) is good to do, since the students need to just thrash about until the see the A-Ha. But that can be very frustrating. It isn't good to leave your students frustrated, of course.

Another reason for not using the technique you suggest is that you don't want their functional code to be just misspelled C#, using ideas from imperative and/or object-oriented thought patterns. Code in one language based on knowledge of another can be truly ugly and the programmer can miss the elegance of the new language.

And functional program can be truly elegant and mind expanding.

To balance the trade-off you can, of course, use "Rosetta Coding" only sparingly. And only when it seems really needed. Perhaps you could start out without it at all and use it only in situations in which the students are struggling, rather than as a main-line technique. You could also use it only when working with individuals (office hours) rather than with the larger group if a student needs to be reminded of the basic structure of an algorithm. Personally, I wouldn't use it as the main structure of the course and am happy to let my students thrash a bit in mildly turbulent waters. But that needs limits also, of course.

Salt is fine, but don't over-salt. Judgment and a bit of restraint, perhaps.

Since the two languages are from different paradigms the difference in resulting code can be quite stark. For example, reversing a list in linear time in Scheme is quite a lot different than you would likely program it in C# with mutable data. But even Java and Ruby, closely aligned, are not the same language and have different thought  patterns. It is the thought patterns that are the most important lessons of the various paradigms.


How do I explain blockchain using an analogy?

Use a classroom activity, then present that as the analogy.

An old campfire activity, for those that remember it. A growing story that nobody knows the end of, or even if it will end.

The objective is to create a story, with everyone adding their parts, in turn. Someone starts the story by saying a few lines, and ending mid-sentence, just before some action happens. The next person repeats what the first persons said, and has to finish that sentence with something that makes sense, and then continues the story, using their own idea, since they don't know what the first person was thinking. Like the first person, the second stops mid-sentence in what they're saying. The third person repeats everything the second said (which includes what the first one said), and finishes the sentence left incomplete by the second. Adding more lines to the story, this person also ends mid-sentence. It continues in a similar fashion with each person repeating the whole story from the beginning, adding a couple lines, and ending mid-sentence. At some point the "next" person will not be able to repeat, even in their own words, the story so far, and the chain fails, hence ending. If it happens to be too short, or if not every student has had the opportunity to participate, a new story may be started, and try again. Once everyone has had a chance to participate, in as many rounds as you deem appropriate, you can pick up the chain and finish the sentence, and the story, bringing it to a successful completion.

After the story, or stories, have run their course, you can relate the process to a blockchain. Each piece (except the first) depends upon the preceding piece, and is meaningless without it. If, at any point, someone in the chain doesn't hold up their part of the "contract," by completing the previous sentence, the story is ruined. Still, even without an end, everything up to the last incomplete sentence remains valid, and can be traced back to the original piece.

This is totally non-technical, so it will not be of value in discussing blockchain implementations. It will, however, be memorable, and the students should be able to grasp the concepts behind a blockchain implementation when you do present it.


Recommended IDE for teaching web development to beginners

I find that the best introductory IDE is a lack thereof because, for the most part, the features that an IDE offers (code completion, organization, etc.) are more hurt than help and tend to promote completely unrelated questions, for example, "What is this dropdown under the word I just typed" and other questions about IDE function rather than language functions. Generally IDEs are a distraction to beginners.

I would use a text editor with syntax highlighting such as sublime text, but nothing with too much many extra features. You certainly don't need a full fledged IDE.


What thought process would lead one to invent object-oriented programming?

There are a number of different ideas that are all called OO.  I'm going to focus on the Simula-style OO.  Here's my fiction which I think isn't too far off from reality:

As computers became more powerful, the amount of entities in an model started to grow.  In addition, the different types of entities in these models was also increasing.  These models had the concept of the data for these entities which represented their state called 'structures'.  They also had the concept of behaviors that could be applied to these entities called 'methods'.

Because these entities were heterogeneous, the data in the structures wasn't always the same.  While all the entities might have some data elements such as a position in space, there were other data elements that were specific to some types of entities.  This presented a problem.  Some methods were common to entities such as movement.  But since the data structures had inconsistencies, making sure these common methods worked for all structures was difficult especially when a common method might need to work with properties that didn't exist on all entities.  Additionally, there were methods specific to entities and if a method used with an incompatible entity the results were unpredictable and possibly disastrous.  While careful programming could overcome these challenges, this was tedious error-prone work.  Productivity slowed dramatically as the complexity of the models increased.

What was needed was a way to organize the program in order to eliminate the need to manually keep track of all of these competing concerns.  The first idea was to classify these objects into hierarchies.  Then the methods wouldn't need to understand every different  kind of entity, they would only need to consider the classifications that were relevant to behavior and the structure of the data.

The next idea was to reorganize the methods so that they were aligned to the classes themselves.  This removed the need for lots of special cases inside of the methods for different classes.  The method was already specific to the class.  Within a hierarchy, a class could 'inherit' behavior from a more general class in it's hierarchy or 'override' the behavior to make it more specific to it's needs.  Note: inheritance was later determined to create more problems than it solved beyond very limited use.

These approaches resolved most of the problems with the complexity of these models.  Now the data structures could be modified for a given entity without having to consider the entire design.  New entities i.e. 'classes' could be added with relative ease.  OO would continue to be refined but these features established the core of the approach.


The theory of parsing, translation, and compiling, v.s. Compilers: Principles, Techniques, and Tools?

A lot has been done since 1973. But for an introduction, the earlier books should be fine.
For a more advanced treatment, choose a modern book, of course.
Another book that I like a lot is On Pascal Compilers by Brinch Hansen from 1985. While it is written in Pascal, it is one of the true pieces of CS Literature. It restricts itself to Recursive Descent parsing which is suitable for LL(1) languages. But my view of languages is that the should be LL(1) for readability, though compilers might use LR techniques for efficiency.
So, it depends on what you need. If you are a novice at this and haven't yet built any compilers an older book might actually be superior.


Build logic gates out of dominoes.

Start off by showing this video from Numberphile in whole or in part. In it is a demonstration of how to use dominoes to model logical operations of a computer. It begins with a simulation of an AND gate and writes out its corresponding truth table. This is followed by the same process with XOR, which then allows for the construction of a half adder and in conclusion a full adder. (You may also share this video with students, which contains an elaborate, 10000-domino construction. Per the YouTube description, "The result was a Domino Computer capable of automatically adding numbers. It can take any two four-digit binary numbers and return the five-digit binary sum.")

Then challenge students to build elementary logic gates themselves (you might need a lot of dominoes, but I bet it would be worth it in the long run). You could start by having them come up with designs for AND, OR, NAND, NOT, XOR, etc. on their own. Depending on how this goes, consider using this resource to help guide the design of gates in dominoes.

After students create these gates, consider giving them longer Boolean expressions to model and solve using dominoes. This would also be a clever way of showing how DeMorgan's Law works.

The level of complexity knows almost no bounds with this approach. I could see some students, especially those with a love for computer science, who would thrive doing a hands-on, constructive activity like this.


Take everything with a grain of salt - if they like you they'll tend to be kind in their evaluations. It's also really easy to have anonymous surveys that yield ridiculously positive results (see the "analytics" used by just about any after school, drop in, or summer CS program for examples - using questions like "are you more or less likely to take another CS course").

Whenever I do an anonymous eval I do a few things:

Figure out a way to make it anonymous but to also make sure everyone submits one. Once I wrote a system that they could audit that collected responses and emails then scrambled the answers and sent it to me with a list of who responded separately another time I had the students send the results to a trusted third party.
Ask the kids for the good and the bad. I tell them that even the worst teacher does some good and even the best does some things wrong. I tell them that it's also nice to see some positive and if I only asked and got the negative it would be just to depressing :-)
The bad is important so I know what to change but the good is also important so I know what to keep.
I tell the kids that saying something is bad is ok. Better is why it's bad but even better is a suggestion as to how to change it.
If possible you want to follow up with the kids a semester or year later (if not longer). The perspective of time can really change opinions.


Teaching past the "symbology" of a language

Knowing how to use a tool is different from knowing why/when to use a tool

At a basic level, there is a difference between having certain skills and learning to apply/orchestrate these skills to achieve something more complex.

Forrest Gump was a good runner, but had no knack for understanding American football and needed to be told to run when it was time for him to run. Forrest has a skill (running), but was notoriously incapable of seeing the bigger picture (how to win a football match). This is made painfully clear when Forrest does not stop running when he reaches the endzone, instead running into the stadium.

In order for students to orchestrate the separate skills they have (iteration, calculation, ...) they must first be comfortable with the skills themselves and know them like the back of their hand.

Right now, your students are Forrest Gump. You taught them to run. You have not yet taught them how to decide for themselves why/when/where they should run and why/when/where they shouldn't.

Breaking down the problem is a skill on its own

Additionally, understanding that a complex challenge can be solved using an orchestration of basic skills requires your students to learn how to break down the problem.

  They seemed to "get" these other things, but when it came to looking at code and trying to apply the same logic, they just straight up had no idea what to do.

Based on your description, I infer that you're expecting this to automatically happen, but that's not the case.

  After a long time they were not able to grasp the problem, and I didn't feel comfortable literally just telling them the answer.

As a teacher, if your students do not know the answer, it's counterproductive to withhold the answer from them. It's akin to the old "if you don't know what's wrong then I'm not going to tell you" joke. Clearly, the fact that they are not finding the solution means that they are currently unable to find the solution. Withholding the answer perpetuates the issue and is going to lead to dispirited students who no longer care to look for the answer when they don't know the answer yet.

Teach them to break down the problem without touching any code. Walk them through the problem description, and analyse the issue to see if you can break it down into smaller steps.

In theory, you should never tell them how to solve it. All you should do it break down the problem in smaller and smaller steps until your students realize that they already know how to solve these (sufficiently small) steps. Depending in your students' skill level, you may have to break things down repeatedly.

If they really aren't getting it, then it's time to consider if the students have have enough exposure to the rudimentary skills that you're asking them to orchestrate.

If you break down a complex problem down to e.g. number addition and students still don't respond to it ("I know how to solve that part"), then you're either dealing with disinterested students or students who aren't comfortable with the basics yet.

Functions are essential constructs toward abstraction

  I think part of the issue is that they have yet to cover functions, which would make it a whole lot easier: abstract away the Q1 part of the question, and thus make it easier for them to make that leap.

Yes, this is probably the biggest factor in why they're not thinking in abstracted terms. However, it's not so much that they should already know functions.

When you introduce functions with simple examples that do not yet warrant functions, then students are left wondering what the purpose of a function is other than "to put things elsewhere". Coincidentally, my wife is taking a beginner's development course and this is exactly the stage they are at.

Rather, this is the exact moment for you to introduce functions. Let them solve Q1 on their own, and then refactor Q1 to use a function. Tell them that it's the same solution but in a different form and do not elaborate on the purpose of functions yet; only explain how it works.

Then, when you let them tackle Q2, let them do it by themselves, without any suggested for loop. Wait for them to make the mistake of copy/paste repeating themselves. More importantly, let them make that mistake.

When they've made that mistake, present a (fictional) Q3 in which you ask for them to perform this calculation for one million numbers, and then look as they all sigh and moan about the challenge.
Alternatively, you could phrase Q3 as a change to the calculation logic, which will require them to change all instances of their copy/pasted code. Bot options lead to the same result: unhappy students.

Now, you've created the perfect audience that is incentivized to learn about method abstraction and how to prevent copy/pasting in code. Refer them back to your Q1-with-a-function solution. Work out Q2 using that pre-existing function. Work out Q3 with that same function.

This will convey the importance of abstraction (functions) as opposed to brute force (copy pasting). Work smarter, not harder.

A practical example

  Pythagorean theorem - calculate the hypotenuse of a right angle triangle when given the length of the other sides.

We all know the theorem, where c is the hypotenuse:

c² = a² + b²

or when we solve for c:

c = √(a² + b²)

But how do you write an application that finds the value of c?

As a developer, you immediately start breaking it down into core tasks: addition, squaring (or multiplication), square rooting.

But your students aren't going to think this way. So far, they've been introduced to problems for which there was an explicitly existing tool. Their first few challenges were all one-trick-ponies, i.e. they could be solved by knowing a particular keyword and implementing it.

Logically, they are going to expect that this challenge (just like the ones before) will have a simple one-keyword-answer, which it doesn't. Walk them through it. Tell them there is no short answer to this, they must cobble something together with what they know.

Present the challenge to your students, and ask how they are going to solve this. If no one starts breaking down the problem, ask them to do the math manually:

  What is the length of the hypotenuse when the length of the other sides is 3 and 4?

When they tell you the right answer (5), ask them to show their working out. What you will get is a written-word-pseudo-code answer to the programming challenge. Something along the lines of:

  I squared the 3 and the 4, I added them together, and then I calculated the square root.

As they explain this, write it down:

Square the numbers
Add them together
Take the square root

And now ask them if they know how to solve any of these bullet points individually.

Now, you will get students who see that the complex challenge (Pythagorean theorem) is nothing more than a combination of simpler challenges (multiplication/squaring, addition, square rooting) which they already know the answer to.

To really sell it, you could enforce that the challenge must explicitly break down the problem into these three steps:

Enforce that students make four separate methods:

calculateSquare(x)
add(x,y)
calculateSquareRoot(x)
calculateHypotenuse(a,b) where you've explicitly disallowed any direct calculation and are only allowing them to declare/assign variables and call the other three methods.

If the students still seem to struggle doing this on their own, split the students into groups of three, where each student tackles one of the three "simple" methods.

When they are finished creating their own methods, they can then work together at implementing the main calculateHypotenuse(a,b) method which will rely on the methods they just created.


Is it okay to teach C++ to my 7 year old brother?

I want to tack on to Buffy's answer by focusing on one line from your question: "I want him to learn C++,Java,Html" (emphasis added).

The bigger question should be "What does he want to learn?"

Part of the beautiful challenge that is teaching is getting students to want to learn what we want to teach them. What has your brother shown interest in? What has he told you that he wants to learn? What are his hobbies? How could something about those hobbies be expressed/constructed in a program? Above all else, where do his interests align with what you can teach him?

I'd encourage you to read this thread about starting students in Python, this thread on engagement with computing, this thread about programming languages for teenagers (shout out to Processing!), and our recent HNQ about the age at which students should begin learning programming.

Make it fun and engaging for him. Have him build a game, one that he himself would want to play. The language skills will come with time (and intellectual maturity). What you can do now is two-fold: pique his interest for the future and teach him the essential concepts of computational thinking that underpin programming in any language.


Advances in CS appropriate for CS1 and CS2 made by female computer scientists

I think Rear Admiral Grace Hopper is perhaps the easiest to explain to new students, and to tie in with an important advancement in computer science.

I try to discuss the transition from early programming in machine language to programming in higher level languages. I'll usually show the students some machine code that I will tediously decrypt. Then I show and talk about assembly languages. Then I'll make a point that "there has to be a better way". Then I'll introduce Grace Hopper and her ideas about compiled languages. Showing a little COBOL code with English words and contrasting it to the equivalent machine code is striking.


What physical examples can I use for public key/asymmetric encryption?

Since cryptography is a bit elaborate, this will be too.

Basic encryption is like the following:

Take the "information" you want to transmit and put it into a locked room. A guard sits at the room with an actual key.

Take a piece of paper and rip it in half, the more jagged the rip the better. Give half to the guard and the other half to the person you want to "communicate" with.

To access the information, the person presents his/her half of the paper and the guard matches it with the guard's own half. If they match up the guard will unlock the door and give access to the "information".

Depending on the protocol the guard might re-lock the door or destroy the "information".

Locking the "information" in the room is encryption. The receiver and sender "keys" are the two halves of the piece of paper. Presenting a torn piece of paper to the guard is the attempt to decrypt.

Note that neither half of the "key" is shared with anyone but the sender and receiver of the message, so duplication isn't an issue. This is fine for a one time message or even repeated messages between the same to entities.

But this isn't sufficient for the public-private asymmetry that you seek. In that scheme you want to publish one half of the "key". So modify the scheme as follows.

If someone wants to communicate with you, you control the "keys" and the room. As before, you rip a piece of paper and keep one part, though it shouldn't be a standardized size of paper. The piece torn off, which will be made public, shouldn't  be enough to reveal the overall shape of the paper, perhaps a hole torn out of it or a corner torn off. One piece (the public key) is duplicated and published. Anyone who gets a copy of the public key can communicate with the you, key owner. You keep the other "private piece" without revealing the true overall shape of the original paper.

Anyone with a copy of the (other person's) public key can put something in the key owner's room, guarded by the key owner's guard. Only the key owner can remove things from the room as controlled by the guard.

To communicate with you, the key owner, the person presents their information and a copy of the public key (piece of paper) that you published, to the guard who locks up the information and keeps the key (public key half) that you presented. The room is re-locked. When you, the key owner, wants access to the information you present the private key to the guard who will then unlock the room for you after matching the two pieces of paper and verifying that the overall shape is correct.

Only the key owner can remove things from the room, since the overall shape of the "key" is unknown and "can't" (we hope) be duplicated. Anyone can put things in the room but it will be readable only if the public key held by the guard matches the overall key.

A related key pair can be created by taking a private drawing (that you produce yourself) and using a part of it as the public key. This might be easier to reproduce than the torn paper. However, it must not be easy to deduce the entire drawing from the fragment. Infeasible, if not impossible.


What can be the causes of the difference in student performance?

There is a point, somewhere around where puberty starts but I don't think identical, in which the brain changes its structure. It is much more capable of abstraction after that point than before. Young kids don't do a lot of generalization, for example, adults do. So, perhaps the study just captures part of that.

I don't have it available, but I think there is a lot of brain science around that structural change. A simple search may turn up some of it. We aren't born fully formed either in mind or body.

An implication of that is that how and what you teach toddlers and youngsters isn't the same as what and how you can teach teenagers. Also, every person hits that change at a slightly different age and it isn't instantaneous any more than any other brain change is. For the youngest, make it visual and tactile, even aural.


Trying out the concepts of machine learning during teaching from home

While I don't know any digital equivalent of that particular game or neither I was introduced to RL this way either. But, still there are other games and videos that might help you to teach your students RL. Some of them were actually very useful when I was a beginner.

EVOLUTION (By Keiwan Donyagard)

It's a downloadable Android App based Game where the players create creatures with bones (represented with Black Stick), joints (represented with Red circle/spot) and Muscles (red , connecting the bones). The organisms starts hundreds of thread and learns to walk bit by bit and after each iteration by iteration, they become perfect learners after few minutes.
Link : https://play.google.com/store/apps/details?id=com.keiwando.Evolution&hl=en_US&gl=US

Flappy Bird Video (Uses a bit of Deep Learning Methods, an example of Deep RL)

https://www.youtube.com/watch?v=WSW-5m8lRMs

Google's DeepMind Playing Atari

https://www.youtube.com/watch?v=V1eYniJ0Rnk

There are some experiments where AI did outsmart their creators and performed unexpectedly well too.
Here are some videos:

https://www.youtube.com/watch?v=GdTBqBnqhaQ (By Two Minute Papers)

OpenAI Hide and Seek which actually breaks the game (https://www.youtube.com/watch?v=kopoLzvh5jY)

Motivation: Reinforcement Learning and Deep Reinforcement Learning is an important field of study in AI because it is a general way to Build an AGI and ASI. (AGIs called Artificial General Intelligence and ASIs are called Artificial Super Intelligence.) The core development and framework of such systems have already been put in form of AIXI and AIXI-tl and they would definitely change the way whole humanity looks at it. Some of the notable researchers claim that Artificial Super Intelligence would be the last ever the biggest invention of Humanity and the most terrifying thing is that we still don't have a proper framework and ethical standards set for use of such super intelligent systems (Superintelligence: Paths, Dangers, Strategies, Nick Bostrom.). While some theoretical paper do have measures of frameworks on dangers of such systems (https://arxiv.org/abs/1607.00913), but we still are far from specific idea about the matter. This is primarily because of lack of researchers here in this particular field. We hope more and more people join and contribute to the emergence, control and setup of ethical standards of such super intelligent Systems.


Reference request for resource with difficult programming exercises

If he wants to have a blast biting into some very fun and challenging problems, Project Euler is fantastic, and entirely language neutral.
He may find that certain problems are out of his grasp until he learns a bit more programming, but there will be many that will be possible even with what he has.  (Arrays, structs, and pointers should make all of the problems accessible, even if some of them are still possibly too hard as problems before he has a good understanding of linked lists and trees.)


Turtle examples for loops and variables, or even something else

What your system is missing, actually, seems to be a feedback mechanism in which the turtle can "sense" something about the world it is in. If it, for example, could sense edge walls, then it could use that sense for conditional constructs. In Karel the Robot and its successors (Karel J Robot, Monty Karel, ...) there are a number of things that a robot can sense such as walls and "beepers".

while (karel.frontIsClear())...

If you can have multiple turtles then one turtle sensing something about another is another possibility for feedback.

But, until you get something like that (sensing about the world) you can probably only write conditional and looping constructs based on stored information in the program itself, such as counters.


Explaining the Value of Knowledge of Digital Logic

Your best bet of how to answer why students should care is to stop and ask yourself what good reasons there are to care about it (or any topic). Do that before reading on?

OK, so my answer is: because science. The word means knowledge. If you want to know something instead of just have opinions (possibly wrong) or worse, then you will want to be finding out. But why bother to know anything, is really the question. Caring is your issue. Caring means that one can influence things, and not caring means that one will be pushed around helplessly by circumstances.

Is it effective to care, is the obvious question? Can we actually learn enough to have any effect? When things seem perplexing and obscenely complicated, then it appears hopeless. Science brings hope because it is able to render the complex simple enough to manage. When I found out that all matter is composed of just 3 elementary particles, and that there are basically only 2 forces that affect us, only one of which we have any control over, it was revolutionary. If more people knew these things, they might wish to learn more. When you ponder the 88 keys on a piano, able to make basically all (western) music, or the 92 naturally occurring elements making basically all things, it is astonishing. The organization of atoms (predicted 2500 years ago) in to the stunning wonder of the Periodic Table is a great story!

All computers are made of transistors, and built up in to a few simple circuits replicated millions of times, like the cells of the body or brain. If that is not inspiring and provoking of interest, I would release the students from school, as they are unreachable: they don't care to have an influence on their own future.


Is there any purpose to having students do fiddly cache homework assignments?

It sounds like you've already answered your question, but I'll throw in my two cents:

It depends.

Does every software engineer need to simulate the differences between direct-mapped, 2-way set associative caches, and 4-way set associative caches? Absolutely not. I've been a programmer for about 10 years now, and I think I have a pretty successful career, and I have no idea what those things even mean.

However, should some students, who are particularly interested in these kinds of things, take a deeper dive? Absolutely yes.

So, it comes down to a question of: is this course designed for students to get a high-level overview of computer architecture, or is this a more specialized course designed for students to get more information about the low-level details? In other words, is this a breadth or depth course?

You might want to give students a high-level overview, and then point particularly interested students at further reading, more advanced courses, or specialized fields they might study in grad school.


How to teach students to work with multiple layers of abstraction?

Link to real life

“Who has came to school by bicycle?”
“OK so we need to know how to make a bicycle”
“What time did you get up? It must have taken a long time to build the bicycle?”

Take it to the limit; be absurd. So the pupils tell you “You don't need to know all this to get to school.” Agree with them.

“Any one here ever fix a bicycle?” — “yes”
“So you have to fix it every time you ride?” — “no”
“But you do have to think about how it work, the inner tubes, the oil, the gears, every time you ride it, right?” — “no”
“Why not?”

Link to past experience, in subject

“Now what about a print statement, we need to know how that work to be able to use it, right?” — “no”

“So over the next few days/week we are going to be looking at a more complex system than before. We can not hold it in your head all at the same time. So I am going to ask you to do what the professionals do: don't try to remember/understand it all at the same time. We only need to understand ‘how’ for the bit we are working on. It is enough to understand ‘what’ for the bits that this uses”

This is only the 1st draft of an idea, and not tried with a class.


Why does AP Computer Science A use Java?

Particularly since they have recently removed interfaces and abstract classes, I would say that there are no particularly important philosophical reasons that they are using Java.  At this point, it was a historical decision.
The exam began in Pascal, and when they looked for a way to move towards Object Orientation, they switched (in 1996) to C++.  This was controversial at the time, as Java was very modern and was thought by many to be a conceptually better language, particularly for students.
They switched from C++ to Java in the 2003-2004 school year largely for two reasons:

Java was considered to be a better object-oriented language, particularly with regards to inheritance, and the compiler does a much better job at checking to make sure that beginners aren't doing silly things that they definitely shouldn't be doing.
College programs around the country were taking up Java, so it better reflected the reality of the introductory courses that students would be getting credit for.

You can read the justification for the switch to Java courtesy of the ever-magical wayback machine.
Given the recent changes to the AP Test, it does not appear that there is any particular good pedagogical reason to stick with Java at this point.  In fact, the latest iteration of the test basically ignores the most important features of OO, instead emphasizing a great number of imperative concepts.  However, the testing language is unlikely to change any time soon, as Java is still the dominant language at universities for teaching introductory Computer Science, and these are the institutions that must agree to provide credit if the AP exam is to continue to provide value.


Any website/textbook with problems+solutions in algorithms?

Based on clarification in comments, Algorithms 4th ed. by Sedgewick and Wayne seems to meet your criteria. The book itself doesn't seem to have an official PDF version (I haven't searched for unofficial ones of dubious provenance), but the code is available both at the linked page and on Github, and includes solutions to selected exercises.


What to do when pupil destroy lab equipment?

How should I prevent damage to equipment?

Number each piece of equipment, assign each student (or each group of students) a number, and instruct students (or groups of students) to use only their numbered piece of equipment. Explain that each student (or group of students) is responsible for their piece of numbered equipment and they will face punishment if equipment is damaged.


Finishing College with Employable Skills

The kinds of things suggested in your question and many similar things won't help them. Learning some other "tool" or "language" or "technique" at a beginners level will still leave them with just a bunch of tools they don't really know how to use.

Instead give them a project - preferably a hard project - in which they can use what they have learned, but which also likely forces them to learn at least one new thing. Moreover, if their goal is employment, make it a team project so that they get the experience of working closely with others.

If you can make it a real project, not just an academic exercise, all the better.

Also, make them use some proven methodology, not just hack together a solution. My suggestion would be Extreme Programming, since it is completely defined and has good personal practices within it. It would give them good guidance for a first such project. Scrum, being a bit more general might leave them without the guidance they need, hour to hour.


What should a teacher do with information about plagiarism before the final submission

I assume that somewhere you discuss plagiarism and the social good of respecting the IP of others. If not, plagiarism detection is just a "gotcha" that doesn't really benefit the students or your relationship with them.

The following suggestion is offered tentatively, and might require tuning. It might also require research on the effect.

If the tool is good enough to tell you in real time that something bad is occurring, it is also good enough to tell the student at that moment. So you could build that feature into the tool.

However, there is, then, the danger that a student could game the system, modifying things just enough that the warning goes away. So it might be necessary for the warning given the student to also warn that not every "violation" will be reported to the student but will be reported to the instructor.

Caveat: This was "seat of the pants - in the moment" design. I can't claim it is best practice. It is, however, based on the principle that fairness and communication are positive attributes in education. Help the student grow in many dimensions, not just the technical.

In your discussions with students about plagiarism, be sure to include the concept of self plagiarism which many don't recognize as a problem since it doesn't violate IP rules. But does make derived research and attribution more difficult.

And, like any lesson, it needs to be reinforced. Very little that you do just once will actually be learned. Active learninig is reinforcing as lecture is not. Class discussions about plagiarism and its tradeoffs (short term gain - long term  pain) might be useful.


How to advise change in a curriculum as a new teacher

You might not like this answer, but I would be cautious. There could be many reasons why their curriculum is laid out in the way that is.
They might be dealing with students of more varied abilities at the start than you think. They might have later coursework that depends upon mastery of the current coursework. They might only have it in place for historical reasons.  This current curriculum may well be in place because of certain problems with another approach that they took in the past.  Or, they may feel that the mission of their program is somewhat different than you think it is.  (This last is almost a given, actually.)
Therefore, the first order of business is, at least for a while, to do more listening than speaking.
Now, as for what you can do: at least in the US, many institutions that teach to the ages you mention have periodic curriculum reviews. Sometimes these committees can even involve outside representatives from industry.  You could express your interest in serving on such a committee if your institution engages in this practice.
Beyond that, you can certainly share your observations.  Most people (though certainly not all) would be willing to engage in such a discussion with someone who is not pushy or overly-opinionated.  And, in such a conversation, you may well find that there is openness to change!  What I would stress, however, is that you should also remain open to the idea that things are in place for reasons that you simply don't know, and they might not ultimately choose to change the structure.


Any good beginner tutorials for learning LLVM

As stated in Buffy's answer, you'll want to first be familiar with the other steps of compilation, because code generation is typically the last step in the compiler pipeline. If you haven't already, I'd suggest looking in to lexing and parsing as well. Optimization is nice as a bonus, but llvm does a good deal of optimization on its IR by itself.
Once you're familiar with the general outline of how a compiler works, you can start building one yourself. There is a language that is designed to be easy to build a llvm compiler for, called Kaleidoscope, and I'd recommend looking up a tutorial for building a Kaleidoscope compiler in whatever language you choose. llvm has bindings to many different languages ranging from haskell to C, although you will likely have the best experience learning in C++ since that's how llvm's API is implemented.


Although it should probably be only one strategy among many, you might teach it through practical examples.  In this short program that uses flask_user (and
which students can install in just a few minutes) the decorator ensures that only authenticated users can use the route:
https://flask-user.readthedocs.io/en/latest/quickstart_app.html