The importance of writing understandable code

There are a ton of blog posts and several books on the topic of readable code, containing far more eloquent and complete arguments than one can make here (or that I could come up with myself). Depending on their level it's well worth sharing some extracts of well-written texts directly to show the importance of understandable code.

The most fundamental reasoning behind readable code is that people need to read code, not just computers. Or like @ben-i says here:

  First, right from the beginning, and repeatedly, I talk about the
  two audiences for code: the computer and people. These two
  audiences have completely different needs. I come back to this theme
  with every new structure that I talk about, discussing coding style
  and norms with if statements, variable declarations (naming
  conventions), for loops (hey, why do we avoid break statements?), etc.

Novice programmers typically give their total focus to getting code to do what they want: make it compile and then give the right output. That's really hard when you're starting out, and it's understandable that they give 'working' priority over any other qualities like 'readability'. As they mature, programmers learn that making some code work isn't the only goal. Once you can write code that works you realise there are other things to achieve too, which is where all other sorts of software engineering practices come in.

Readability is super important because most code will be read many many times more than it will be written. I think this is the most important message to get across, and it drives all the different aspects like formatting & naming. I suggest teaching and discussing this core concept and keep coming back to it whenever talking about a new aspect.

It's one thing to get students to understand the importance, but another thing to make them bother to do it when 'getting it working' is so much more an immediate problem. To some extent that's fine, but even novice programmers should be taught the value of writing readable code because it makes their own coding easier.

I guess there's a few approaches that can be used in tandem:

Discuss why it's important. Perhaps a sports analogy: when you're starting out with [insert sport here] you just care about hitting the ball (etc). But the top sportspeople in the world spend all their time honing their technique to get better results. Writing readable code is one of the things that professional programmers spend time improving and perfecting all their careers. It makes you better. It makes you faster. It lets you achieve far greater things. It helps you work as a team.
Break down different aspects of readability and give exercises on them, the simplest being to have students write and also review code where the approach hasn't been followed at all, e.g. with indenting, bad variable naming, bad comments, etc. Get them to desk-check the execution or result of some poorly written code versus well-written code.
Have them read & discuss articles about readability & maintainability. Depending on what level the students are at they should given reading about this and discuss it in class, even just to appreciate that it's an important ongoing topic in the CS community.
Mark them down for various aspects of poor readability. Even if they just follow the rules for the benefit of marks that's better than not doing it; gets them into the practice and at some point they'll appreciate it.
Have them review other students code regularly, either in a group or individual setting.
Teach the benefit of readable code as you're writing it. Once you're writing more than a trivial piece of code you always have to re-read it and think about what's going on. It's difficult even for the original author to read poorly-written code; by following guidelines to write readable code they will actually find it easier to write code.


Teaching Arduino---but not just "monkey see monkey do"

This sounds a little bit like an X-Y problem. When you're using micro controllers in a computer science class, what is it that you're trying to teach? How to write a for/while loop to satisfy an abstract line of pseudo-code, or the joy of making yourself something that previously you have only seen as an expensive gimmick in a shop?

I think there are similarities in science practicals. There, there is a precise script to follow, and often not much scope for 'now make up your own experiment to mix random chemicals'. What you're teaching is (a) a re-enforcement of the theoretical work through application and repetition, and (b) the practical, hands on skills of real development.

What we do in the real world (particularly in the embedded device space) really is find someone else's description of what they did, then copy it and make sure you can also get it to work. Finally, you make your own version better. Along the way, you learn lots of vitally important practical skills. Assembling the project isn't the only goal, it's almost an excuse for the activity.

Debugging is harder. The 'debug by random iteration' approach won't work.
Results are tangible - you can hold them. You can flash lights, react to stimulus, move things. This teaches students about real applications, not just web pages and databases.
MCUs are more resource constrained. You can make optimisation a necessary part of the task, not just a pointless exercise.
Each student will put their own twist on the exercise, drawing in other skills.

Picking out the current micro:bit ideas on twitter:

Robot Football
NeoPixel Clock
An optical indicator for a S/W project (I think, was a bit unclear)
Arcade game on a 5x5 display

If I'm interviewing, I can ask about one of these projects, what was hard, what was interesting, what comes next. That tells me something about a candidate that no 20 minute coding test will. All of these projects would take any of us here some time to complete too.

If I gave you an arduino and a kit of hardware, I'd say 'do the blink LED exercise first', to make sure you know how things behave when they work. Then a few more simple follow on activities. Jumping straight in at the deep end is too big a step - we set up commercial products just the same too, with easy step-by-step instructions (plus videos). People still come back with questions - our first question is always 'does binky work?'


I think the "peanut butter jelly sandwich challenge" is a great lesson in general, but it's especially great for computer science. Kudos.

That being said, I think you might be conflating two separate topics that are each worth their own lessons:

The exactness of syntax: take rightHand plate and take plate rightHand are two different things, and a computer might not be able to understand what you mean.
The exactness of semantics: take plate rightHand might sound like an obvious instruction to a human, but that's because we've had years of practice picking up plates with our hands. But a computer hasn't had that practice! What if it tries to pick up the plate with a fist? What if it tries to grab a plate by the middle instead of by the edge? So often our instructions to a computer have to be much more detailed than we first thought.

The "semantic exactness" part is the real beauty of the peanut butter jelly sandwich challenge, imho. One of the hardest things to do in computer science is take things that humans "just do" and break them down into individual steps. If they continue exploring CS, your students will eventually have to ask questions like "how would I sort a stack of index cards with numbers written on them?", and their initial reaction will be "I don't know, I just do it!". The peanut butter jelly sandwich challenge teaches them to dig a little deeper than that first reaction, and to start breaking things down into smaller steps.

And the fun part is that no matter how exact students make their instructions, you can always find a way to get it wrong.

Anyway, back to your actual question: I would propose a three-part lesson:

Step one: Have students come up with "programs" that they enter into your engine. This might be a homework assignment. This teaches them the "syntactic exactness" part, and gets them thinking about breaking things down into smaller steps.
Step two: In class, have students volunteer to read off their programs. You follow their instructions, pointing out as many inconsistensies as you want, in as messy a way as you want. After a few examples, take a step back and give them the lesson that even if your syntax is valid, sometimes your semantics can be unclear. Then maybe have them abandon your syntax and give you instructions in English, that way they can be more specific about each step. But like I said before, no matter how exact their instructions are, you can still find a way to get it wrong.
Step three: After a few rounds of this, have students break off into pairs: one student giving instructions, one following them and getting it wrong in the same way you did. Whether you give them real ingredients or tell them to pretend they have real ingredients is up to you and how much of a mess you want to clean up afterwards.


This is not an answer.

I see what you mean, looking at: https://www.ets.org/s/praxis/pdf/5651.pdf

They have an example:

// precondition 1: A is an array
// precondition 2: The length of array A is n.

but then they have a for loop over the array that looks very c like:

for (int j=1; j<= n-1; j = j + 1)

then they assign

int temp = A[j]

Now if I assume this is C-like, I just skipped the first element, if I assume this is Pascal-like, then I have the first element.

So this can be difficult to wrap your head around when you are in an exam situation.  It does seem that they are trying very hard not to trick you, using the comments and such.  But it would be pretty easy to ask, "Does this function correctly caclulate..." and then give you options of (A) Yes, (B) Errors and you really have to look around for how this thing is supposed to work in the first place.

I also can say that it is a little bit annoying to have to wonder if they are going to use other strange nomenclature for other functions in the code, for example how do they do exponents? (x^2, or something else?), how about mod?  I'm sure there are more things to worry about.

Good luck!


Why did the percentage of CS bachelor's degrees going to women peak in 1984?

Obviously, there is no way to definitively know the answer to this question.  But my favorite theory has to do with the advent of the home PC, and the original marketing of computer games to boys.  The strongest support for this theory is the timing, which means that I must now give the obligatory caveat that correlation is not causation.

Basically, the theory goes like this: as the home PC started to sell, the good folks in marketing had to choose which groups they would target with their limited ad dollars.  The earliest games that came out involved balls and shooting anyway, so young boys were chosen as the target market.  And thus began a generation of young boys who logged hundreds or thousands of hours with computers, with no corresponding boost for the girls.

As this generation of children reached university age, more boys signed up for computing majors, and professors began to tailor their classes towards this majority of people who already had some background.  Girls who did come in often felt like fish out of water (and abandoned the major), leaving us where we are today.

It does not have to be so.  There are inroads being made into this problem, and I am hopeful that with the total infusion of computers into all of our lives that is going on now, the timing is right for this problem to begin to fix itself, as the experience differential has begun to level out.


What's a good example of a static factory method returning instances of subclasses?

I don't have a good answer to this. However here are my thoughts.
Named constructors
A good use for static factory, is to implement named constructors: Java, C#, C++, et al do not have named constructors. However named constructors can be useful, as they allow you to document different ways of constructing an object. Therefore use a static factory, to create the object. The static factory will use private un-named constructors.
Problems with the pattern
However other uses of static factory seem to be an anti-pattern.
You now have a super-class depend on the sub-class. The sub-class already depends on the super-class.
The static constructor can also easily break the single responsibility principle: the class is a thing and a factory for a thing.


Opportunities for Interdepartmental Collaboration

Some ideas to ruminate on.

With you as the guest in another department, thoughts are:

$\LaTeX$ presented to a writing class, preferably one where they've already had to submit three or more papers that were graded on presentation as well as English usage
Web design (for portfolio usage maybe) to any arts or photography class
Mathematica, if available, to any advanced mathematics or lab sciences class
SQL (any flavor) to any business-related classes, if any exist at your school

At these engagements you can show how the program can be used in real-world application to what they are learning, and/or be useful to them in their class now. Best of breed for that would be the use of $\LaTeX$ for the writing class - freeing them from formatting and presentation details to work on their writing skills

As a guest in the computer class, you could look for any instructors that rely on computer programs in their course material. Especially useful would be any that employ a program that is Free/OpenSource software. (If it is hosted on GitHub where they can also look at, that's even better.) A good candidate might be an art class that uses GIMP.

If you find a significant portion of your students have a common interest in another field, you could engage that department for a collaborator who can show how the computer is used in their field, even if it's not applied in the classroom itself. (Of course that could also include teaching those instructors as well, so that they are in a position to understand the tools at least as well and the students they teach.)

Lastly, to get things rolling, you could offer to do a session or two in another class to teach their students extra features of the Office software that they use, if any, with the students. Lab science classes probably need at least Excel for processing and presenting measurement data from experiments.

The first set of ideas is to present how the use of computers can help them now with their classwork. The second set is to show your students the application of what they are learning in your class to things they already know, or will be taking soon. The third set of ideas shows how computers are being used in the work-a-day world to make things easier, or better, in the field they are really interested in. The final idea is a method of beginning the idea of collaboration in your school before the other instructors realize it's even possible.


Will I Regret Using Python As A Teaching Language When I Later Need to Teach Static Typing?

If you teach Python's typing system correctly, you should have no problem later. The rule in Python is that names don't have a type associated with them, but all values do. It isn't that "things" change type. They don't. Objects and other values have a well determined type when they are created and that type never changes. Names never have a type to be changed. But any name can be associated with any value.

When you move to a language that requires explicitly applying a type to names (Java, say), then you just need to teach them that names are given types also, as a sort of redundancy so that errors can be caught earlier (compiler v run-time). A name associated with a type can only refer to a value that has that type.

Applying types to names (as well as values) isn't really that big a deal, and the students will be more sophisticated when you get to it.

However, they may not like having to explicitly apply types to names. But that is a different issue. The reason given above will be enough for many of them.

Finding errors early is a big win in programming. If you take that attitude when teaching Python you will stress things like early testing (preferably test-first programming) so that errors show up soonest.

For the distinction between a "thing" and a "name applied to a thing" it is often instructive and always fun to return to Haddock's Eyes. Lewis Carroll was more interested in mathematics, of course, but the ideas apply equally well to CS.

Don't confuse "typing" as hitting keys on a keyboard with "typing" as applying a type to a name or value. It may be that the first version of this was confusing in that regard. Here "typing" means only the latter.


You might want to explore CS Unplugged for use with any youngster. While it doesn't use programming, it provides some foundation in computational thinking and provides some metaphors, etc, that might be useful to learning even in an environment where the student is learning to program.
I don't think it is necessary to do everything in the CS Unplugged curriculum prior to starting programming. And you might not want to use any of it explicitly, but it is worth the effort for an inexperienced teacher to explore this at least.


Which are common misconceptions about code execution? How to efficiently debug my student?

I may add to this as ideas occur to me, but here is a starter version.

You don't state the general academic level of the student, so I'll assume secondary school or beginning university. The student has studied Algebra at least and has some background in math.

The second really big misconception is that a program is just like math. In particular, in C, the misconception that a statement like

  x = y + 1;

is an equation to be solved, rather than an operation to be performed. But this is based on the first misconception that a "variable" in algebra is the same sort of thing as a "variable" in programming (in C like languages). In fact, in algebra, a variable doesn't vary, it is a fixed but possibly undetermined value. In C, the value can vary. In algebra, the above represents a relationship. In programming it is an operation. So, first, solve those two possible misconceptions with examples, exercises, and explanations as necessary. Once you do that ++y makes some sense as an operation.

The third big misconception is just that a computer executes an algorithm, which is a sequential execution of defined steps. The program counter, PC, keeps track of the "current state" of the algorithm. In the while loop, the test only gets executed when the PC comes to it in an unrolling of the loop into a sequence of operations.

My personal preference is to teach "variables" as "references to values" not as contents of memory locations. So

  x = 5;

means that x refers to 5, not that it is 5. Then you avoid the problem that if the next statement is

  x = x + 1;

that the student thinks that five has magically become six. It is just that now x refers to a different value.

Caveats.

Note that I'm assuming C-like languages. In lisp-like languages algebra variables and lisp "variables" are actually the same - undetermined/unspecified but immutable values. Also in Fortran IV, you could actually make five magically turn into six. History lesson there, though.

And, of course, modern high performance computers aren't strictly sequential anymore, with speculative execution at branch points.

In fact, with a bit of finesse you can discuss a C program with no reference to any actual machine at all. It defines an algorithm. Full Stop. The finesse part is just about the PC mentioned earlier.


Explaining why styling should not be done directly in HTML

I like the idea of producing a few style sheets, and having the pupils apply them to their HTML. They can then see the power of having separate style sheets.

Start with a style sheet that you made. Use the new grid layout, have some college styling. But at first get them only creating the html.

They can then start editing the style sheets. They will see that the power of one small change can change every heading, or every paragraph.

I have also in the past, written a HTML file that had a set of buttons at the bottom. These buttons would trigger a different CSS file to be loaded. It was some very simple JavaScript.

To answer should they be kept separate

Keeping style and content separate, is recommended by W3 and many others. It implements separation of concerns and single responsibility. Both very important patterns in software design.

Even better: keep layout, style, structure, and content separate.

One css for layout, another for style, then a template for structure (I use moustache), pull the content from a database, to create json, and programmatically combine it with the template (use a template library). [this section is now about my teaching, but what I do for my websites.]

To answer should you devote a lesson to separate CSS files.

Yes. If it is important to keep these separate, which it is, then you should teach pupils to keep them separate. Save time by not teaching them to mix it in with the HTML (This will save time twice, as you won't have to un-teach it).

I have only done this with one or two people (not a class).


What is a good design for a Capstone Course in CS?

Personally, I'm a believer in a project based capstone and a group one at that.

The project should involve going from generating (and pitching) an idea through design, development and ultimately delivery and should require integrating multiple tools.

Since many kids would want to use such a course as preparation for internships and jobs, I'd say it's more appropriate to take in the junior rather than senior year. That's ok though since you're done with most if not all core major requirements by then and are taking electives.

I know taking a capstone prior to the senior year sounds wrong to some but it should show mastery of many if not all of the core concepts in a typical CS major and fill a big hole in a students development.


REPL environment for teacher assignments

I have been teaching with Cocalc for a few years. It has most of the features you are looking for, but unless you are using python with nbgrader there is perhaps not much support for unit tests/autograding. It's not perfect but it gets the job done, with less frustration to me than trying to grade this stuff in Canvas. Also, I can rely on the simplicity of identical environments, no more babysitting each student's installation and worrying about Windows vs Mac setup, etc.
Cocalc allows the creation of "courses" where each student can receive "Assignments" and "Handouts" from the instructor. The students' projects are self-contained VMs and you can do a bit of central administration on them. They can use free ones, or upgrade for a small fee. You can do some LMS-type things there too, such as grade and comment on returned work. Here's a link to the Teaching documentation. There are a good amount of videos and blog posts put up by other enthusiasts as well.


OBS Studio fills your description.
It is not the easiest program to use, but you can find plenty of tutorials on YouTube.
While rewinding the recording again might seem appealing, it is very common to find out more errors after you complete the recording. In that case, you need a better video editor. OBS studio might be enough, but shotcut is your best bet.


One strategy that's sort of similar to the "embrace" strategy described in the other answers is "acknowledge" -- not only do you explore the quirk, you explicitly acknowledge that it's a flaw or mistake in the language.

After all, languages are designed by humans, and humans are ultimately fallible creatures: I think it's ok to acknowledge in some cases that the language designers messed up, or were working under assumptions and constraints that are no longer relevant today. This lets you work in teaching moments about:

The importance of planning and the realities of software maintenance/backwards compatibility
The fact that everybody makes mistakes and its ok
Demonstrate what balanced technical criticism looks like (as opposed to the annoying sort of "language fanboyism" some students seem to pick up)

You can then amp back up the enthusiasm after you've moved past the quirk and returned to the actual content to help emphasize what you ultimately think is important and worth focusing on.

To return back to your original question, I think whether or not you actually discuss quirks or brush over them depends on to what degree the quirks impact your students' ability to successfully write code.

For example, take the a == b vs a === b thing in JavaScript. I would argue that sort of quirk is ultimately irrelevant in the grand scheme of things: the "always use a === b" rule is almost always what you want, so I would probably spend only a minute or so talking about the quirk (I'd probably spend most of that minute cracking jokes about JS, honestly), finish by mandating students must always use a === b, then move on.

In other cases, trying to paper over or ignore quirks would be irresponsible. One example of this might be JavaScript's Byzantium rules on how exactly the this keyword is scoped. This issue actually does come up fairly frequently in practice (especially once you start mixing together object-oriented and functional style code), so is something you probably do actually need to cover in some detail -- at the very least, you need to give students a good set of rules of thumb they can apply.

Another example might be a == b vs a.equals(b) in Java -- this distinction strikes at the core of several fundamental Java topics and so must probably be taught in detail at some point.

There are unfortunately some quirks that fall into a middle ground: not so easily brushed aside, but not really worth spending time explaining (for example, the broken interaction between Java arrays and generics). In those cases, it might be worth just engineering your homework assignments so students simply never run into those quirks, or just writing that portion of the assignment for them, with comments for the curious.


How to Design Programs is released under the MIT license, and has the distinct advantage of being integrated directly into DrRacket.  This allows you to work through bite-sized chunks of Scheme, and gives you an easy tutorial-style way to follow the textbook as you explore the language.

Within DrRacket, go to the Language Menu, and the Teaching Languages are in there.  They each reflect portions of How to Design Programs.  The instructions for utilizing the Teaching Languages are contained in the preface to the book.


Could you recommend books on concurrent programming?

Concurrent programming is easy, synchronisation is hard.
Have a look at this video for an alternative to synchronisation: https://www.youtube.com/watch?v=2yXtZ8x7TXw
When you have to synchronize
Use easy (High level) synchronization. see:

Scoop from Eiffel.
Transactions
Pipelines / message passing
coroutines (for when you don't need parallelisation)

See also no lock / zero lock structures: Most pipes that are thread safe use locking. Or are not thread safe, and expect the user to do the locking. However it is possible to get thread safe zero lock queues. There rely on a few atomic instructions. (I prefer the name minimal lock, because the atomic instructions do locking).
Only use low-level synchronization to implement high-level synchronisation.
If you need synchronisation, and if you do not have high-level synchronisation, then find a good library that implements high-level synchronisation, using the existing low-level synchronisation.
Don't write it your self, except as an exercise (and do to it as an exercise, it is fun and you will learn a lot), as it is very hard and you will get it wrong.


Real world example application built with Python and JavaScript?

I have just written myself a web-mark server, to store book marks to my website. I got fed up with the proprietary ones, and decided to make one of my own (probably could have found a ready made one with a Free Software Licence).
It used Couchdb. This involves writing code in Java-script (the manual says that the server side code can also be written in python, I chose JavaScript, so it would help be learn it), but because it provides the framework, you write lots of small functions. You will also end up learning about the no-sql db couchdb, http, and client side web design (html, css, Java-Script). I used jquery and knockout.js on the client side.
First things first
Because I did not follow a tutorial, I ended up looking stuff up as I went. This would probably be to effort-full, if it was your first language, as you would be looking up everything, and not know what to look up (how can you look up how to do a foreach in java-script, if you have not yet heard of a foreach.
Therefore it would be beneficial to find a tutorial to do first, then work on a project.
You can also work on an existing project. There are many Free Software (Open Source) project that you could help with. It is much easier to contribute to an existing project, that to start from scratch. If you want you can contribute to my bookmark project. (If you do work on someone else's project, and it if for an assessment, then ensure that you tell the assessor what bits you worked on).
Learning two languages at a time may make things confusing, and make it take longer to learn. However research into natural languages shows that, for babies and infants, learning two or more languages at a time has a positive long term affect. Though it does slow externally measurable performance at first. For these children the languages are in different contexts, one for each parent, or one at home / one at school. I would suggest that you focus on one language, until you get sufficiently skilled.
Python seems to be widely used as a teaching language (1st scratch, then python). JavaScript has may pitfalls. A good language to learn Object Oriented is Eiffel. However you could learn, non-OO first (OO just adds to structured, most modern languages are structured or structured+OO). Therefore, if you have not used scratch, then have a play with it, then start on python.
Other project Ideas — python

Unix command line tools: rewrite some of the Unix tools (I did this in C in 1st year at university).
Create a web-server: there a libraries in python.
Something with a Raspberry-Pi: these thinks have connectors to add some sensors and output devices (barcode scanner, rfid reader, LEDs, motors, relays, buttons, …). They also run Debian Gnu/Linux ( Gnu/Linux runs on 490 of the top 500 super computers (the other 10 are other Unixes), ⅔ of web servers, most of the internet infrastructure, and a lot of inbedded systems.
A game: 2D (the SDL library is very good), or text adventure / interactive fiction.


How to make term reports, easy to do (and secondly effective, and accurate)

I've always admired the Swiss' education system of teaching kids where they rarely have examinations, but rather through constructive assignments and homeworks to teach students. At a conference I've attended, I heard a quick introduction on gamification of education and I am trying this out with some students.

Here is what I proposed:
Assesments (excluding exams and final project, due to curriculum and school board constraints) have unlimited re-tests, limited to once a week.
0.5 credit is awarded for 50%+ and 1.0 credit is awarded for 80%+
At the end of the term, their number of credit earned is divded by total number of credits for a "term work" grade worth x% of their final mark
The goal here is for students to not worry about a 50, 60, 70, 80, 90 or 100, but rather track their progress through completion of content. I believe the unlimited retries gives incentive for students who are falling behind to realize early and catch up immediately, rather than later. This is to avoid the mentality of giving up because it is "too late" or "wait for next test".
 To some degree, I believe in the innate competitive nature of CS students transferred from love for gaming

I believe this method (with modification to suit your needs) meets what you are looking for.
Accurate enough to give a % mark because you track progression. Although I foresee multiple 100% with this method
Does not disturb students because they are well aware of their progress, and know they can make improvements rather than blankly stare at an unfortunate poor test 1
Quick and low effort - I just use an excel macro and export to show my class after each week their progress


Image compression, for example sending back photos from faraway in space and through narrow communications, is interesting because it gives visual scene of the work done. You can compress the individual pixels to a range of bit-depths, from 2/4/8... 32 bits, you can compress 2 bits inside 8 bit registers of a PC which often reads and writes memory blocks of 8/16 bits. It's very good to have a thorough understanding of XY color graphs.

The concept of images also leads to the topic of floodfill, and recursive searching of black and white pixels, and recursion generates 100mb or 1gb, which leads to the concepts of stack overflows from disorganized memory. Students therefore learn to keep 2D and 3D arrays for pixels and voxels. If they do 3D arrays to compress data in, they are building a minecraft world.

Voxels are stacks of XY graphs, on a Z axis, so videos are actually voxels, using XY and Time, most work done on 2D graphs alot easier and smaller, and also very similar to 3D graphs.

In a minecraft world you are introducing the kids to lots of 3D concepts, and the limitations of bandwidth every frame to and from the graphics cards, and overall memory limitations. a voxel engine has to be very optimized to get around those.

I recently used 3D arrays to solve floodfill recursive algorithms so that they take up 100 times less space than line-scanning floodfils and I found it mentally very engageing. A voxel space can take up a billion memory spaces very fast, 1000x1000x1000 points of space, which requires a lot of bandwidth optimizing.

When you have objects in a voxel space, and you find the edge voxels of the shape, you can generate a point cloud, which is useful too. Point clouds use huge amounts of data, and they represent visible shapes. Being able to organize algorithms in point clouds requires a lot of organization, it leads to the concepts of Octrees and nearest neighbor algorythms.


What would be a good project for teaching big program concepts?

You're definitely on the right track with your project scope but high school students can pay attention to large scale text based games.  I have had great success having them implement Blackjack.  This project is large by nature but you can place restrictions on how they solve the problem.  I've found that using three classes helps cut down on confusion.

The card class creates a single card object for use in the deck class
The deck class creates a deck of 52 cards made of card objects, also includes a shuffle and dealTopCard method
The hand class lets them actually deal a hand to themselves and play against a simple computer (the AI is simple to program)

I give this problem to AP CSA students in two parts, the deck and card classes with methods, and the hand class with functional game parts.
For higher level students, I give an open ended problem to algorithms & data structures kids where they need to write an algorithm that will procedurally generate a solvable (and interesting) puzzle.  It forces them to do their own research while implementing core functionality to a game.  Typically slide puzzles work well because they can be represented in a 2d array.
Middle School students tend to lack the attention to work on and understand a large and complex program.  Drawing an animal with Python turtles or something similar can be a good way to show how quickly bad code can get out of hand.  Just mentioning Discord bot is a good way to grab attention.  Going through the steps of creating a bot that does something even as simple as outputting a link by chat command goes over very well.
I have plenty more examples but as a general rule, the more "out there" the program while having clearly defined instructions, the better it holds high school student's attention.


Here is my system.  I give it top marks for ease of sharing, but one downside is that it does not do any kind of autograding without some scripting on my part.

I purchased a paid subscription to Dropbox.  This allows me to set up read-only folders.  At the beginning of the term, I copy/paste all of the names from the course into an Excel spreadsheet and collect an email address from every student for a Dropbox.

I then create a series of folders using a .bat file (I am a Windows user), generated with a function like ="mkdir ""APCS 1 - "&A2&", "&B2&"""".  This creates lines like mkdir "APCS 1 - Johnson, Cathy" I copy and paste this group into a .txt file, rename it to .bat, and - voilà! - I can double-click to create a directory for every student in my class section.  I run the batch file in some subdirectory of the Dropbox folder so that they will ultimately be sharable.  I then go through and share each of these folders with the respective student with write privileges.

Finally, I create one last folder, something like AP Computer Science Section 1.  I then copy and paste the email addresses themselves into the share box for this folder, but only allow read priveleges.  Now, I can drop my assignments into to class folder (which is basically instantaneous), and I receive my submissions through their private folders.  I get everything timestamped, and don't have to log into any websites to get the assignments.

One more side-benefit of this arrangement is that when I need to send a file to some student, we already have a shared folder that I can drop it into.  No need for emailed attachments.


What can the instructor do to overcome the Authenticity Bias in students?

Share their own struggles. Period. The instructor can start dispelling the myth by sharing his/her own story (replete with self-doubt, struggle, and frustration most likely) about studying computer science.

In Harvard's CS50 course, the professor shares his experience of not starting as a CS major and of essentially taking CS50 himself pass/fail. That's in the first lecture and communicates an important message about his journey not being one of simply innate talent. In another MOOC I've referenced before (Programming Languages from UW), the professor points out that he didn't write a line of code before college. As a student in each course through edX and Coursera, respectively, these small windows into the journeys of the professors has boosted my own confidence that one does not to be fluent in assembly at age 10 (exaggeration) to be a skilled programmer/computer scientist.

I share with students my own long and winding road that led me to CS. I share with them what I continue to study in my free time. I display old, poorly-written code. I recall one instance from teaching last year when I was trying to communicate to students how important it is to read program specifications and language documentation extremely carefully. From a homework assignment for Programming Languages, Part A, I kept figuratively banging my head against the desk because I was sure my logic and code were right, but I wasn't passing the checker. The problem: I was misunderstanding how a library function was working. Once I re-read the documentation and realized my error, the fix was trivial. Moments like this happen to everyone at every level of ability. Everyone struggles with something at some point.

Students need to see that the person teaching them is fallible, and that his/her knowledge has been gained through a lot of "blood, sweat, and tears," not because he/she wrote C code at age 5 (exaggeration again!) and never had a problem learning anything thereafter.

I also find some of the stories from freeCodeCamp inspiring. Their forum and Medium blog are filled with examples of individuals making career changes, working hard for an extended period of time, and achieving some level of "success."

The bottom line: find stories to share that show students there are more people feeling what they feel than they might first imagine. Prove to them that computer science rewards hard work, discipline, and focus. In my mind, that starts with the person in the front of the room sharing his/her journey.


What are the basics of CS that I should know, before I start my journey into machine learning

The first two paragraphs of the Wikipedia article on Machine Learning will give you a good outline of the things you need to know. Algorithms and Data Structures are key from CS, but you also need quite a lot of things like Statistics, Mathematics, Pattern Recognition and such.

It is a pretty long road if you start out only knowing how to program. It is also a field with a lot of current activity and a lot will change before you get very far along that road. It is good to have a goal, but if you start late in a hot area you need to keep a flexible outlook so that you have options if that field cools off while you study. But those same things needed for ML are also good for other things as well.

So, the courses you mention probably aren't especially necessary but your statement that you have trouble with documentation is a bit worrying. Perhaps that will change with practice.

If you are a young person starting out, don't commit too deeply to any one path. Learn the basics so that you can choose later when you know more, both about yourself and about the state of research at that time.


How bad is a Computer Science course that doesn't teach Design Patterns?

There is more to a CS degree than programming and more to programming than Design Patterns. I'm actually an expert in such things and have designed and published a few as a committed member of the patterns community. If I were teaching you programming in some object-oriented language you would certainly learn about and use many such patterns, but you might never hear the names, just the usage as good ways to write programs in a certain set of languages.

However, I have a friend, also in the community, who is well known and has designed many things fundamental to areas of programming languages who doesn't use the standard design patterns you are probably thinking of at all. The reason is that he programs in LISP and CLOS, not Java and C++. His informed opinion about the design patterns is that they are merely corrections for flaws in certain languages, primarily C++. Many of the kinds of things that design patterns accomplish in C++ are done in more natural ways within Common Lisp itself without needing any such mental tricks.

So, it may well be that your curriculum is flawed, but not teaching the patters in the Gang of Four book is not the only indicator. (Some of those authors are friends of mine, in fact).

Moreover, there is more (much more) to CS than programming. Have you learned data structures and algorithms? Have you learned architecture and databases? Have you learned data communications and concurrency? Have you learned to work in teams on large projects? Have you learned to think abstractly and to decompose problems and compose solutions? Those are vitally important too.


How to introduce Kotlin in a Programming Languages course

I think the answer to that depends on how you're structuring the course overall, and what Kotlin brings to the teaching of those ideas.  I know of three distinct approaches to an upper-division PL course:  the "paradigms" curriculum (à la Sebesta's book), the "interperter/design space" curriculum (EOPL, Scott's "Programming Language Pragmatics", Louden, Turbak/Gifford/Sheldon, etc.), and the hybrid theory/implementation curricula (less common and few things in print: the Racket team, Norman Ramsey's adaptation-in-progress of Samuael Kamin's book).

Do any of these describe what you're doing with your course?  What is it that Kotlin brings to the class that is not already represented by the other three functional languages your students have learned?


Is there a free platform to host coding challenges within a class?

It doesn't do ranking in any manner, but CodingBat permits you to create challenges with tests for your class in either Python or Java.

While the interface begins assuming that you will have one method, you can add as many methods as you wish.  However, you are limited to one class (so no inner classes), and you are forbidden Exceptions, so the projects would have to be fairly small in scope.


What is the difference between computer science and computer engineering in brief

I think you're still slightly confused yourself, actually.  All of the fields below have a great deal of overlap because they are in similar parts of the world

Computer Science: Computer Science is the broad study of computational systems, which can be a little frustrating, because people often use the term to describe some specific subset.  If you major in "computer science" at a university, it is not at all clear what you will be studying after a few intro courses until you inspect the curriculum. It is perfectly possible to get a CS degree without studying almost any content from the other fields outlined below. However, all of those terms could possibly be called "computer science" depending on the context.

I (and some others) hold that Computer Science is purely the branch of mathematics that deals with computation. Some people try to keep things less ambiguous by adding the word theoretical before CS to indicate the mathematical field, but this is not always the case. (Take a look at the Computer Science Stackexchange to get a sense of what I would term "CS".)

Software Engineering: The art and science of creating good software.

Information Technology: The field concerned with the hardware and software infrastructure that manages networks and data.

Computer Engineering: a field that mixes Electrical Engineering with Software Engineering.

Mechatronics: a field that combines Computer Engineering with mechanical engineering.


Should unit testing be taught in introductory programming classes?

I'll assume that you mean a first programming course that uses a language (Java...) that has well integrated testing tools.

If you just use unit testing as an add-on then I'd guess the proper answer is no. There are other things the student could be doing.

However, if you are willing and able to modify your teaching a bit then unit testing can be a big win. I've used it in teaching introductory programming to adults for years (since back when Extreme Programming was young).

I do two things. First, I give out assignments differently at the beginning. Rather than giving students a narrative to describe a programming exercise or project, in which they must first decompose the description into tasks, I give them the task list itself. In Agile Programming language, I give them a small product backlog or story-card deck. The tasks are numbered in a logical (do this first) order so that when the backlog is completed the project is done.

Therefore I'm using a bit more than just unit testing. Other "personal" agile programming practices are employed, including pair programming. I also act at the student's Customer, answering questions as needed.

The second thing I do: On the first day of class I do a demo project in public. I start with a small number of "stories"; tasks that decompose a simple project. I pick out a student (volunteer or other) and we pair program on a laptop connected to a projector so all can watch. I start out as the "driver" with control of the keyboard and my student is the "navigator". He or she may know nothing of programming, or very little. We look at the first story, discuss it a bit to get a "picture"/analogy/metaphor. I then fire up Eclipse, start a new project add JUnit to the project and write a test for just that one card. It fails of course. So then we (my nav and I) write app code to make that test pass. Repeat. At some  point we switch roles and the student becomes driver and I act as a very helpful navigator. If the class isn't too large you can also open "navigation" (comments, questions,...) to the class as a whole, to get them used to the process of aiding the driver.

Along the way I discuss what we are doing at each step (go "meta"). This can take up much of the period, but if you have enough time you can distribute the code you've done to the class. They can pair and work on the next story as you wander about giving help.

So, they see unit testing and pair programming and build on the test-first philosophy in an integrated way.

Another thing, that works well with this is that, when you assign them a project, you can give out a unit test suite along with the product backlog. In other words, you write the unit tests and they make them pass. The down side of this, however, is that the tests contain identifiers from the app (class and method names for example). In the big picture, the test suite is your low-level design space where you decide on such things. If you write a test for the "increment" method, you will normally do it before you even have a stub for the method. In writing the tests you discover the name as well as the args it should have and its return type. If you give the tests initially you have already done this step and so need to teach it a bit later. Maybe by the 3rd exercise.


Teaching C#, Java, etc. to students who are bad at OOP

I know exactly what you are talking about. Back when I was still ( I am glad I am no longer doing that) working as a faculty in a university, I ran into situations like this. In fact, with my usual style, I got confrontational with the faculty who was supposed to teach OOP in the previous semester and stuff happened.

Here is what I did.

First up, the logistics. I had a detailed discussion with the HOD and also with the students, and convinced all of them to come for additional classes (I called them Bootcamps)
The Bootcamp was a 2 day affair ( 6 hours each ) and was held on a holiday. No attendance or anything like that. Students who are serious can come (and 80 % of the class showed up)
Taught the basics of OOPS. I essentially summarised the entire semester worth of contents into 12 hours.

Did this work? For me, it did. I was able to carry on with my usual syllabus with confidence that they are at least, not as blind as before. sure, I had to spend 2 of my personal days, but it was worth it.

Here are the things I crunched on those 2 days.

Classes and Objects (and the interconnection between, and compared them favourably with structs)
Encapsulation (especially private and public and why this is important)
Inheritance (the big boss of OOP, and by far the most important thing about any OOP language)
Polymorphism (although this was pretty straightforward and did not drive people crazy like inheritance or the initial discussion of classes and objects)

So, talking from first experience, the situation you described is the norm rather than the exception. If you want to get them up to speed, I suggest a bootcamp or a similar variation.


Why would mutation be considered by some as a difficult concept to grasp?

I personally teach mutation almost immediately.  However, I agree with Buffy that more difficult is not really the metric people are using to decide to teach mutation later.  It is about giving certain key habits a chance to grow and develop before you get there.

Most people find recursion naturally more difficult than a loop.  There is no reason why this must be, and folks who learned recursion first will often find the difficult one to be the standard imperative loop.  If you begin a student in a programming world without mutability, what habits will grow?

Certainly recursion will come quite naturally.  So will linked lists and trees.  And certain sloppy habits will be naturally avoided, such as this balderdash:

System.out.println("You found " + hotdogs + "hotdogs!");
System.out.println("How many glasses of water will you drink?");
hotdogs = myScan.nextInt();

Ultimately, there is a deeper philosophical statement being made by the instructor about which habits they would like to inculcate and foster at the very root of their students' thinking.  These patterns of thought, it is presumed, will modify the initial ways that the students approach problems even later in life.

I do not know of any research that backs this up, but, of course, much of what we try to impart to our students is not from research, but from intuition. And, who knows?  They might be right about this one.


What autograding software do folks use for Java code?

For simple stuff I've used CodingBat. They've got an authoring system buried on the site. It's not terribly difficult to create your own questions, although the instructions are pretty wordy.

When you create a problem there are a set of fields to fill in. I'd attach a screenshot, but the network I'm on blocks imgur. I'll try to come back and add an image later.

doc

This is the instructions that your students will read.

hint

If you want your students to have the hint button, add some text

cases

List as many test cases as you want. Separate each parameter that you want to send into the method you're testing with a comma. The expected answer comes at the end.

It looks like this for the method below. 123 goes into sumEvenDigits as n and then 2 is the expected answer.

123,2
2006,8

code
Starter code for your students.

public int sumEvenDigits(int n) {

}

tags
Let's you put questions into categories, specify language, and set a difficulty.


Best Practices / Effective Strategies For Building Diversity In High School CS Programs

Three concrete ideas come to mind based on my experience building a CS program essentially from scratch at the high school level:

Have at least one class that has no pre-requisite. We have one intro to programming course that any student can register for, including freshmen. Students don't need any background, any strength in math, any previous AP/Honors/accelerated classes. Part of the battle -- maybe the hardest part -- is getting bodies into the seats, and then winning them over from there. Eliminating hurdles as much as possible is one logical step to take.

Trust word of mouth. I made it my goal to get in front of every possible applicant when promoting our first year of offering AP CS Principles (2016-17). A year ago, I visited math classes and spoke to probably ~700-800 students before course registration. As a result, I received nearly 150 applications. In previous years we could barely muster one full section of AP CS A. If >20 students showed interest in CS, we were doing well. I believe firmly in the Field of Dreams philosophy: "If you build it, they will come." Even 5 minutes of enthusiasm was enough to spark a massive up-tick in interest. Last year, we had one small class of CS, this year we had three full classes, and we are expanding to four next year.

Don't let traditional grading get in the way of learning. I struggled a lot with this issue this year. I tell students bluntly that programming is hard. It can be frustrating and challenging. So, when it comes time to assessing programs, I let students revise, revise, revise. Essentially, I take a standards-based approach; I don't care so much when they learn something but that they learn it. A low grade at the beginning that is difficult to recover from can be more disheartening than anything else and can sap students of the motivation needed to persist through challenging programming work. At the start there has to be a reward for grit and the desire to improve.


Is SICP appropriate for an advanced high school CS course?

First, I love SICP. I took and later TA'd 6.001. Like many MIT grads, I tried to teach it where I became a professor, and, like most who attempted it, decided not to do so again.

The main reason it is rarely successful outside of MIT isn't the difference in student quality but the difference in the support the school can offer. If I remember correctly, at MIT, there were three lectures a week, two recitation sections, one tutorial section (approximately 4 students meeting for an hour with a graduate TA), and many staffed lab hours. A high school or small college cannot generally provide that level of support. Also, when taught outside MIT, it is usually as a junior-level course, and students still usually find it overwhelming. (An exception is UC Berkeley, which taught it successfully for many years at the freshman level.)

I am not saying a high school class could not succeed, just that it would be very difficult, and the amount of work required would be exceptional.

It might also be hard to motivate students to work so hard on something so abstract, when they could be learning app development, computer games, or another more immediately rewarding topic with less effort.

In summary, I would advise against using SICP for a class at the high school level, although I do think it is possible to supervise an independent study with a sufficiently motivated and sophisticated individual or small group of students.


Book recommendation: basic, broad and solid overview for advanced learners

It is a bit hard to capture all of that. Unfortunately*, the best book is probably The Structure and Interpretation of Computer Programs but that assumes the person is willing to do some programming.

But one can learn a lot on Paul Graham's Essay Page, just by choosing interesting titles to explore.

*Unfortunately = work involved, not just browsing.


How to help students comprehend the HTML document flow?

Absolute positioning as bad practice

Referencing the StackOverflow question, "Is it considered bad practice to use absolute positioning?", the consensus is, just like nearly everything in CSS, "it depends".

But let's just throw some data at the topic:

More than 50% of website traffic is presumed to be from a mobile
device. Using absolute positioning (especially when positioning from
body) will impact how mobile viewers see your content.
There are
literally thousands of possible combinations for screen sizes and
resolutions. Positioing absolutely will break on most viewports.

These are the two biggest reasons to rely on document flow as opposed to positioning the elements yourself. But obviously, the student(s) are trying to solve a problem they have with the hammer they have.

So, maybe instead of trying to convince them not to, show them how bad it performs under real world situations and provide some alternatives.

Define the problem

Open a browser like Chrome, and using the bottom left corner of the browser window, resize the window. Elements positioned to flow around constraints will reposition, absolute elements will not.
Also in Chrome, open the developer tools and open the "device tool bar". This will allow you to look at the page in a simulated screen resolution for a number of devices.
Visit the web page on the student's phone. Switch the phone between horizontal and vertical views.

Better Practice

Use a grid. There a number of grids available like those that come standard with Bootstrap, but sites like css-tricks.com also have a number of smaller implementations that actually describe the basics of a grid, like this nice one from Chris Coyer.
Be right on the cutting edge and teach grid layout directives that are only in draft proposal (but work in some canary browser releases) this other tutorial on the Mozilla Dev Network.
Be less on the cutting edge and teach Flex.
Introduce viewports to trigger css changes at certain screen size

After some or all of these, reflect by going through browser resizing, etc. explained above.

Some other talking points

I'm not sure what kind of project the student is creating, but some other things to consider under certain circumstances:

Their experience with x, y coordinates will help them a lot if they are doing game development or graphics within a canvas tag or creating SVGs. Discuss when those are appropriate to use in HTML (SVG icons for links under certain viewports, eg).
Discuss content visibility and re-flow on devices of different resolution. Moving or hiding information based on user context (are they on
a desktop with lots of viewable space and a mouse, or are they on an iphone 4 and just want to click the 'buy' button?).


Teaching data structures with C++: should I go with smart instead of raw pointers?

In my view, C++ isn't a toy. It is a professional language that should be approached in a professional way. With that in mind, the latest versions are a vast improvement in safety over the earlier versions.

Bjarne Stroustrup once said something like: In C you can shoot yourself in the foot. In C++ you can blow your leg off.

That said, use C++:17 or later and use smart pointers. There is no reason to teach students techniques that are considered obsolete. Find a good book that is compatible with that philosophy, not one that uses a "historical" approach. The past was left behind for a reason.

Alternatively, teach C if you want to teach lower level concepts or Java for higher ones.

I'll note that many of us had to take an historical approach to C++ since we started when it was only a preprocessor for C itself. It has come a long way since then and modern developments have made it safer.

An anecdote might be instructive. I once spent 24 hours finding an allocation bug in a C++ program. The correction required a single character change in the source. Not very productive. Smart pointers would have made such things much better. I now much prefer languages with good garbage collectors to having to solve the memory management problem again (and again) in every program.


Strachey's proof for the Halting Problem is accessible to anyone who accepts reasoning by contradiction.

See
https://academic.oup.com/comjnl/article/7/4/313/354243


latest Book (2018/19) for Computer Science for Grade 2 to 8 students

Since you are asking about a wide range of ages, let me suggest that no single book is likely to do the job for you.

Instead, let me suggest a web site CS Unplugged which uses non computer resources to teach simple concepts of CS, including Computational Thinking.

The main idea is that many things, including toys, can give youngsters appropriate metaphors that will bring them to a mindset that helps them later learn things more formally.

You can also do an online search for Computational Thinking, which will reveal a large number of resources, some (not all) of which will be appropriate for you.

I wouldn't try at this level, to focus very much on computer programming, though Scratch is directed at youngsters.


Criteria for admission to AP CS courses in high school

I don't have criteria with evidence that are indicators of success, but I have some I use that can indicate the lack thereof.

At my school, although we are not allowed to specify prerequisites for our courses, the other programming teacher and I "vet" prospective programming students using data from students' literacy and math history (the two of us combined teach VB.NET, C#, SAS, and AP CS A).  The literacy and math scores come from the prior year's end-of-course tests.  This data is made available in an interface provided by, I believe, Pearson Education.  For each student we can see something like the following:

Where the colors/shapes mean the following:

We have found that Red or Yellow in math and/or Red in literacy are accurate predictors of a student who will struggle in programming.  Just looking at the data from last semester, when I taught programming I (VB.NET), the only C's and D's I had in the course were the students who had Red or Yellow math scores or Red literacy scores.

Every semester when we go through our rosters (we are doing it right now for next fall), if we encounter a student who has signed up for a programming course who does not have a strong math or literacy foundation, we first approach their counselor, show them our prior semesters' data, and talk to them about the student's chances of success.  The counselor will then talk to the student, and maybe the parents.  Sometimes the student will choose to take something other than programming.  Sometimes the student will want to take programming anyway, and that is fine.  We just want the student (and parent(s)) to be aware that, if they want to be successful in programming, considering their history, they may have to work extra hard or get extra help.

While this process we go through may smack of "profiling", our goal is to help every student be as successful as they can be.

Note that the converse, a student who has all "Green" data, is not necessarily an indicator that they won't struggle.  There are, obviously, other factors, many not quantifiable until you get to know the student:  motivation, maturity, perserverence, and hard work.


Explaining how the Internet and the World Wide Web work

One analogy I use in my intro class is transportation. The Internet is the roads, bridges, and highways. The World Wide Web is the cars and trucks that travel along these routes, carrying cargo to/from different places.


I'll try not to write a book as an answer here, but my experience with this is long and deep.

The first thing you need to know is that you don't start with just the programming language itself. If you try to teach integer variables and 'if' and 'while' statements before you get to objects you may fail. I'm going to assume that your intention is to teach a first course that is also objects first. The students in a course like that might have no prior computing experience, though some will have.

The key to a successful course is to teach object-oriented problem solving, and not an object oriented language. In fact teaching problem solving via programming should be the objective of any first course no matter the paradigm. You want the students to learn to use objects and you want them to learn to create objects and you want them to be able to define new kinds of objects. But you don't need to do those all at once. You can spread it out over a short period of time - days, not weeks.

The key is proper scaffolding, written (or found) by you. The students work within a defined framework that can be quite complete (even Turing Complete). Another big idea that you want to believe yourself and teach your students is that an object is a "bundle of behavior."  Never mind instance variables (fields) at the beginning and never mind getters and setters. Define for the students one or more kinds of objects and their behaviors. I've done this with most OO languages and all of them can be introduced the same way. I'll focus on Java for the rest of this, as it is the language of APCSA. It is also a good, though not perfect, OO language widely used in industry.

I have a lot of experience with Karel J Robot (KJR) so let me describe how it can be used as an introduction, that might take half of the first course in computing and teach students how to program. It is not, however, specifically tied to APCSA, nor does it cover every topic needed by your students. But in about half the first course, students will be able to write serious programs that require deep thought. At the end, I'll try to list many of the things not covered.

The KJR world is a simulation in which one or more robots can be created and which have a few behaviors. The "world" of the robots is a rectangular grid and one or more robots can occupy an intersection. An intersection can also contain one or more movable "beepers" that robots might pick up or put down. Infinitely many beepers (effectively a beeper making machine) is also possible at an intersection. A robot always faces in one of the cardinal directions North, South, East, or West. A robot can perform one of five primitive actions: move, turnLeft, pickBeeper, putBeeper, and turnOff. Those are your primitive behaviors and when the student begins programming, nothing else is known, though some additional things are revealed later in the course. In particular, a robot doesn't "know" where it is in the world. The world can also contain walls between intersections that will block forward movement and cause an error if a robot attempts to move through them.

So, what kinds of programs can you write (using only main and the primitives? Well, to a programmer they are pretty boring: Move forward three blocks, pick up the beeper that is there and return to the initial position and direction. The solution is just a sequence of primitive actions, of course: move(); move();...

Students see a bit of syntax in the language and think in terms of the behaviors and nothing else. The learn about statement sequences, the most primitive control structure of  programming (arguable, I guess).

Next they get a much more complex problem (first day's homework), which if solved with only sequences of primitives is unwieldy. It is obvious that something better must exist. But if you choose that program correctly you can notice that there are patterns in the solution. Even in the first assignment the robot had to turn around twice and had to move three blocks twice.

On the second day you discuss the homework and find the repeated sequences of instructions. Now you introduce a new class (their first view of a class) in which you get newly defined behaviors. This class is a subclass of the most primitive class. You are introducing inheritance (too early perhaps, but essential in KJR). The new class has a few additional methods: turnAround(), moveMile()... Note that it is too early to introduce parameters. All of the methods so far, and for a long way in KJR, are mutators, the state of the robot is changed in some way. But the notion of a mutator is in no way linked to any idea of a "setter."

Now you have the basic framework of problem solving. Define a new class. Within it define new behaviors. Create robots with new... and exercise the new behaviors to satisfy some programming task.

Note what is NOT done. There is never any speculative class writing. All classes are purpose built to solve some small part of a larger problem. The book talks about the decomposition process in detail.

You are now in the third day of class and have covered three chapters of the book. The fourth chapter is much deeper and discusses polymorphism, largely by showing how the Strategy design pattern can be used to modify the behavior of a given robot without writing a new robot class. Instead Strategy classes (and Decorators) are used to build a much more sophisticated model of computing. This chapter requires several days. It introduces object-valued variables which up to now have only referred to robots.

The fifth chapter introduces selection and there the student learns about booleans as well as the fact that robots also have some self knowledge. However, there are no methods returning information about the current location or explicit direction. A robot can respond true or false whether its front is clear (no wall) or if it is facing North, or if there is a beeper on the current intersection, etc. All of these accessor methods return booleans, so the student can now write conditional statements, which opens the door to more sophisticated exercises. These accessors are not "getters" either in concept or in fact.

The sixth chapter is repetition, but note that the student already has a good knowledge of the nature of computer programming and they haven't seen any of the primitive data of Java other than boolean. For loops are introduced here, so integers are used, but only in simple ways - step counting, for example.

Later chapters (they are all pretty short) cover recursion and even concurrency.

The key to all of this, however, was a well thought out scaffolding structure in which the students can learn deep lessons in a way that you can control and in which it is harder to go astray in the minute details that you find with integer operators, float/double, ... The point isn't to teach Java as a language, but how to think like a programmer - specifically as an OO programmer.

The BIG idea

Java defines a logically consistent virtual world in which students can program without reference to lower level (machine level constructs) and can create consistent mental models without having to mentally compile their code to bits. A well designed simulation defines a yet higher level virtual world that if (Turing) complete can be used without reference to lower level constructs to solve any problem. That is very powerful. Robots can sort (piles of beepers) for example.

A slightly smaller idea is that you, the instructor, should think about what not to teach, especially at the beginning, as you do about what to teach. Teaching a complete subset intensely can be more powerful than teaching "the whole enchilada" at a shallower level.

Caveats

If the instructor skips the polymorphism chapter, students will come away with the unfortunate view that OO programming is all about inheritance as all of the robot classes must derive from a simpler such class. In fact, OO is really all about building "bespoke" or "tailor made" objects out of parts that are also objects. Skipping polymorphism also gives the impression that selection and repetition are all you need in order to know "how to program", that they are the real thing, an impoverished view IMO.

KRJ is not the only way that you can implement this general course framework. The Greenfoot system is a simulation rich world in which you can build similar (or not so similar) things and use the same general plan. There is an associated instructor site, the Greenroom, to which teachers have contributed many simulations. The general idea there is a World in which Actors can move, turn, interact, etc.

What is missing

The big one is counting with integer variables (other than simple for loops). One issue with teaching int and counting early is that from then on every problem becomes a counting problem, so students wind up with a poor mental tool kit. If you teach counting later, rather than earlier, students need to think harder about problems. You can "count" with decorators and encapsulate the actions themselves, rather than just the count in a (strategy) variable. You also can teach recursion without having to justify it as an alternative to counting.

There is no discussion in KJR of many of the things we love, arrays, for example, collections, iterators, and such. There is a companion book that covers most of what would normally appear in a first course but it assumes the students can already write sophisticated programs.

APCSA

In the past Karel was used a lot by AP teachers, but the course has changed as has the exam. I've never tried to use it to teach APCSA. I'm sure there are many things missing that the instructor would need to add to a complete course.


Creating Interactive Gnu/Linux shell programming courses

Not sure about automatic grading, but you can try this combo:

Jupiter as basic infrastructure
with the bash_kernel to add support for bash exercises
and nbgrader for the grades.

I never used nor tested this particular combination, but you can dig a little bit the documentation to check if it works for you.


First project in my second year data structures intro

Sorry, but digging in your heels or telling the students to wake the hell up is going to get you exactly nowhere. When a small percentage of your students fail to successfully complete a project it is likely their own lack of background or application. But when only about a third are able to successfully complete it, it is a problem with the course, not with them.

Some possible reasons for the problem. Perhaps they started late on it and weren't able to do a good job as user Adam asked? If so, why was that? Are they overworked generally in your course and elsewhere? I doubt that so many are just late starters. Was it a problem of insufficient testing? Was it too many tried a brute force approach that doesn't scale? How much does the course stress that early on - both testing and scaling? It seems like they weren't able to ask questions (of the TAs at least) as the project progressed. If they get stuck, how do they get unstuck? Just on their own?

I think you have a problem and I can't diagnose it, but you can. You can, for example, have your TAs do a postmortem with small groups. I hope you have more than one or two for 200+ students. The first question I would want the failed students to answer was "Were you surprised by the failure?" That can lead to a lot of discussion about the nature of it. I would ask about how much testing they did, especially on large sets. Were they able to use the tester effectively, providing appropriate inputs, or were they misled by it. Another question I'd want an answer to is how many students now actually know why they failed. What was it in the code or its creation that led them to failure. If they don't know that you have a serious problem going forward. I think that for these and similar questions your TAs are better able to get you usable answers. The students are less likely to feel intimidated by the questions than if you ask them directly.

On another level, I'd ask how many independent runs did you do with each student's work? Just one? The data was random, remember. Maybe naive inputs to the tester gave them poor feedback while doing their own testing.

Maybe a five week project with little guidance or feedback is sub-optimal. Especially if you treat it as an exam. It seems like a lot of time, until it isn't. Why not shorter projects? Why not more feedback? Why not, to be honest, continuous feedback?

I wonder how many students who failed did so only for run time and how many weren't even able to put together an algorithm at all. Has anyone given them feedback on their code and approach other than "failed"?

Are your expectations about what they "should have learned" in the earlier courses realistic? Are you making assumptions not warranted by the facts?

Don't just stamp your feet. Find out why this happened and change your teaching structure accordingly. Treat it like a scientific problem with an engineering solution.


What's the best way to assess programming?

Some related research
There has been some research into how to hire people: How do you select people that can do the job. The traditional methods rejects too many “good” people, and accepts too many “bad” people. It turns out that the best thing to do is to test them doing the job, and/or selecting for attitude.
Therefore to test programming you should test programming (I don't care how good an essayist my heart surgeon is).
Google is one of the companies that has done some research in this area. There will be others. I heard about this on BBC Radio4, so there may be some info on there web site (good luck finding it).
Some other suggestion

Open book: programming is not about memory (off line: to web pages downloaded before exam release).

Automated tests, for the coding section (tests written by the exam board). See test-first, and unit-testing.

Look at what can be assess automatically, assess the rest manually (I think there is an article in Hello World issue 3).

To avoid plagiarism: Give them materials to work with, be open book, use exam conditions (multiple small exams).

It was suggested by one teacher: “pupils are messing up in the early stages, this is trickling through and causing pupils to loose marks in later stages as well. Therefore divide the test into multiple sections, the output of section one is not the input of section two (exam board provide inputs for each section, a different problem, the confusion does not propagate).

Check for working code.

Check big-O (run-time, and code size).

Check for good-name (of methods, and variable), over comments.


How can I incorporate agile development into CS1/CS2 courses?

Don't.

Agile is great, but it's mostly about how to manage the development process, interact between the different parties involved, communicate status and break down larger projects of work into achievable segments. When you're trying to understand what a loop/function/class/object/etc is there's really no need to also think about the software engineering issues for larger projects, teams, etc. Students only have capacity to learn so much and I'd argue it's counterproductive to have them spend some of their attention on learning agile.

By all means talk about it if you're looking at software engineering practices, but it shouldn't be a focus.

Test driven development might be ok to teach, although I suspect it will just complicate things for new students.


My company has a training program for software engineering interns. A computer science problem is given to them that they have to code. Every individual intern is going to create a PR to one of our company's repository. Without merging the PR, an instructor can do a code review and add comments, just like Udacity's. IMO, GitHub is better for code review than Udacity. It has everything that Udacity has to offer and much more.

Also, they are learning the GitHub workflow which may be helpful in companies that use GitHub (like mine).


Students seem to be unable to use code to express their ideas. Is the teaching methodology improvable?

There is a lot to unpack here, but first, YES, the teaching methodology can be improved, but that is always true, an unending quest.

Next, I'll note that C is a language with enough pitfalls that many people struggle with it at the detail level, finding it harder to think more globally. My preference, perhaps not open to you, is to start with a language at a higher level of abstraction generally and then, later in the curriculum, work both downward toward the machine and upward from where you start. An OO or pure functional language, if well taught, makes abstraction easier.

However, the biggest recommendation I'd make to address the problems you state is to introduce (at the beginning) unit testing and test driven development (TDD). Find a good testing environment for your language and insist on its use: No Code Without a Failing Test.

I normally start out a course with TDD, combined with giving assignments in an already logically decomposed way. Instead of a large program to write (large is relative, of course), I give them the "top down" decomposition initially that, in C they would be able to implement by writing a lot of functions.

Thus, at the beginning, I relieve them of having to face a blank screen with a large problem and nothing but 'main()' to work with. Later you can continue this, but making the pieces bigger, requiring some decomposition (helper functions) be developed. My mantra for a "too big function" is about five lines. My mantra for "too complex function" is nesting more than two levels. You can break these rules for especially boring code, but not for the interesting logic of a program, or it will be impossible to understand and maintain.

Note that breaking a problem up into parts is how Agile Development (Extreme Programming, Scrum, ...) actually work, with the Customer (in this case you) giving the Team (your students) manageable problems each of which contributes value.

Also, with TDD, you can provide some tests initially along with simple requirements. Teach them to stop programming when the tests pass. Or, write additional tests and make them pass. But the tests are small and simple, usually without internal logic, and the application code needed to make them pass should also be simple function and uses of functions.


Need a good "streaming" software for coding tutorials/workshops

I work on a Macintosh, but assume similar capabilities are available on other systems as well. My systems support multiple monitors and each monitor can show a separate desktop (or a section of a larger desktop). A window in one desktop can simply be dragged to another. If you just connect your regular monitor to one (physical or virtual) port and the projector to another, you will have what you want. If you don't have physical ports a junction/splitter may be required to support the multiple monitors so long as the software will support it.

You could, possibly, have two monitors and a projector with the projector mirroring one of the monitors so as to make your own workflow easier.

This assumes, of course, that you are interested in a face-to-face situation, not remote students.


I usually teach Uniform Cost Search (UCS) before A*, since it is basicaly A* without the heuristic (and it reduces to BFS when all costs = 1, so it is pretty straightforward to explain). Then I teach A* and show them animated examples of the explored nodes in comparison to UCS (here you can find excellent interactive examples).

In this step, one analogy I like to use is about mazes: Imagine yourself inside a maze from which you must find the exit, but you have no idea where it is. This is UCS. Now imagine there is no ceiling in the maze (like the Harry Potter one), and there is a tower in the exit which can be seen from anywhere in the maze. Now you can make more informed decisions in your search, biasing choices in that direction. This is A*.


How can I explain lambda calculus to my class?

One totally intuitive way to introduce the concept is with Excel formulas.  So, imagine in A1, we have the value 10.  In B1, we have the formula =power(A1,2), and in B2, we have the formula =(A1+A1)/A1.  So, at this point, our sheet looks like this:

        A   B   C
    1   10  100
    2       2

In actuality, we have now created a literal, and two lambda expressions: $10$, $(\lambda x.(power\, x\, 2))$ and $(\lambda x.(/\, (+\, x\, x)\, x))$.

Now, let's add a formula into C1.  That formula will be: =B1+1.  This is a third $\lambda$ expression: $(\lambda x.(+\, x\, 1))$.  Our sheet now looks like this:

        A   B   C
    1   10  100 101
    2       2

Since we are pointing C1 to B1, which itself points to A1, we have now created $(\lambda x.(+\, x\, 1))\, (\lambda x.(power\, x\, 2))\, 10$, which resolves now in exactly the way you would expect from the Excel formulas:

$(\lambda x.(+\, x\, 1))\, (\lambda x.(power\, x\, 2))\, 10$

$(\lambda x.(+\, x\, 1))\, (power\, 10\, 2)$

$(+\, (power\, 10\, 2)\, 1))$

$(+\, 100\, 1))$

$101$

Simply re-pointing C1 to B2 gives us a new lambda expression:

$(\lambda x.(+\, x\, 1))\, (\lambda x.(/\, (+\, x\, x)\, x))\, 10$

Which again, resolves to 3 as you would expect.

What's nice here is that if you get rid of the 10 in A1 (you must replace it with a non-number so that Excel does not convert it to 0), you will get #VALUE, because you have created a $lambda$ expression, but not fed in the rightmost value.


Abstract data type that has "include" "remove" and "is in" and only those

Carrano, Data Abstraction & Problem Solving with C++: Walls and Mirrors begins by introducing a simple ADT kind of like you're talking about, called a "Bag". But it is not used as a base class for later examples (e.g., trees, et. al.). From Sec. 1.5:


Do you see the "Bimodal Distribution" too?

Ah, the famous bimodal distribution in computer science!

When I took my first CS class in college, I frequently helped out a fellow student in my section who struggled mightily, spending unreasonably long amounts of time on seemingly simple labs. We made very little headway together. In spite of a semester-long effort bordering on the heroic, the student just couldn't seem to get programming.

I asked my professor about it late in the semester, and he said that there were a certain number of these students every semester, and that he didn't really know how to help them.  He said that, if they didn't withdraw and kept working, he would let them go with grades of C instead of the Fs they actually earned on their exams.

I saw it again years later, as I started teaching my first computer science courses.  In every class, there were some number of kids who just didn't get it.

And I was not alone!  Others were seeing it, too, and there was even an unpublished research paper that started to make the rounds on the internet called The Camel has Two Humps, which asserted both the bimodal nature of the field and that they had created a test that could predict who would be able to "get" it.  That paper was hardly the beginning of the story.  In fact, professors have been investigating this bimodality for years.

Lately, however, the story has been changing.  The author of the original unpublished study issued a partial retraction, and researchers began looking at far larger datasets of introductory CS grades.  It turns out that that bimodal distrubution is not really bimodal after all.

So what is going on?

When we teach programming, we want our kids to be able to program.  So we test them on programming, and we want to heavily weight our grades on, well, whether or not they can obtain the proper output.

To illustrate this, let's take a hypothetical problem prompt, and some sample answers.  The question, which will be in an introductory Java class, will read, "Create a function called makeN that, given a number n, fills and returns an array with $n$ sequential values".

Answer 1:

public int makeN(){
    array[n] = 0;
    array++; // until its done
    makeN = array;
    return makeN;
}

Answer 2:

public int[] makeN(int n){
    int[] array;
    for(n < array.length; n++)
        array[n] = n;
}

Answer 3:

public int[] makeN(int n){
    int[] array = new array(n);
    for(int x = 0; x < n.length; x++){
        array[x] = x;
    }
    return array;
}

Answer 4:

public int[] makeN(int n){
    int[] array = new int[n];
    for(int x = 0; x < array.length; x++){
        array[x] = x;
    }
}

There's a clear progression among these answers, and they represent vastly different levels of understanding.  Unfortunately, our topic requires students to be able to pull together many different concepts in order to do almost anything.  If we were to grade by whether the answer fulfills the prompt, they would all receive the same grade.

I actually have come to believe that, in a good rubric for a coding example, "actually produces the proper final output" should either not be present at all, or should be worth a miniscule amount of credit.  A good rubric will capture attempts at portions of the algorithm, and successfully achieving steps of the algorithm.

This example above may have been extreme, and I doubt if most teachers would award exactly the same grade to answer 4 as they would to answer 1, I this cognitive bias certainly exists (I possess it myself), and it seems perfectly plausible to me that examples 1 and 2 might receive almost identical grades.

The trick to get out of bimodal thinking, then, is to break down the skills into smaller subskills, and break those down into further and further tiny understandings.  This has two benefits: first, you see the clearer progression among your students, and two, head-scratchers like answer #1 become actionable, and you can see how to help the student to improve.

Student #1 may never quite get to a complete picture during your class - he or she clearly has a lot to learn! - but it is unreasonable to the student (and to you) to demand basically 100% comprehension in order to avoid failure.  And taking a partial understanding as a partial success shouldn't just apply to the student. It's the teacher's success, too.


How to structure a Predictive Keyboard project similar to GBoard

Markov Chains are great for putting out nonsense based on statistical data. However, a predictive keyboard that outputs nonsense isn't very useful. It needs much more context than a Markov Chain can produce. Such a program would base its next output entirely on the most recent entry.

That said, a project to do something like the Mark V. Shaney program might be fun in an Introduction to Data Structures course. However, it is unlikely that students would have previously seen Markov Chains at that point in their studies so some background in that would also need to be incorporated. Markov Chains might be taught in a Discrete Math course, but that usually comes later. Some schools might teach these two courses in tandem, however, making it a bit more feasible.

Such a project would, however, also have the advantage that the statistical basis (the Dictionary) used could introduce concepts of Big Data and how to process it.

You are correct that a predictive keyboard uses past data, but I'm pretty sure that it is based on a much more complex predictive model than could be provided by a Markov Chain. "Predictive Keyboard based on Markov Chains" is probably an oxymoron, though. You can do either or, but likely not both together.


I looked at them when they first came out and decided not to use them. Did go through and look at the topics and make sure that we're covering everything we need to in class. But between labs that I've written or purchased we've got a pretty good set of assignments that covered everything that the AP provided labs hit on.

The 3 AP labs also lean more towards projects instead of simple labs. I prefer to do a lot of small, single method labs. Especially early in the year. We do larger scale projects later, and they overlap a lot with what AP provides.

And not really part of your question, but I can't imagine only spending 20 hours on labs through the year. We probably hit that goal within the first month of the year.

Edit

Following up on a comment asking about lab sources...

The best labs are past AP exam FRQs. My goal every year is that by the AP exam we've done every past FRQ in class as a lab, quiz, or test. We start in September. Going back to 2004 there are 45 FRQs if you don't include the GridWorld ones. I generally assign them as in class assignments though since there are solutions posted everywhere online. If they're assigned to be worked on outside of class they'll be daily grades which have very little grading weight in our district.

Another good, and cheap, source are programming packets from old contests. UIL, the organization that runs academic and athletic contests in Texas, sells past tests on their website. You can buy a PDF with all the tests from a year for $4. There are 5 or 6 tests a year with 40 multiple choice questions and 12 programming problems in each test. Only downside is that they're not sorted, so you'll have to go back and figure out where they fit. And some are more data structures problems instead of AP-A. ACSL also sells past contests on their site.

And our district buys curriculum from A+ Computer Science. Best thing here is that it's a complete curriculum - labs, project, quizzes, tests, slides; everything. I use this mostly for the written tests because I hate writing multiple choice questions, but I also tweak some of the labs a little and use them.


Lambda expressions exercises and practice

One of the interesting things added to java in v8 is functional interfaces. Previously java only matched things up and verified correctness by type (type names). With functional interfaces, java now looks at the structure of code in certain situations.

I can add examples to this answer to clarify if anyone asks.

One interesting feature you can add is a method to do simple repetition. I like to teach a lot of things before if and while, but sometimes you just need repetition and the most common sort is a constant-number-of-iterations loop.

@FunctionalInterface
public interface LocalCommand
{
    public void accept();

}

/**
 *  Repeat a method a given number of times
 * @param howMany number of times to repeat the method
 * @param what the method itself, as a Command. Especially useful in Java 8
*/
public static void repeat(int howMany, LocalCommand what){
    for (int i = 0; i < howMany; ++i){
        what.accept();
    }
}

Usage:

public void aCommand(){
    // do something interesting
}

repeat(3, aCommand()); // structural matching with the functional interface
repeat(3, () -> {aCommand();}); //lambda expression
repeat(3, () -> {System.out.println("Hello");}); //lambda expression

In java 8 you don't need to ever explicitly say that aCommand is, in fact, aCommand and you don't need a new enclosing type to implement the functional interface. You don't even need to specifically say that it is a functional interface, Java will grok it by structure alone.

With repeat(...) in my library I can do repetition before I need to talk about for and while loops.

I used only the simplest case of a functional interface here. You can use Consumers, etc just as well with only a bit more complexity.


I have been responsible for using performing and evaluating tools for detecting software plagiarism in my academic department.

There are several published review articles in the scholarly journals. One such report Culwin, MacLeod & Lancaster, 2001, UK JISC, "Source Code Plagiarism in UK HE
Computing Schools,
Issues, Attitudes and Tools" gives an overview.

Basically, there are published algorithms and methodologies you could implement yourself, open source software you can run locally, or an internet based service you can register and use.

One such tool that you can run locally is JPLAG from the University of Karlsruhe in Germany. This has several language syntax implemented, and as it is open source you can amend as desired.

The best online tool is MOSS from Stanford which is the one I ended up using.

If you wanted to research the various published techniques for detection, Google Scholar is a good source.


What resources and data sets are available for teaching big data courses?

Related questions:

Good datasets for intro CS courses?
Toy Databases for Class Examples/Homeworks

There are a few Stack Exchange sites you might want to check out:

Open Data: Open Data Stack Exchange is a question and answer site for developers and researchers interested in open data.
Data Science: Data Science Stack Exchange is a question and answer site for Data science professionals, Machine Learning specialists, and those interested in learning more about the field.
Cross Validated: Cross Validated is a question and answer site for people interested in statistics, machine learning, data analysis, data mining, and data visualization.

Kaggle also offers a bunch of example datasets and a bunch of real-world problems that can be used in a class.

But taking a step back, you might want to teach the meta-lesson of finding data in the real world. There are a ton of APIs and open-source data repos out there, and finding them is a very important skill by itself- plus it give students a way to actually use their skills after the class ends.

So instead of just giving your students a flat file, have them come up with their own. Maybe they use an API from a product they use, like Twitter, Spotify, or YouTube. If that's too advanced for the students to do, then maybe you spend a class coming up with the dataset together, with you writing the code and the students talking about what would be interesting to see.

Or just searching for "XYZ datasets" returns a ton of results. Have the students come up with datasets related to stuff they're interested in.