Books that summarize pedagogical research within our field

Here are books in print that address a range of issues within teaching computer science, synthesize pedagogical questions and research-based answers distilled from research, and include extensive references to the literature.

Frieze and Quesenberry. (2017). Kicking butt in computer science: Women in computing at Carnegie Mellon University.
Summarizing the efforts at CMU to diversify CS undergraduate enrollment, the book is intended to help CS teachers duplicate CMU's success by focusing on benefits of diversity rather than gender differences.

Guzdial. (2016). Learner-centered design of computing education.
Intended as a review of literature on teaching CS to people who are not aiming to be CS professionals, the seven chapters define the problem, summarize the research, and ask many questions yet to be answered in the literature.

Hazzan, Lapidot, and Ragonis. (2014) Guide to teaching computer science, 2nd edition.
Intended as textbook for a CS teaching methods course, the Guide helps a CS Methods instructor model active learning techniques by structuring the text around 110 activities in which the CS teachers are the participants.

Kafai and Burke. (2014) Connected code: Why children need to learn programming.
Describing educational programs that have worked with children, and the programs' results, this book aims to help teachers and influencers lead cultural changes toward computational participation and new ways of thinking and learning.

Krauss and Prottsman. (2017). Computational thinking and coding for every student.
Aiming to help the K-12 teacher with no CS experience, this book offers lesson plans, resources, and pedagogical advice mirroring the consensus of the CS community. Self-described as a "getting-started guide," it is not a review of literature, the the References list about 50 sources, some of which are research articles.


Using autograding (Github Classroom) - pitfalls and best practices?

In the auto grader I use, the following process is followed:

The students files are copied into a pristine work area
The "provided" file(s) are removed from the work area
If I intend to use MOSS, the remaining files are copied for later use
The "provided" file(s) are copied into the work directory
The result is built (if necessary)
Tests are executed and graded

Note that the "provided" file(s) copied in at step 4 may be a superset of the file(s) provided to the student in the assignment and typically contain other/additional test cases.
If the build fails because a student has modified a "provided" file, the students gets no points. If Java assignments, the provided file is often a interface, sometimes an abstract class. In C/C++ assignments, the provided file is often a header file.
If some test cases are provided and reused verbatim in the final run, those test cases only account for 60% of the final grade. Thus, the student can not receive a passing grade by just making those test cases pass.


The analogy is far from perfect, but Snap! is to Scratch as Mycroft is to Sherlock.

For me, the big advantage for Snap! is its provision of custom functions rather than just the custom blocks that Scratch 2 offers - Snap! functions return values that can be passed to other functions and so on, making it much easier to implement mathematical ideas and to build up programs by defining rules and relationships rather than sequences of steps.

In Snap! functions are 'first class citizens', thus functions can be passed to other functions as parameters, or be stored in lists, or (pretty much) whatever, and so Snap! can be used as an introduction to functional programming.

In short, Snap! makes it easier to address much more theoretical CS than is convenient in Scratch, without introducing the need for text based programming.

On the other hand... Snap! doesn't have the same rich range of support materials or vibrant support and sharing community that has made Scratch such a success.


Is there some meaningful percentage of students who can't learn to program?

There are a number of reasons why students don't learn, but few non medical ones why they can't. Leaving aside the medical reasons, such as hormonal imbalance or other disorders, I think that students who don't learn either have little desire to learn or have had poor teaching in the past. Even students with some learning disorders can learn given desire and patient teaching, but it can take a lot of work and understanding of the student to enable it. Once common problem with students is extreme introversion. That can make it difficult for the student to seek help and ask questions. It is good if you can find ways to help students deal with that in a positive way. See this question for more on the idea here.
Desire
Some students don't learn what you are teaching because they have little desire to learn it and no incentive to put in the work required. They may be in your course for the wrong reasons and would rather be anywhere else if it were only possible. They put in the time, but nothing else. There is probably not a lot you can do for them as that desire needs to be internal. Some students develop desire after a period of indifference, but I don't think this is common. I've had undergraduates in CS who were only in the major because their family (father) would only support them if they stayed. Such students can be counseled to study something more interesting to them if possible, even if it requires doing that in addition to computing. Better, though, if you can counsel the parents to better support their child.
Some classes are required, of course, and so interest for some will be higher and for some it will be lower. If you know something of the goals of the student you might be able to connect the current class to those goals, increasing interest and desire.
Poor Teaching
Many students do poorly in CS (as in mathematics) due to poor or indifferent teaching; especially the attitude among some teachers that it is OK to leave some students behind. Not every student takes the same amount of effort to teach and every student learns differently. My usual mantra in this situation is that "Your students are not like you." They learn differently than you did. Your presence in the classroom as a teach is proof enough that you are a special case.
Some especially bright kids do poorly in school because they are simply bored and nothing is exciting enough to them to put in the effort. Some students find other subjects especially easy and don't really know what it is like to have to work to learn. Some students don't learn because no one ever taught them how to learn. Some think that hearing something once means they have learned it and are surprised later when they can't recall something, wondering why you never taught it to them. Some students have a fundamental misconception about some small thing that has snowballed into a big block. Some students have never had a positive learning experience (maybe generally and maybe just in some topic) and simply hate everything about the process. Some teacher say incredibly stupid things to students and even some institutions have incredibly stupid ways to deal with students, actively damaging them.
I have examples in my learning and teaching background of each of these things.
As a student I was a thought not very bright when I was a kid and was nearly "held back" to repeat an early grade. However, I was just deadly bored with school. No one ever bothered to tell me why I was there or why or how I should try to succeed. Being bored I was a bit of a troublemaker, leading to lack of support from teachers. Later on, I was given an IQ test and the results were reported back to me as "You probably have the skill to succeed in a Junior College, but probably would only be frustrated by a full undergraduate program." I later earned a PhD, of course, so the assessment was a bit "off". The first course in which I actually learned anything was in Plane Geometry in HS. I got entranced by the problems there. Prior to that, mathematics was, perhaps, my worst subject. The doctorate is in Mathematics, of course.
In teaching, I once had a student with two problems. First he was dying of a chronic condition, but also he had been given misinformation about the precedence of operators by some early teacher that was reinforced when he used a too-simple pocket calculator. He couldn't seem to get it right in elementary programming and learned to hate it. He thought he was stupid that he didn't get it and he thought that all of his teachers also thought he was stupid. I think I managed to convince him otherwise before he died but we banged heads a bit before the reason for his difficulties became clear to me. It took a bit longer to convince him that I wasn't actively trying to deceive him.
I once had a class of students who were almost all doing very poorly. Since my teaching style then was to face them, rather than lecture with my back to them, the diagnosis was pretty simple. No one had ever taught them how to learn in a classroom. They sat passively and listened and watched, taking no action themselves. I asked one why he didn't take notes and he pointed to his head and said "It's all here." Well, I had evidence otherwise, so had to interrupt the syllabus to actually teach them how to learn and to force them to actually do it. I've discussed part of the method in another answer on this site.
Solutions
If you want to teach every student, however, you need to know every student. If someone is doing poorly, you need to try to understand why that is and to tailor a solution to their needs. To do that you need to be dealing with a reasonable number of students, of course, so if you are a professor of 800 students, the individual care must be given by your army of helpers. But even wit 20 or so students you need help. This is why pairing and group work is so important and why you can't always let students choose their own groups. You need to get feedback from the members of the groups (peer evaluation) and you need to find ways to act on what you learn.
The solution to teaching every student is not to individually tutor every student, but to find ways that every student can learn what they need to learn on their own terms. Not every student wants to earn first marks. They want to learn "just enough." They are satisficing rather than optimizing. You can make that work for them too, so that "not earning first marks" doesn't mean "failing."
Success Story
I once had two students (compiler course) who were repeating the course after failing it. The classmates of these two were generally among the best I've ever had in one group. But these two had, seemingly, never had a positive experience in CS. They seemed to be dull, requiring repeated explanations of the simplest ideas over and over. Fortunately the course was taught in an incremental way in which the students could accumulate points toward success rather than by demonstrating it on exams: a project course. I convinced them to come to my office hours and there was never a time thereafter that they weren't there. Fortunately the other students didn't require such high maintenance. I also had simple ways for students to ask questions when they were working on their own and so these two could get small helps whenever they needed it. It turned out that these two wound up (a) explaining things correctly to me by the end of the course (b) earning the highest grades that term, and (c) angering the other students who thought I'd put these two in the class to make themselves look bad. My last contact with them was to remind them of what they had done and that they could repeat that elsewhere if they were willing to put in the same amount of work. I think that teamwork also helped here and they supported one another throughout. Note that I didn't need to put additional time into the course for this to happen. The office hours were required and the mailing list for questions was a common feature of all my courses. Another question here seeks ways to make this out-of-class communication easy, though I think it needs better answers at this time.


Order to teach looping constructs in a non ideal language

I prefer to teach while loops as part of my unit on if/else statements since the syntax and thought process are virtually identical.

I then introduce for loops when teaching lists (in Python) or arrays (in Java).  With for loops, language impacts which style you likely use first.  With Python, I use the for item in list structure first.  In Java, I use the C style (for i=0; i<...) loop first.

I don't try to introduce all styles of looping at once as I prefer to develop the concepts across units.


Is there any pedagogically motivated reason to teach quadratic probing?

Yes, you should at least introduce the idea to your students.

That said, it is also a truism of education that you need not explain every concept at the same level of detail. In this particular case the first couple of paragraphs of the Wikipedia article on the subject is probably enough. A couple of minutes could be well-spent.

Students need to know that there are a range of solutions to any given problem and that those possible solutions have trade-offs. This is an excellent opportunity to stress that. Linear probing creates bottlenecks in some situations (poor hash functions for example). That can be a problem. Quadratic probing, while more complex, does a bit better. It might be easier to implement than trying to guarantee better hashes over which the programmer may have less control. Even if that particular solution is never used by your students they will encounter such choices in the future. Help them get ready for it.

By pure serendipity, Eugene Wallingford's blog post just yesterday discusses a related topic. Blog: Jan22-2018, "Same Footage, Different Film"


Should I start out as a “junior developer”?

Feature building is a junior developer job. It's also a senior developer job. Feature building is part of any developers job.

QA is testing of those features. If you become a QA specialist you won't be developing features at all. You also won't be using TDD. TDD comes before the code under test. Not after.

QA testers come in two types: manual testers and automation testers.  Automation testers are often feature developers as well.

If someones convinced you that newbies must start in QA they've feeding you crap and I wouldn't want to work there.

Some shops don't even have QA roles because the developers test the crap out of their own stuff and then hand it to a peer to test it again with fresh eyes. Some do all that and then still hand it to a QA group who spend all day doing nothing but gleefully breaking software.

QA is a speciality in and of itself. It's a mindset as much as it's ever a job title.

But QA is not where newbies need to start and it's not a dumping ground for sub par developers. QA is where you put your best or it's not QA.

At the end of the day, a junior developer is just someone who might learn a thing or two from a senior developer.

As for the career advice find people doing these jobs and ask them what their day is like. That will tell you what you're likely to learn in those roles.


How can I effectively manage peer evaluation among my students?

Something like the following has worked for me over several years. In any group assignment, each member of the group also submits a peer review sheet. For a group of two (e.g. pair programming) I ask each participant to detail the most important contribution of their partner AND their own most important contribution. I don't ask who worked harder or ask them to make an evaluation. I ask them for the contributions.

In a group of about five, I will ask each member to name the (say) three most important members of their group and to mention the key contribution of each. I tell them that they can include themself in the list of three. I also ask, separately for their own most important contribution.

I let them know at the beginning of the course that this will happen and its parameters, so it isn't a surprise.

Students see that they are supposed to contribute to a group and are not asked to speak ill of anyone. Keep the questions entirely positive. But you also learn a lot from what is not said and who is not included in the contributor list.

If the project happens outside your view, you also learn things about individuals that you can not otherwise know. I've had students I thought were slacking who were praised by teammates for making the team work properly.

These peer evaluations are not optional.

This same idea was also discussed here: https://cseducators.stackexchange.com/a/2578/1293
It is also, essentially identical to part of this: https://cseducators.stackexchange.com/a/3402/1293

Let me note that there may be cultural limitations here. In some cultures it may be odd to name oneself as a top contributor. In others it might be very natural. You can modify the scheme, of course, either requiring or forbidding naming oneself as one of the top people. Use your judgement here.

Note also that this solution is based on the Peer Feedback pattern in Pedagogical Patterns: Advice for Educators


Are there any recommended tools for teaching syntax and grammar of programming languages?

I agree with @Buffy's comment. If your goal is to teach the concepts of lexical rules and context-free grammar, I would focus on that rather than on using tools to build parsers from those grammar rules.

I've found that if you have first taught regular expressions and finite automata, that you can teach these concepts quite nicely within that scope using toy languages that you invent and derive in class.

For example, you could create a language defined as:

L = {w | w is a pair of positive integers which are added or subtracted}

For example, these would all be valid strings in such a language: { "3 + 2", "5 - 1", "0 + 2", ... }

Then you could define your grammar by deciding what set of variables (V), set of terminals (Σ), set of substitution rules (R), and start variable (s) you need to describe that language.

G = (V, Σ, R, s)

This can all be done in a class or group discussion on paper (or whiteboard) without any tools. I find it easiest for students to come up with Σ first, then use that to deduce the members of V, then R, then s.

A guided discussion could go something like:

Σ

"Let's decide what kinds of things we could see in our set of terminals, what symbols (some people refer to these as tokens, though parsers think of these differently) would we see in this language?"

...

"According to our definition of L, this could be any positive integer, a plus, or a minus. So the set Σ could be defined as:"

{ℤ+, +, -}

V

"Now, how could we group these things together?"

...

"The things we're seeing are either positive-integer things, or Operator things, a valid Expression in our language always appears in this form:

Expression -> positive-integer Operator positive-integer

Since the set of things that can be a positive-integer is already represented by ℤ+ in our set of terminals (Σ), that leaves only two types of things in our set of variables:

{ Expression, Operator }

R

"Now, let's come up with the substation rules for this language. We already said that:

Expression -> positive-integer Operator positive-integer

"Since positive-integer is a terminal, we just need a set of rules for Operator. What kinds of things can an Operator be?"

...

Operator -> +
Operator -> -

"So that means the complete set of rules is:"

Expression -> positive-integer Operator positive-integer
Operator -> +
Operator -> -

s

"Now, we just need to decide what the starting variable should be. Which element of V should be our top-level item?"
...
"Expression"

Next Steps

From this point, you can then walk through derivations for the grammar. Depending on where you want to go next, you could then illustrate the grammar as a finite automata or as a parse tree, or express it in Backus-Naur form.

If you still want to discuss parsers, I've also given students assignments where I provide them with a simple grammar definition like the above, and ask them to implement a DFA that can determine if a provided string is a valid expression in the language. This is a lot easier if you've already discussed regular expressions.


How to document the developed work using an agile methodology?

In SCRUM, during the end of each sprint, there is a Sprint Retrospective and Spring Review. Important artifacts from the two should be extracted into this report, as it reflects the "developed work".

I'm not sure the scope of what you require from your students for documenting the work, is it for the whole internship, or just one cycle? In any case, because Agile is done incrementally, they can just write one template per sprint they've completed.

Sprint Number
Sprint velocity
List of stories completed
Did it meet success criteria (definition of done and agile manifesto)
Notes from sprint review
Notes from sprint retrospective
Implementation strategies (if it is required by you)
...


tl;dr Make the mapping between the software and the hardware explicit at the start and then show the code, rather than the other way round. Draw pictures. Give them a mental overall image, not just detail. Detail with no context is hard to follow, and hard to learn.

In many ways this question is like another here in that you have a complex system that must be taught all at once. See the answers to that one, including mine.

A useful strategy for this would be to turn it around a bit and start out by saying that the code they are about to see is a model of the physical device. The parts of the model match the parts of the device. The robot has two arms and so its model has two "Arm objects". Objects in the model need a description and the description (in Java) is provided by a class: RobotArm.

The physical robot's parts have functionality of various kinds and these are modeled in the RobotArm class with methods: move, etc. Once we have the class (at least in skeleton form) we can instantiate it: new RobotArm().

The Robot class itself is built by composition (arm fields: Robot.leftArm...

So what you do is make a mapping between the code and the physical thing and point out that (as I assume is true of the code) the mapping is pretty direct. This is actually pretty faithful to the idea of OOP, in fact. Modeling is a good first metaphor for OO programming.

At this point you can show them some code, but I'd show it heavily ellipsed, with only the detail needed shown in full. In other words, only show some of the methods and maybe only parts of some methods.

So the code you show above in your Question doesn't come first, but only now after they have seen the map, even if the map is incomplete. The class is an abstract description of the physical thing and the code completes the description. When you show methods, don't make them naked (as if this were just C coding), but show them as part of their class.

I've assumed that the robot itself is an actual object in your framework. It is possible that it isn't, if there is only one. The robot "object" may be implicit. Or possibly your code (above) is really part of a method of the Robot class so you wrote leftArm... rather than this.leftArm...

Note that if the "Robot" were not a physical device, but a screen simulation instead, the same ideas as above work well.

Another way to put all of this is that you do the integration step for them and present that, rather than depending on each student to integrate the detail into a consistent whole and all in the same way.

So, you introduce three big ideas (Class, object, method) and show how they relate to each other and to the physical thing. There are a few smaller ideas also (instantiate, part-whole composition), of course that you incorporate into your lecture. It should only take 15-20 minutes to do this at a high level.


What would be a good first choice to teach game programming to beginners?

For those interested in 3D (though, it can be used in 2D) game making with an engine, I would suggest teaching Unity. It's an engine and a platform for creating games.

Unity can be used with C# and Javascript, which means that those who choose to use it will also have some experience with some very popular high-level programming languages.

Additionally, Unity is, in part, a graphical engine. This means that the game is made in a graphical way, and the student can decide how much coding would be involved (Unity has an asset store, in which some scripts can be used. Some are free and others are not). This allows students to be comfortable with the game they are making, and they decide how much programming they do. This
 degree of freedom is often very beneficial for students.

A portion of making a game in unity involves designing, and artistic work. This can be a very convenient environment for the students who are into interactive design.

Overall, Unity fits the bill by being flexible and answering each students needs and areas of interests and expertise. So I think that it is a very good choice to start with.

From my experience, it's quite enjoyable to make games with it just for the sake of playing around with the software. This isn't too relevant to the question, but students who enjoy working on projects are more likely to make great projects.


relationship between ACM curriculum guidelines from 2013 and computing curricula 2020

Actually, since it is a draft report, you have an opportunity to influence the final version. Contact one or both of the Co-chairs. They can also give you some more information on their thinking. I'm not personally involved in this, but know several of the participants. They are likely to be helpful.


Benefits of explaining low-level architecture in a programming class

Students should understand the importance of the memory hierarchy, including how caches use temporal and spatial locality to tremendously speed up memory accesses. Otherwise, a student would not know there is any difference between:

for (int i = 0; i < 1000000; i++) {
    for (int j = 0; j < 1000000; j++) {
        arr[i] += j;
    }
}

and the logically equivalent reordered code:

for (int j = 0; j < 1000000; j++) {
    for (int i = 0; i < 1000000; i++) {
        arr[i] += j;
    }
}

The difference is that, in the first piece of code, each array element is retrieved from memory once and placed in either a register or the cache, from which it is operated on a million times. Ignoring spatial locality (which would apply equally to both versions), the total number of reads from memory would be 1,000,000, and the total number of writes would be 1,000,000.

With the second version of code, each array element is fetched from memory once for each value of j. The total number of reads from memory would be 1,000,000 x 1,000,000 (10^12); the total number of writes would be the same.

Per Latency Numbers Every Programmer Should Know, a main memory access takes about 100 ns; an L1-cache reference takes .5 ns. Accessing a register adds no time to instruction execution.

Ignoring the times for the writes (which may not be in the critical path) and spatial locality (which applies the same to both versions) and assuming that a[i] is stored in a register, the data memory access time for the first is 10^6 * 100 ns = .1 s. The data memory access time for the second is 10^12 * 100 ns = 10^5 s.


Easy on-boarding for grad students to lead outreach?

The situation you seem to have is that you have students (your volunteers) suddenly thrust into the role of teachers without any preparation other than what they can emulate from their own teachers. Teaching is a skill that can be learned but only through reflection and practice and that takes a lot of time. And you don't have that time now. I would guess that most of your volunteers are (a) used to be lectured to, and (b) have a learning style consistent with that.

However, as I've said in response to other questions here, the students aren't at all like their teachers. Every student is different and your learning style is not the same as that of your students. Good teachers learn this, mostly through experience, and learn to accommodate students with a variety of learning styles.

My advice, then, would be to try to have the volunteers give up a "teaching role" so that they don't get trapped in the emulation game. Instead, have them work with small groups of students in a responsive way, answering questions only rather than giving out information. Have the volunteers act more like mentors than teachers. In other words, divide the students into groups with one or two volunteers for each group. Each volunteer is just a resource for the group, not its leader.

One thing they can do, of course, is give something of their own backgrounds and what led them to tech. They can talk about what they find hard in learning and how they work to overcome that. They can talk honestly about the obstacles they faced (and that women in general face) and how those can be at least partially overcome. Counterbalancing the obstacles, the volunteers can also talk about what they love most about geekiness and what cool things they have built or helped build.

Mentoring relationships can be fostered and it would be good if you can find some way for those to continue after your volunteer gigs end.

But if they think of themselves as teachers they will just emulate the teaching they have been exposed to and that may not lead to the best outcomes.

If your volunteers know something about Agile Software Development process, especially Extreme Programming, you can do something like the following. Have each volunteer act as a combination Customer and Coach to a team of students. These are two quite different roles (two "hats"). As a customer, the volunteer breaks down a project into stories and feeds them to the team over a set of iterations. The Customer also handles acceptance of the work between iterations. As a Coach, the volunteer keeps the students on track, observes the periodic (daily) meetings and makes sure tests are written. If every team works on the same project, then you might be able to have one (or maybe two) volunteers act as Customer for all the teams, and the others serve just as coach (and mentor, of course), one for each team. The volunteers, by the way, will learn something if they also compare notes periodically and have their own debriefing sessions.


Blockchain cipher suitable for preschoolers

If all you want is a simple hash function you could do something like this.
First take your original message and apply something like ROT 13 to it. This gives a reversible cipher, of course. Then give each letter a number, say N = 1, O = 2, etc, wrapping after Z. Next, just add up all of those values. It is no longer a reversible cipher, but a hash. To get it to be fixed length, simply pad or truncate it to, say, five digits.

Pretty bad cryptography, of course, but simple enough if the students can count and add.

The use in a blockchain is up to you.

This hash has the features described here: https://en.wikipedia.org/wiki/Cryptographic_hash_function, but they aren't very strong, of course.

Fixed Length
Deterministic
Easy to Compute
Infeasible to Reverse
Change in the Message changes the Hash (not a lot, though)
Infeasible to Generate a false message with the same Hash (maybe).

Call it the puppy-1 hash function if you like.

And of course ROT-13, like the Caesar Cipher, has some historical interest.

In the first part, ignore case, punctuation, spaces, etc., which isn't sufficient in general, but should be for this use.


How can I improve other programming languages while having command on one language

Looking at Buffy's answer it's clear to me that I've understood the question quite differently, so I will set some context before I get to the point.

  However you are good in only one language.

I think that this is too strong: it's possible to be good in several languages if you use them all frequently. However, I do know the feeling. The main language used in my undergrad course was Java, and that was virtually the only language I used in the 7.5 years after graduating. But for the past 9 years the primary language in most of the projects I've worked on has been C#. Now when I revisit Java I keep typing string and getting compile-time errors until I correct it to String.

On the other hand, the key word there is primary. One project was written in C# but used a code generation tool whose templates were in some weird Visual BASIC variant for which I never found documentation, and in addition had large and complex SQL stored procedures. Real world projects often contain an unholy mess of different languages, chosen for good or bad reasons, and the ability to handle that is a useful skill to develop.

  As I know all languages are related to each other at some extent, but it's difficult for me to remember syntax for all languages

Supplement your memory. Write revision notes as though you were preparing for an exam on the differences between the language: one side of paper (A4 or letter) where you list the most important mappings from your strongest language to the target language. E.g. if your strongest language is Java then your notes for C# might include:

import is using
Method names begin with upper case
Map is IDictionary and HashMap is Dictionary
Generic types are reified, so if you have a static field Foo in a class Bar<T> then Bar<string>.Foo is a different field to Bar<int>.Foo.

Also, use IDEs where possible. It's much quicker to fix compile-time errors as soon as you type them than to wait until you've finished a unit and can attempt to compile. Auto-completion for syntax is also getting quite advanced now.


Should CS students be doing their tests on paper?

100% yes. In beginning courses, it's practically a cognitive requirement.  Let me see if I can break down for you why it is so important.  It comes down to what we can know that the student knows.

Let's say we have a student who is a rather mediocre coder and who, to be honest, really has no idea what is going on in class. We're going to give him a problem in Java, which is to go through an array of ints, add all of the numbers in said array, and return the result.  We're also going to let him use an IDE to build it, so that he can find syntax errors and spot-check himself for silly errors by running the code.  The first thing he writes is this:

for(z=array[0], z < array, z+1){
    z=array[0];
}

So, how much can we say that he actually knows?  I can forgive that he used commas in his for loop.  I might even, depending on his background, forgive that he forgot to declare z.  But what can be said about the fact that he set z to array[0] instead of to 0?  Or that he is comparing z to array instead of array.length(), or that he is never actually changing z in his z+1 statement? These are mistakes of comprehension, not syntax.  What, also, can I say about the fact that he keeps setting z to array[0] over and over again?

The fact is that, if he writes this into an IDE, a few things will happen.  A bunch of code will light up red.  A red line will remind him that he forgot to make a return.  Another red line will tell him that z < array is not possible, because they are of different types.  So, he will start typing things until the red lines go away.  Does he necessarily understand the things he is changing, or has he been trained, Pavlovian-like, to change code that has been underlined in red?

As he makes some red lines disappear, new red lines pop up.  He then turns his attention to those until he makes all the red disappear, and now he has this:

int g = 0;
for(int z=array[0]; z<array.length; z=z+1){
    g=array[0];
}
return g;

This code is much, much better.  It's still not perfect.  But, given the flaws in his first draft, do we have any reason to believe that he really understands this new version and why it is actually better?  Or is he just changing code until the red goes away?

Now, he runs it, and it immediately ends by returning the value 0.  So, since he still has about 5 minutes left to his exam time, he starts just changing things at random.  He changes his int z to be = 0.   Now he starts getting a number returned!  He tries putting g into g=array[0], then he puts z into it.  Now he has g=array[z].

He dithers about a bit, and finally adds a + in there.  He now has the correct code:

int g = 0;
for(int z=0; z<array.length; z=z+1){
    g+=array[z];
}
return g;

He turns it in to the teacher, who says, "Boy, he sure understood this!  That's one student that I don't need to give any extra attention to, because he is in great shape in my class!"

The takeaway questions then are:

How well does the student understand the material?
How well does the student's grade reflect that?
How much worse are the odds that the student will now receive the extra help that he so desperately needs?

We need tests that actually show what you really know, which is not always the same thing as what you can produce with prompting help from an IDE.


Agile / SCRUM Course Structure: Downsides? Resources?

Don't subvert the very purpose and essence of agile development: the ability of the product owner to re-target the project (almost) instantly and make changes and adjustments to the backlog as business conditions dictate. The alternative of specifying everything at the start has failed repeatedly in long running projects in which it makes no sense whatever to follow the initial plan.

Some of what I write below assumes you (or a future reader) is familiar with the terminology and the purpose of the various roles and tasks. To try to be complete would require a text-book.

So....

You need to separate the developer group (Devs) from the product owner (PO) (person or group). I normally do this randomly, but other things might work. The PO has control of the backlog and releases features from it per iteration. The developers don't see the whole thing other than in overview form at the start. If you don't want the Devs to do estimation you aren't doing agile, so they should do that, per iteration for the most currently relevant cards (features). Then they give the PO a "velocity" that will determine how many features can be in the iteration. If you are doing a project in one term, iterations should be short (1 week?) and small. But even if they don't estimate time per task, having been pre-determined, then they should still give velocity, having seen a few of the features desired now. Otherwise they will just be frustrated by too much work in too little time. That leads to burnout and is not agile.

The downside is that the PO doesn't get to develop. That may be an advantage depending on the makeup of your student group, or not. I prefer to be the PO myself so that I can throw in a kink or two along the way.

As ctrl-alt-delor says, you need to prevent speculative, build-ahead, development. You have to be fierce in rejecting all attempts at it. Not showing the entire backlog helps with this, but simply rejecting any feature produced speculatively is needed. The problem is that your students have likely gotten in to one bad habit. They have probably in the past been given partly specified projects and assignments where "creativity" is valued. So they try to get creative, by their own definition, ignoring the needs of the PO. In the real world it seldom works that way (Startups excepted) and you need to learn to work to someone else's vision not your own. So you need to make that work in the class.

The following is speculative and I haven't tried it. If you really want every student to experience every role then do this: Appoint a PO somehow for the first iteration and they hold that role throughout. Accepting or rejecting (with your guidance) backlog items as they are "completed." Then at the end of the iteration rotate roles so that the old PO becomes a developer and some other student takes on the PO role. They will need some time to become familiar with the backlog, however, so it probably can't happen that the iteration ends one day and a new PO takes over and specifies the next iteration immediately. A negative aspect of this is that the old PO will have knowledge they shouldn't have (and wouldn't have) in reality which may make them eager to speculate.

I would also require the "small-ball" skills (sorry, US baseball term) that Extreme Programming suggests. I.e. personal skills: pairing, test first, etc. Pairing will help them teach one another and build team skills.

Another possibility for doing a course on Agile Development, though it doesn't match your stated requirements is as follows. (I say this as others may benefit). Instead of one large project have a bunch of tiny projects with 10 minute features and 30 minute iterations. If you run a course in 3 hour segments this can be made to work. In fact, I know of one real-world outfit that does this sort of thing on real (i.e. large) projects - maybe one hour iterations.  With such a scheme a person is PO for one project but will take a different role the next day.

At some point in any agile course, trying to be realistic, you need to throw a curve-ball (sorry). Change the backlog/project-direction in some fundamental way. Estimate from the current code-base and move on as usual. It really happens that way (experience here) and also shows that the word "agile" actually means something. Trying to make the initial requirements too precise is also a problem/trap  that will encourage speculation. Real agile projects don't work that way. The initial backlog is pretty vague about specifications. It is only as you approach the iteration in which a feature appears that it becomes specific.

You will need to guide the PO so that they do sensible things. You will probably need to be the project Coach. If you need to ease the development you could provide some of the tests (unit tests) to guide the developers. After doing this initially they can take over. But you need to give them advice (as coach) on the quality of their tests.

Note that I've merged ideas from both Scrum and XP here. Scrum works well for the overall management (Backlogs, acceptance...) and XP for the day to day tasks (pairing, testing...). If you don't require day-to-day level skills the students will probably just thrash. Agile requires discipline, which is often missed - especially by those who reject it.

There is more to say, of course. But the bottom line is that to teach agile you need to be agile.


“What do you mean it’s plagiarism? It’s from the docs!”

So, my take on this is to sit down with the student and have roughly this talk:

So, I'm a little disappointed by the lab you handed in, for two reasons.  The first is that it is pushing on the edges of plagiarism.  Now, I'm not going to go through the formal process, and there is going to be no punishment this time.  I am instead assuming that this is a distinction that you were unaware of, and I am going to make sure that you are completely aware of it now:
Plagiarism means passing off someone else's work as your own, and this code isn't really your own, and your source isn't fully cited.  As I said, I'm not going to pursue this further at this time, but in academic work, you should be citing sources for anything that is not entirely your own.
The second reason I'm disappointed is because you've even more deeply misunderstood the purpose of the assignment.  You clearly came in thinking that the purpose here was to accomplish the task.  I know that in industry, the idea is often to just get working code out.  But in spite of what you might think, I actually care very little about [insert the result of the lab here, such as "the number of brick arrangements in this oddly-specified wall" or "whether the character in this game can correctly identify a collision"].  Why do you suppose I created this assignment?  Was it because this is an unsolved puzzle, and there is a pressing need to accomplish this task?
Of course not! These problems have been solved many times before.
The purpose of the task is to help you learn and absorb the material, and to help make you a better student and a more capable person.  The ideas in this lab are foundational, and carefully chosen to help you build up to bigger and more difficult ideas in the future.  I want you to absorb these ideas well enough that you can mentally use them to build those bigger and more complex ideas.  The goal was never this algorithm per se.  The goal has always been mastery, so that you can move on to even bigger and better things with a good chance of success.
I think you can see where I'm going with this.  You have kinda cheated me by giving in work that's only sort of your own, and you have kinda cheated yourself by only sort of wrestling with the topic well enough to master it.
We will survive this today, and we will move forward.  But I need you to understand that this isn't the way to approach lab work.  Can I now trust that I won't get this sort of work turned in again?

... and after the student agrees ...

Good. Labs are for learning. I hope that the rest of your day is pleasant.  Take care, and I will see you again in class.


What's the benefit of prohibiting the use of techniques/language constructs that have not been taught?

Rules like this are generally instituted because the teacher is attempting to teach a concept made moot by one of these constructs. For example, as a teacher, if you're teaching bitwise operators and ask students to implement absolute value, it simply makes no sense to permit the students to use whatever library function does absolute value. You're teaching bitwise operators, and the fact that they know of the library function doesn't help them learn bitwise operators.

I believe that because you're asking here, the reason for the prohibition isn't as obvious as in my example, but my guess (without knowing the specifics of the situation) is that the prohibited constructs are not what are being taught so, for that course, the students knowledge of a more advanced concept is irrelevant to the subject matter being taught.


Student not understanding explanation the 1st, 2nd... and 8th time

Maybe you are stressing things of minor importance. You gave us two examples.
vector<int> copy;
for (int i = 0; i < my_vec.size(); i++)
    copy.push_back(my_vec[i]);

sure is lengthy, and probably also a bit slower than the C++ expert version of
vector<int> copy = my_vec;

But it does its job and is readable (while e.g. to me as a Java guy, I'd struggle to remember that the assignment operator here does a copy of the data structure). And, regarding performance, we all know that in at least 90% of all cases, it doesn't matter. And if it matters, I'd search for a solution where the vector doesn't have to be copied at all.
Regarding Hill Climbing: During 40 years of software development, I rarely ever needed hill climbing, and I've been working in algorithm-sensitive areas. So, unless your students' jobs need things like hill climbing regularly, think of exercises better matching their everyday needs.
To summarize it: You're not preparing that guy for a PhD in computer science (which most probably isn't needed for his job and out of scope for him as well), but giving him some tools to improve the software engineering aspects of his work.
With this guy, I'd switch from a fixed curriculum to practical reviews of production code, concentrating on readability, robustness and structure, looking at code written by different developers. If he struggles there as well, then have a nice, deep talk with him.
EDIT, as requested by OP
Regarding the "nice, deep talk": If that guy really struggles hard with basic concepts of software engineering, then he'll probably never catch up with the others. That mindset of specifically-structured thinking is not given to everybody. So, he should understand that his talents might be somewhere else.
He can choose whether he wants to pursue his career as a software engineer, with the risk of always staying behind all the others. Or he can find a different role in the team where his talents shine. It might be he is good at understanding the customers' way of thinking, or at hardware development and interfacing, or UI design, or management, or quality assurance, or whatever. Software development teams need so many roles besides coding, there might well be tasks where he can shine.
That's what I'd talk about with him. You should try to make this a positive experience for him. Maybe you already observed some of his talents, so you can suggest some migration path. For that talk, interpersonal skills are most important.


Why might be the benefits of teaching data structure course in Python?

Since we're missing a lot of information, this answer will be fairly bare-bones.
There are no "right" or "wrong" answers here.  Everything hinges on the goal of the course.  And this is as it should be.  Usually, you choose the learning goals for the course, and then choose a language that helps you to achieve them.
If the goal is to understand algorithms and data structures, you would want to work in the language that students would most easily grasp the underlying concepts.  Typically, that would point you towards high-level languages that handle garbage collection for you, but it might be a lower-level language if earlier coursework within the program gives students a lot of fluency in a that language.  (Garbage collection itself could be studied within an algorithms class, as it's essentially a graphs problem.)
If the goal is to get a lot of practice with direct memory management, then you would certainly want to move towards a lower-level language such as C++.  This would come at the expense of some algorithms/data-structures study, but the tradeoff could be considered worthwhile.
It all depends on the outcome the instructor is going for.


I use school colors and principal's name.

If someone comes in tomorrow and says your principal is no longer Mr. Smith, it's now Ms. Jones then that change is made for every object (student) in the school. You don't have to go to each individual student and tell them that their principal has changed.

It worked really well this year because we did get a new principal.


Learning and teaching competitive programming depends a lot on what level the students already have. The first step is getting to know basic features of a programming language, preferably C, C++ or Pascal, since some contests require to use one of these. Out of these, C++ is used most.

These basic features include at least: variables, strings, input and output, if and else, while, for, basic manipulation of arrays. In fact, this is usually enough to (theoretically) be able to solve every problem. Of course, built-in sorting functions and things like inteprenting characters as numbers are useful as well. As you say, this is mostly just knowing, and less insight.

Improve someone's problem-solving ability is in the beginning mainly practising, for the problems you don't really need any textbook algorithm or other, more complicated techniques. Besides explaining solutions to problems that the student can't solve but already tried sufficiently hard, there is not very much to teach. The "tried sufficiently hard" is important: you learn this problem-solving ability the best when doing this.

After that, on a higher level (e.g. National Final Round, or even the IOI), the students need some standard textbook algorithms (e.g. Dijkstra's algorithm) and other techniques, and you can teach this. You can find all the topics you might want to teach in the IOI syllabus.


Using microcontrollers in an Introductory course

Microcontrollers can address two important aspects.

The first is bridging the gap between the code, and the real world. Particularly if you have sensors (accelerometer, buttons) and outputs (an LED array, sound, motors). Not just to address the robotics aspect (which can rapidly get complex), but some simple game concepts (patterns, reactions). Nothing which is any harder than doing the same on a Raspberry Pi with a GPIO extension, but potentially cheaper hardware (which is important if it is likely to get fried). Also, if you want a battery powered device, or a small data-logger, a microbit is more suitable than a Raspberry-Pi.

For introductory use, I think creating a simple tilt-sensitive animation is a very effective way of making 'coding' seem more real. Yes, the coding gets more complicated if you want to do more - but starting in a block editor or python avoids this.

The more tactile, less 'black box' approach to coding seems (according to research by the BBC) seems to provide more up-front interest to less technical students.

The second aspect is working in a resource-constrained environment. Admittedly this is more a advanced concept to teach, but the microcontroller is 'clearly' a different beast to a laptop or a phone. Having some restrictions sometimes help people to solve problems more easily than giving them the blank sheet of 'plus anything you can find a python library for'. A computer small enough to wear on a lanyard will shift the way students think about what is possible.


Should I teach that 1 kB = 1024 bytes or 1000 bytes?

You should teach both, and you probably want to use the binary unit. When you are talking about the difference, it may be helpful to tell them about how to tell the difference when reading them:

The SI kilo- is k:
$1\ \text{kB (kilobyte)} = 10^{3}\ \text{bytes} = 1000\ \text{bytes}$

While the binary kibi- is Ki:
$1\ \text{KiB (kibibyte)} = 2^{10}\ \text{bytes} = 1024\ \text{bytes}$

I notice that you used KB in your question to refer to both sizes; perhaps you should also point out that KB could be interpreted as either of these prefixes (though Wikipedia suggests it is most often used in place of KiB). In your position, I would suggest clarifying which one you mean if you use this notation.

(While you're going over confusing units, a related difference in writing units is that lowercase b is bits, uppercase B is bytes; an eightfold difference is much more significant than 2.4%.)


Computer Science vs IT vs Digital Literacy

When we were drafting the English national curriculum, we found it easier to think in terms of the foundations, applications and implications of computing, all three of which really should be included in any broad and balanced approach to the subject. You can map these to computer science, IT and digital literacy if you wish, although you would need to accept a rather broader definition of digital literacy than that used by the Royal Society

Foundations would be about the underpinning principles of computer science (logic, algorithms, data representation, abstraction), as well as their practical expression through programming and more generally in computational thinking.

Applications is about skills in using digital technology to get useful work done, including collecting, managing, analysing and communicating data and information and creative work in a range of digital media.

Implications is about a critical understanding of the impact of digital technology on individuals and society as well safe, responsible and ethical use. I'd include intellectual property, privacy and security here too.

I've an illustration of all three in response to the question 'How does Google work?'

Foundations: big data, Page Rank, Big Table / the Google File System (GFS) etc

Applications: type your query, click the button (well, these days it starts searching as you type), but also filtering results, advanced queries etc

Implications: profile, filter bubbles, advertising, smart creatives, separating costs and revenues for accounting purposes etc


Pedagogical reasoning behind a minor difference in two loops

This is a really good place to introduce boolean variables (or just to use them, if they've already been introduced. It also introduces the idea of descriptive variable names.

user_wishes_to_continue = True

while user_wishes_to_continue:
    answer = raw_input("Do you wish to continue?")
    if answer != "yes":
        user_wishes_to_continue = False

print ("Good bye")

Note: here I use raw_input, which returns the user input as a string, rather than input, which interprets the  user input as python code (meaning that you have to put "yes" with the quotation marks each time.


Why some students think that programming is difficult and hard to learn, how I convince my students that programming is not difficult as they think?

Careful! That's a pretty aggressive statement, and is liable to make folks who really do have trouble feel pretty bad about themselves.

You may want to take a look at this question. Whether you believe the answer to ultimately be yes or no, you will find that even the most adamantly "no" teachers admit to some number of students who have enormous difficulties

Interest is highly important, of course, but how your brain is wired matters a great deal as well. Don't discount real difficulties that people face. That's the kind of thing that causes people to beat themselves up mentally, when they're alone with their own thoughts.  Interest is important, but may not be sufficient, and dismissing the problems others face can be unkind.


How to tell a student that s/he should enroll in a different program?

Don't tell them anything. Ask pointed questions.  Ask why they chose this course, or this major.  Ask where they expect to be in a year or in five years.  Make them talk through their plans.  Let them find the gaps in it.

This past semester, I asked every single student that came in to my office to change majors to CS (or to IT) the same first question: "Why?"  Some students had a great immediate answer, and I signed the form right away.  With others, we had a 20 minute conversation.  Some of them said they're in it for the money, and I would say things like "You'll make more money as a plumber, and you don't need college for that."  "Oh, but my dad said-"  "But what do you want?"

It's like helping them learn to debug.  Let them come to the decision.


Answering student questions as they work outside class

Threaded discussion forums allow everyone to see all questions and answers and to post questions and receive answers at any time that you find convenient to check in and update. I have used this in online teaching before. It works very well.

Actually, I don't know of anything else that does or would work. I would love to hear about other possibilities.


I post solutions after the due date of an assignment. And usually, I'll go over them in class as well.

Two birds...

Students get to see at least one working solution, although I try to come up with several.
Posting the solution serves as a good block to students asking to turn in assignments late. They'll understand pretty well that they can't turn it in late after I've already posted solutions.

I've been trying this year to make videos of me working through the problems. Sometimes they'll be screencasts of me working through the problem in front of the class. Sometimes they'll be a little more scripted and recorded when there aren't students listening. Usually it's the shorter problems where I'll just record myself during class and the longer ones that I script out a bit.

Another activity I like is to do code reviews. I'll screen shot several student submitted solutions and we'll go over them anonymously. I'll include a couple that are really good solutions. But, better than that, I'll also include a few that are really close but not quite a working solution.

On some assignments, especially those that are a little more difficult, I'll provide a pseudocode algorithm with the assignment as a bit of a cheat sheet. Nothing that can be just typed in, but sometimes students need a little bit of a nudge in the right direction.


Any tools or frameworks for visualisation of algorithms?

Actually, a few years ago, there was a large effort to work on algorithm visualization and many tools were developed. Tom Naps led part of that effort, but I suspect he is now retired.
But a simple google search for "algorithm visualization" will turn up quite a lot of both tools and people.
They aren't hard to build, actually, if you use a language like Java that has a large and sophisticated graphics library.


Talking about new/active subfields of CS to inspire students

I think a really interesting one would be the idea of cryptocurrency, this may not be what you are looking for particularly, but it is a new horizon that is bringing many new ideas to tech. Ideas to cover, the block chain, the ethereum flash crash, the anonymity (or lack thereof) of cryptocurrency, regulation of cryptocurrency. How mining works. The list goes on and on


What could be the possible advantages of teaching Scheme as first programming language?

I think that the purpose of such a course is not to teach you a language. After all, Scheme, with its abstract syntax, is pretty minimal as a language. The purpose of a course like that is to teach you to think abstractly. If you can do that now, several years later, you can probably thank the course for getting you started. Abstraction, after all, is the big idea about computer languages.

A course in Python or another language can do similar things, but not in quite the same way, since in those languages you also need to learn the language syntax, idioms, and other structures. Scheme pushes all that aside for the opportunity to focus on abstraction. The things that are not in the language make it easier to focus on the big ideas.

This isn't really related to your question, but I note that many language designers start out with a lisp- (scheme-) like syntax to try out ideas in the language before they think very hard about its concrete syntax. It turns out to be very good for such experimentation.


How can I set up and deliver a Computer Hardware Course for the first time?

Somebody is going to be spending some money.

From the question, it seems that the school has not set up a lab environment for the course. Your purchase of Pis was a good move in the right direction. To be useful, your Computer Hardware and Software course needs to be more of a lab style course than a knowledge-based course such as history or math. Making it more hands-on for the students might even help reduce the rowdiness and tame the ADHD.

Test Basics

There is no age requirement, from CompTIA, for taking the tests. CompTIA does, however, recommend 13 as a likely minimum age. (A point to return to later.)

The overview from CompTIA provides:

  Specifically, we recommend that you have the following skills and knowledge before starting this course:

  Recognize the main components of a PC and different data media such as USB drives and DVD.
  Start the computer and navigate the desktop.
  Use Windows Explorer to create directories and subdirectories and manage files.
  Use a web browser such as Internet Explorer to view websites.

  After reading the CompTIA A+ 220-901 Certification Study Guide, you will be able to:

  Identify types and characteristics of PC, laptop, and mobile device components, including motherboard, CPU, memory, and storage, input, and output devices.
  Install, configure, and troubleshoot peripheral devices and system components.
  Install, configure, and troubleshoot print devices.
  Install, configure, and troubleshoot wired and wireless LAN links and Internet access devices.

  After reading the CompTIA A+ 220-902 Certification Study Guide, you will be able to:

  Install, configure, and troubleshoot the Microsoft Windows, Linux, and OS X PC operating systems plus iOS, Android, and Windows mobile devices.
  Configure and manage PC and mobile device network connectivity plus users, groups, and shared resources in a typical SOHO network.
  Use anti-virus tools to prevent and recover from malware infections.
  Configure access control measures, such as authentication, security policy, encryption, and firewalls.
  Perform basic PC maintenance while working safely and responsibly and communicate effectively with customers.

Based on the test expectations, I would surmise that while you may not be well versed in each objective, you have a solid foundation of experience and exposure which will make gaining the requisite knowledge easier than you're anticipating. In practical terms, the level of knowledge being tested is mostly just a notch or two above "common knowledge" anyway. Reading the book by Mike Meyers (see next section) could be all you need to learn about the A+ to be able to teach it to your students. I'd still recommend getting a copy of the Official study guides anyway, even if you find a used one somewhere. The manner they present the information is influenced by how they will test for it, and knowing that will help you design your course to help ready your students for the test.

Instructor Prep

It seems a bit much to expect that high school students would be able, and willing, to purchase their own copy of the official CompTIA A+ Study Guide. As the instructor, however, you probably should. As an alternative, or supplement, you could read CompTIA A+ Certification All-in-One Exam Guide, Ninth Edition (Exams 220-901 & 220-902), by Mike Meyers. In various versions, his CompTIA related books have been recommended reading. This book is probably available in your local public library, or through ILL if they don't have it.

As a guide for developing your course you can at least review the objectives for the two A+ tests, (hardware) 220-901 and (software) 220-902. An extra problem is that the 220-901/220-902 test series is old. They were launched in Dec., 2015, and are set to be retired in July 2019. If a partial objective for the course is to prepare the students to pass the exams after the course, there could be a timeline issue. The current test is set to retire at about the same time as the students would be finished with the course.

The CompTIA tests are billed as "vendor-neutral" and they do cover the majority of the field, including Linux, Mac OS, iOS, and Android, in their testing. Windows is still the priority for the testing, with almost all the software and networking scenarios involving Windows-based tools for their solution. That said, without the exposure and practice with Linux, and the mobile OSes, they are unlikely to achieve a passing score on the real tests. What little there is for Android and iOS can be discussed and some of the students can practice on their personal phones, since it mostly involves increasing security or connecting to networks and email servers. The improved security on their devices will not be a bad thing at all.

Lab Prep

While it is not, technically, required, the A+ preparation course will be most effective if it is based on in-lab experience more than memorization of material. (Think of automotive mechanics more than chemistry.) Especially in the hardware section (220-901), what the students need to learn is what they can do rather than know. The software test (220-902) is more evenly split between skills and knowledge. Even so, doing it will mean more than knowing it. This means having a "lab" available to practice in. The lab does not need to be anything permanent at all. One A+ Prep course that I was familiar with at a community college used a regular classroom. The instructor had all the elements needed stored in a collection of plastic crates and they were wheeled into the classroom on a hand truck for the class twice a week.

Build a test lab with a couple desktop computers with monitors, a couple network hubs and/or routers, cables that work (and some that don't :D) and extra hardware (HDD, RAM, printer, external devices including USB HDD).  In this case cutting edge is not as good as old-school. An old Intel Pentium Dual Core/AMD Athlon 64 x2 with a motherboard that is just new enough to include a SATA port along the IDE port(s) and smallish HDDs, 150-300GB, in a mix of IDE and SATA. An extra advantage of using the older (ancient?) hardware is that you can probably find it very inexpensively in thrift shops and second hand stores. Since it is for school, you may even convince a local electronics recycling center to donate some of those parts. If you can amass sufficient spares you won't have to worry about the occasional damaged parts.

In addition, even a non-working notebook (laptop) which can be dissected, and a few samples of other portables to allow the students to see the internals, would be helpful. Opening a notebook computer can be tricky - usually there is one piece you have to "pry" off first, after which it becomes a puzzle box, removing screws and pieces in the proper order.

On the software side, specifically the OSes, you can get by with, and I recommend using, Windows XP Pro, and an older Linux more appropriate for the collected hardware. The "latest and greatest" Linux kernel will probably work on the suggested systems, yet newer kernels will not supply any additional benefits to the students, be larger, and take longer to install. A system that can be installed from a CD (not a DVD) and operate without updates or extra installed packages allows the students to practice setup and configuration of Linux without needing an Internet connection for the box each time. Likewise, with Windows XP Pro, Service Pack 2, you can do a complete install without having to access the Web for updates or drivers. As the system will be installed, and then removed, repeatedly, there is no issue with the licensing for Windows, and you will not have to perform activation. One legal CD-KEY is all you need. (Several copies of the install disk, however, is strongly advised.)

Motivation

This probably the hardest part to give pointers on, as I have never met your students, and do not know anything about their background. The one point that seems to apply in almost any situation, however, is "self-interest." Other than the rare student who loves knowledge for its own sake, they are not going to be very motivated by "knowing" something unless it makes "getting" something easier. knowledge of why the students are in that class could help. If they took that course because the school/district/state requires it, the only "motivation" they start the course with is "pass the class." Worse, though likely, is that the course had a reputation as an "Easy A" with the prior instructor, and the current students selected your course to avoid doing any learning while collecting a needed elective credit for graduation.

As mentioned in the prior section, CompTIA has no age requirements for the A+ Certification. If the course has, or can be given, the objective of passing the CompTIA A+ Certification tests after completion, one possible motivation can be that your students, still "minors", can obtain a certification that is meant for adults, and having it might open doors for summer jobs, with good pay that even a lot of adults couldn't get. The exams themselves are not inexpensive, however. The CompTIA A+ Certification requires two tests, and they are $219 US each, with no refund for not passing. If the school was willing to fund, as a scholarship, the testing for students who get an 'A' in the course, that might provide an inducement as well.

The subject matter for your Computer Hardware and Software course is, by nature, dry. The sector layout of spinning rust just is not exciting. I like having my systems very personalized, yet I don't find reading about config settings the least bit entertaining. (I probably will not remember what the settings mean next week either.) Making something, and seeing your work produce results, can be quite fulfilling, however. If you are able to create the "lab" and the students can learn about the hardware by building a computer from scratch, there is the challenge of getting it done, and the thrill of seeing it come alive the first time when they get it right. The more "boxes" you have available for building, the better. Still, with just wo, you can make it into a team project, and the teams can take turns building a system. You can even create a pattern where one team builds part of the system, and another team finishes it without knowing what the first team did until the examine the partial build in person.

ADHD Considerations

If the students truly are ADHD, as the question states, then the hands on approach will help even more. In addition, you can limit your "lecture" time to short segments inter-spaced with some form of kinesthetic learning. Something as simple as passing around an HDD to examine can break the lecture into manageable chunks, give the students an excuse to move their bodies, and help them associate something physical with whatever you've been saying. As a general beginning point, limit the time students have to pay attention to you to intervals of 20 minutes, or less. Allow, or encourage, moving about the room for a couple minutes between segments. Walking about the room, or other large motor movements often help with alertness and can improve focus during the other times.


Encourage students to learn and use advanced design

The most fundamental shift in my programing came from my attitude about details.
When I was young I wanted to pull every detail out of everything I touched, pin in down in front of me in one source file and beat it into submission. I could stand in one place and know everything.
After decades of programming my attitude is: the less I know the better. Dealing with a detail? Feh, I let other things deal with that. I already have plenty of stuff to think about right here thank you. I don't need more clutter.
I have shifted from a procedural mind set to a more abstract one.
That sounds fancy but all it means is that no mater where I am in the code, I want to think about only one problem, in only one way, from only one perspective.  Any detail that distracts from that is getting tucked away somewhere. I work very hard to make it that easy because I'm that lazy.
There are many ways to try to teach this, problems that invite students to drown themselves in details if they aren't careful. But one guiding principle has helped me see when I'm doing it right.  It has many names but the one I'm most fond of is:
Tell. Don't ask.1,2,3,4,5
If I have to ask a question then I have to deal with the answer. Usually that's a detail. The only reason I ask is because I want to do something and I don't have enough information to do it. Why can't I just tell the thing I asked to just do my something? It knows the answer, so it knows what it needs already. I should be able to just tell it "do it now" and it should be able to go do it without making me think about it.
Adopt this attitude and working abstractly becomes very appealing. Without it, abstraction and polymorphism are very annoying because they're getting in the way of you knowing everything. Teach your students to love not knowing.
I don't know. I don't want to know.

How to motivate students to use this?
Don't.
Motivate them to explore it. Which is better is not a settled issue. What you should teach is what problems this style addresses. How to identify situations that create a greater need for it. How to identify situations where it's irrelevant.
I've been studying every programming principle and style I could find for decades now and not one of them is something I would advise someone to adopt without critically analyzing how and whether to apply it in any given situation.
What I do recommend is practicing with them. Until you've used one while solving a real problem all your doing is being a tourist. I've watched people end their career by waving a book around preaching principles without knowing how to solve a problem.
When interviewing prospects I'd rather hear:
"If you follow principle x it may help with this y issue."
than
"You should always follow principle x. It's good design. Professionals always follow good design."
Spare me from fanatics that follow rules without thinking.
Encourage them to learn every principle, pattern, and practice they can. Not because they should always use them, but because when they look at code that already uses them they should understand why the code looks the way it does.
The reality is true professionals spend most of their time wading through crap code trying to get what they need out of it while causing the smallest amount of fuss they can.
The really good ones will spot some tiny little improvement they might be able to get away with while they're here. These "boy scouts" leave the code a little better than they found it. Give me those over the crusaders that want a complete rewrite every time they look at a new code base.
Cultivate in them a skeptical "boy scout" attitude. Give them all the tools but teach them to use them sparingly, wisely, and carefully.


The grown-up answer: Because it's good for you.

No, really.

At this age the different things you study all give you different kinds of skills and different ways of thinking. Thinking is good and the more different ways you can do that the more likely it is that you will be able to solve the problems as they come along. The different subjects in the early years are put there because people (grown ups) think that they will be relevant in the future.

Being able to think for yourself means you are more likely to be able to detect the lies that people will try to tell you to get you to do things that aren't really in your best interest, like buying something that has the main purpose of compromising your privacy. Math, History, Philosophy, CS, ... all teach you to think in different ways.

And, in fact, programming is useful in many fields. Even philosophy if you want to examine a lot of texts written by old (dead) philosophers. Science can't do without it anymore. Nor can some aspects of literature.

The less grown-up answer: Because it's fun.

No, really.

Well, if it isn't fun then maybe the teacher needs to rethink how the course is taught. Why isn't it fun? Is it the sorts of problems that the students are working on? Are they boring to the students? Is it the way they are supposed to behave? Too much frustration of working alone (or the opposite, I suppose)? Personally, I hate boredom. Or is it that they just don't have any bigger picture of what it is that they are learning, being always lost in the details? You can always ask the students what they "learned today". I used to ask that quite frequently, just to get them to focus on that before they left the classroom.

Ok. That was a bit grown-up too, but devious. Devious can be good, if done right.


How to convey how much computing power has grown since the 1960s?

This is really difficult to communicate to anyone who hasn't lived through it (and even to those of us who have).

I don't usually go back as far as the 60s.  I show my students a picture of the ASCI RED supercomputer from ~1998, which was the first supercomputer to be able to perform 1 trillion floating point operations in a second (1 TFLOP).  It's basically the size of a warehouse floor, with another floor consumed by its climate control system. It cost ~46 million dollars.

Then I show my students a picture of a typical rack of servers from 2008, which could perform 2-4 TFLOPs.  In a decade, the size had shrunk from a warehouse to a single rack, the computing power had doubled, and the cost was about $200K.

Finally, I show my students a picture of a Nvidia K80 GPU card, which can perform over 2 TFLOPs.  In less than a decade, the form factor has shrunk to a card you can put inside a desktop computer, with the same power. Launch price was about $5K.

That is in less than 20 years.  Extrapolating from that back another 20 years only gets you to 1978; you have to go 10 years beyond that to reach 1968.  It's really hard to communicate the extent of this change.

And that's just the change in raw computational power, ignoring other advances like the Internet...


How to respond when students ask "is recursion good practice"?

Quite honestly, I would be upfront with them about the debate. Send them to a couple other SE threads:

Efficiency: recursion vs loop
“Necessary” Uses of Recursion in Imperative Languages
Are functional languages better at recursion?

This now becomes a teachable moment on a number of levels: imperative v. functional languages, recursion v. iteration, "expense" of function calls on the stack. Students appreciate being shown the messy truth behind topics that are sometimes treated reductively and simplistically. Let them wade in the mire and see what they think about these debates. Have them analyze the arguments they mind on here; now they are thinking on much higher, more sophisticated level about program design.

The key line that I take away from all of these is this one: "You almost never use recursion for performance reasons. you use recursion to make the problem more simple" (top answer to the first post I linked to). It's often times an exercise in thinking more so than programming.

From a pragmatic perspective, discuss use cases for something like merge sort and quicksort (recursive) v. bubble sort (iterative). Throw in traversing tree structures as well. There is a time and a place for thinking recursively. Iteration is not always the best choice to make.

Last, from an aesthetic perspective, based on my time studying SML, there is a beauty, an elegance, an aesthetic to a well-written recursive function. It's clean, clear, easy-to-understand. If part of code quality is its readability, then recursion has an aesthetic quality to it that a for-loop arguably does not.


How do you teach something when you don't know it yourself?

This is a vital question, perhaps the vital question, for a CS educator to deal with, because technologies will keep pushing us.  There is no end to this particular merry-go-round.

I have been stuck, non-stop, in exactly this situation, for the last four years in a high school for gifted students, and I can attest that it is physically, mentally, and emotionally exhausting. It can push you to the edge of a nervous breakdown. It can also be incredibly rewarding, both for you and for the students.

I claim no special wisdom, but here are some of the techniques I've been using.   I hope will be of help to other teachers gazing down the barrel of a similar gun at some point in their career:

Don't be dishonest with your students or try to hide your lack of background.  There will be moments that you come up short, and your honesty and forthrightness from the start will help to mitigate any loss of trust that students might feel when this happens.
Find several great resources.  Do not depend on one resource to give you the sort of thorough understanding you need to do this well.  A strong textbook is great, if there is one to be found, and can help you both understand the material and sequence your lessons.  However, single-source preparation leads to two problems: (a) your understanding will be brittle, and you will be left with only one way to explain a concept when students are lost, and (b) it will be very difficult to deal with questions, particularly from your brighter students, that go off-script and try to connect with outside ideas.

In my best situations, I will have a textbook, a tutorial series (such as might be found on YouTube or a website somewhere), some exercises to work though, and a tutor to help me when I get stuck.  SE can, itself, act as the last two of these for CS topics in a pinch, though it is not as good of a tutor as an actual tutor, who will build a dialogue and set of understandings with you over time.
Use the lesson planning itself as your final preparation, in which you summarize the key understandings and design exercises to help your students fill in the dots.  Over-prepare your lessons, because your instincts for how long the material will actually take to cover are not yet honed.

(I once prepared what I thought would be 3 lectures, and ended up delivering it as 1 lecture because things went extremely smoothly.  At the end of the hour, ,I arrived at the end of literally all of the material I had prepared.  The students enthusiastically told me that the lesson had made a lot of sense.  "Great," I thought, "I'm glad that made sense to the students, but what in the world am I going to do tomorrow??")
When students ask interesting, tangential questions, don't be afraid to reply by asking if they would be willing to research it a little and report back to the class next time.  It is important that not every student question become a major research assignment for you.  Instead, choose your battles carefully. Burnout is a real danger, and your time is valuable.  You have made a pact to help guide students through the main topic; don't get caught up in too many tangents on your first pass.
If you're really caught for time, you can simply present learning materials and ask students to work together to try to make sense of it.  Be careful not to do this too often, because while this technique can work reasonably well for your high-fliers, it does not leave you in a position to guide and help the students who really struggle.
Accept that this is an imperfect business.  You will mess up from time to time.  You will make mistakes.  You will arrive at a lecture feeling prepared, receive a student question, and suddenly realize that you don't understand something that you thought you did.  You may even discover that something you taught was outright wrong.  Be prepared to go back to the class and revisit an idea if you screw up.  But also, be prepared to forgive yourself for some amount of weakness.  You are an imperfect being trying to build a learning opportunity for your students, and all you can do is try your best.


Programming languages specifically designed for beginners

Scratch is a visual block-based drag-and-drop programming language designed specifically for learners, especially children. It's created by the Lifelong Kindergarten Group at the MIT Media Lab.

The language and IDE are pretty much completely connected. Here's how I see it checking off your bullet points:

Object oriented: It has sprites, but it's debatable whether it's truly object oriented. It can serve as an introduction to the concept though.
Good IDE: Yes. There's a help toolbar on the right side.
Simple IDE with run button: Yes.
Visual: It's completely visual and drag-and-drop. Typing is only needed for numbers and strings, essentially.
Free of language oddities and paradoxes: I'm not sure exactly what type of oddities and paradoxes you're thinking of, but Scratch tries to be helpful and avoid breaking your code whenever possible. The blocks themselves are pretty intuitive and self-explanatory.
Other:

Indentation: Since it's not text based, this is less important, but control structures (conditions and loops) do get their code indented.
Variable declaration: All variables must be defined before use.
Memory safe: Yes, it runs in Flash in the browser (next version plans to move to JS). You don't have any control over actual memory usage in your program.

Scratch was my first language, and I've been teaching it as a first language for the past several years. It's great for teaching the concepts without worrying about annoying little things like syntax.


Scheme - Which implementation to use for teaching

Racket is a variant of Scheme that is both very good and very popular. The DrRacket system is probably all you need.

DrRacket is widely used and there  is quite a bit of information about it online. It provides a very simple interface.

There are also Scheme plugins for NetBeans and Eclipse if you want a more complete IDE.


How to make project in java language, for students who doesn't know java?

There is a Pedagogical Pattern called Fixer Upper that can be used for this purpose.

Prepare a fairly large Java program that includes the features you want them to use. In this case it would probably be best if they know how to write that program in their "native" programming language: a familiar seeming project.

Then insert several errors into the program of various kinds. Some of them just simple syntax errors but some of them more complex, even some that break the program so that it doesn't quite solve the problem correctly.

Give them an assignment to fix the program.

If you combine this with unit testing, which they may already know, it will give them some additional practice and skill. If you want them to do the fix-up especially fast, make it a pair-programming exercise.

I normally use this sort of thing as a quick start for a new programming language or even for complete novice programmers.

Make sure that the overall structure of your program is very good. If it isn't, then they will learn the wrong lessons. Start with a structure that you want them to emulate.

A variation on this is to take such a program and go through it in lab rather than making it homework.

Note that reading a large program is insufficiently "active" to achieve the desired outcomes. Having to repair it will engage the students more deeply into both the problem and the language.

My ideal program for this would be several pages long and would include several classes. It would use a variety of design techniques, including a few design patterns. It would favor composition over inheritance as the mechanism for variability. It would define structure with interfaces.

A major variation of this is that the fixer-upper program could, itself, form the core of the project the students will do. Now the students are truly engaged from the start.


Realistic task for teaching bit operations

Maybe a bit too complicated, but fun nevertheless: Teach them about bitboards.
Conveniently enough, a chess-board has precisely 64 squares, so a 64-bit integer can store one bit of boolean information per square. Now the whole state of the board (disregarding en-passant and castling for now) can be encoded by having one integer per type of figure and one integer for all white figures.

Want to find the white pawns? use pawn & white.

The black pawns? pawn & !white

Want to find all occupied squares? all = pawn | rook | knight | bishop | king | queen

Squares reachable by white pawns in a normal move? (pawn & white) << 8 & !all

In a two square move? (((pawn & white & 0xff00) << 8 ) & (!all) ) << 8) & !all

The possibilities range from trivial to requiring detailed understanding of bit-operations and they are indeed used by real chess engines. If you provide a bit of code to visualize the results, these might also be fun to simply toy around with.


Can assignments be graded using blockchain?

Unfortunately, the quoted article has serious shortcomings and would be unworkable in practice. In the first place it isn't just about blockchain, but also mixes in quite a lot of other things, such as the bitcoin that is usually associated with it.

The article also misrepresents in some ways the reasons why you would want to do this. The financial crash wasn't, in fact, caused because financial institutions had centralized record keeping but, rather, because they had been given unlimited power to manipulate markets by a feckless congress. The medical record example is a bit stronger, however.

But the article also has the following technical flaws.

The school principle can create grading value (points toward grade = bitcoin) pretty much arbitrarily.
The transaction fees would have to be much (much) lower as they overwhelm the possible gain by participating.
Unless the student grader is also a miner, they have no incentive to participate as they can only give up points via transaction fees.
The reward (potential) is not in any way related to the educational objectives, made worse by:
In the real (bitcoin) world, the miners are so busy mining that they have no time to do anything else (e.g. study). The system actually enforces this, by making the reward harder to get over time.
At the scale of a school, miner pools could easily reach 50%, destroying the whole thing. Some students would much rather do search for treasure than do actual academic work. Why reward it?
You replace expertise in the subject (teacher grading) with amateur action, which is subject to error. If it just matching answers to keys with no interpretation, a machine can do it.
The overall work entailed increases as each exam is "graded" multiple times, plus the treasure hunt.
I envision that it would be more difficult for a student to contest a marking error in this scheme, though it might result if fewer of them being made.
Even in this scheme, exam papers can be lost. Distributing them probably increases the risk.
If teacher vindictiveness is an issue, blind grading can be done without the other complications of the scheme. It isn't actually essential that the teacher knows who she/he is grading.
As to the cost, I'm sorry, but if we paid teachers an actual living wage I'd be more willing to accept the argument. But in the real world, teachers don't really work for money. Lawyers and Doctors have a similar level of education to Teachers.

But these are flaws applied to the "fun" example, not the thing (blockchain + bitcoin) itself. Reading it might lead to a better understanding of the technology, but it is not a lot easier to read and understand than these, from Wikipedia:

Blockchain

Bitcoin

Fun, though.

As a classroom activity it might bring enlightenment, but, I fear, mostly enlightenment about the unworkability and complication of the scheme.

But let me add something about the two ideas themselves. Bitcoin has no intrinsic value. It's imputed value comes only from its scarcity and the expense (in cpu power) of creating new ones.

On the other hand, blockchain, is a distributed ledger that can keep track of anything using an anonymous and distributed system of agreement. It doesn't depend in any way on the difficulty or expense of creating a block, though it needs a scheme to prevent forging blocks. To be true to the idea the anti-forging scheme needs to be independent of any central authority.

For grades, neither of these, independently, seems to be very desirable (or necessary), unless we are in a post apocalyptic world (Road Warrior movie for example) in which there are no central authorities, having all been destroyed, and no centralized way to verify historical records.

However, a few words about bitcoin and similar things as they have worked out in the real world are in order.

Since it has become difficult to generate new bitcoin, two things have happened. Mining rigs are using up a significant amount of energy - and likely generating a significant amount of carbon dioxide. One estimate of the energy used is approximately that of the nation of Ireland. The other is that these rigs and the energy are expensive, so many internet attacks are now done to install bitcoin miners on other people's systems so that they can bear the cost without benefit.

The bitcoin market has also proven to be very volatile. Fortunes have been made (by the early investors/miners) and lost (those who believe the hype). That makes it remarkably similar to a Ponzi Scheme.


Online classes: Any good ways to avoid having too many interruptions but at the same time not leaving anyone behind?

If you go through your lectures, you'll find most of the them actually cover between 3 and 6 separate distinct topics. We can take advantage of this to improve online delivery. Well before an online class meeting, look at your notes and identify those topic areas. Now instead of one meeting, think in terms of a separate session (usually 10 minutes or less) for each of those shorter topic areas.

Even better, you can almost always find good content freely available online that will cover those topics. Where finding a single replacement for the complete lecture would not have been possible, the smaller topics will each likely have a good option or two available. This online content will often be produced, in that it has good lighting, supporting animations, edited closed captions, etc. If you define the topic narrowly enough, this often even holds for upper-level undegrad work (graduate coursework may be different).

Now you can assign these videos as prerequisites for your class meeting (often with a very short and low-value quiz, just to provide the extra incentive for students to complete this work). You may still need to cover one or two of your original topics personally, but finding the videos is often much less work than creating or delivering your own.

This now lets you change how the conference session is run, whether on Zoom, Hangouts, Teams, Skype, WebEx, BBB, BlueJeans, or whatever. Lecture content is now much shorter, if it happens at all, and therefore less susceptible to these interruptions. Instead, these meetings are about handling class business: introducing homework, setting expectations, providing review material and guides, helping students understand where to pay the most attention in the outside material, and answering questions... you know, the kind of question that would have been an interruption before. It's now part of the primary purpose of the session.

Pedagogically this is called a flipped classroom approach, and it has a number of documented benefits outside or our current situation: Students learn better with the shorter 10 minute sessions, they have the original lecture material for review, they can catch up much easier for missed class times, they can use their video player to slow down or speed up delivery, or pause to take notes without disrupting other students, and it increases student access to the instructor.


Avoiding difficulties when teaching with metaphors

I love to make jokes and allusions. Here are some examples of ways I handle my increasing age difference from my students:

Explaining the reference

When describing how assembly language programmers compete to shave instructions off an operation (such as calculating absolute value), I tell students about the old game show Name That Tune and sometimes even show them a clip.

Challenging students to recognize the allusion

After teaching students about big-endian and little-endian, I ask if anyone recognizes where the references is from. If a student successfully guesses Gulliver's Travels (from the terms or from the images I include), they get a prize. If not, I explain.

Learning students' culture

As a sample app from my mobile development course (to demonstrate design docs), I designed a variant on Pokemon Go where students get and evolve professors by meeting with them. I paid someone on Fiverr to create Pokemon-like images of me.

Create memes

Students seem to enjoy memes. Here are some that I've created.

This one is about L2 caches: