Online courses to form or improve a CS resume?

You've got a lot of really broad questions here, so it's going to be a little difficult to unpack them all. Consider only posting one specific question per post. Also note that the answer really depends on you more than anything, so a lot of this is hard for us to answer. But I'll offer my two cents:

  what other online courses are available to help me build a resume and help compensate for my lack of degree. -- Is this a good way to start learning programming?

This is three different questions:

What online courses are available?

There are a ton of online courses, and which one you'd take depends on exactly what you want to be doing. Programming is a huge topic: there's web development, server-side development, database management, robotics, machine learning, system programming, etc.

First figure out what you want to do. Then start searching for tutorials and online classes.

How can I build a resume to compensate for a lack of a degree?

List the projects you've worked on. Create an online portfolio showcasing the stuff you've actually done. Don't tell me what you know. Show me the projects you've completed that demonstrate what you know.

Keep in mind that this won't happen overnight. You won't get to this point just by reading one book or breezing through one online tutorial. You have to spend some time working on a project.

Are online courses a good way to learn programming?

Like I mentioned above, whether they're a good way for you to learn programming is more up to you than it is us. We can't tell you what's best for you.

I will say that the only way to learn how to program is by programming, working through the process of taking a big problem and breaking it down into smaller steps. Whether you get that practice from tutorials, or from an online course, or from a university, is up to you. The important part is putting in the work.

  What are the pros and cons of self learning compared to learning in an established university program?

I think you probably already know these. A university program gives you access to teachers and peers, and provides a structured environment. Self-learning allows you to learn at your own pace, and it's much cheaper but harder to "prove" what you know.


First of all, it seems like rather nice bones of a 2-dimensional array lab. It does not strike me as being too many things at all.

The interface is cleaner with move(direction), but the internal logic is cleaner divided into methods.  Why not the best of both words?  Provide them with starter code that will utilize private methods:

public void move(direction){
  switch(direction){
    case UP:
       slideUp();
    case DOWN:
       slideDown();
   case LEFT:
       slideLeft();
   case RIGHT:
       slideRight();
  }
}

That is another way, also valid.
It seems excessively finicky to require implementation details down to this level.
Once again, I would provide the interface, but not these sorts of implementation details.  You can provide both ways as suggestions, but leave it up to them.  They may also choose a third option that you have not mentioned.
This fits very nicely if you are providing some sort of GUI starter code, which would justify an implementation detail like this one.


What are some non-CS concepts that can be defined using BNF notation?

Going with real-world things which they should be familiar with are best, even if it is completely outside of education. As you have applied the tag for adult education, I'm going to presume it is outside of normal university/college courses.

A bit of creativity and looking around can develop many an idea as long as you get outside the box. The cafeteria might be a good place to look.

entree ::= pizza | hamburger | steak
side_dish ::= corn | coleslaw | fries
beverage ::= coffee | tea | milk | soda
dessert ::= (apple|pumpkin) pie | (peach|cherry) cobbler | ice cream
meal ::= water beverage* entree side_dish+ [dessert]

  The water is mandatory (already on the table perhaps), it's possible to have as many drinks, and refills, as you wish. There is always an entree, one side dish is included, but you may have more. Finally, if you choose, you may have a desert.

If the situation is at a regular educational institution you can experiment with using degree requirement courses, and electives. There's enough there to allow the students to create their own versions as practice as well.


First, I applaud your ambition!
The first OCP exam covers roughly what AP did until this most recent year, when the college board stripped out Interfaces. I would still suggest that they are mostly equivalent, but there are a few practical advantages to the AP Test:

It is substantially cheaper.
Colleges recognize it for admissions purpose. (As you point out, an admissions officer is unlikely to have heard of the OCP, and would question how it compares to AP, and why you didn't just take AP)
Many colleges, at least in North America, automatically award credit or alter your course placement based on your AP scores. No equivalent system exists for OCP.
Because OCP is a professional exam, and you are unlikely to join the profession for at least 5 years (assuming a 4 year college), the exam may be considered dated by the time you get into industry, and it seems obvious that a college major will count for more than the lowest-level Oracle exam in any case. TBH, I've never heard of anyone asking for job applicants to provide Oracle scores, though I imagine that it probably happens somewhere or they wouldn't still offer the exam.

One last thought for you: you do not have to take the course to register for the test, so you can self-study. If you wish to go this route, but your school won't allow you to register yourself for the exam without being enrolled in the course, you should still be able to sign up at a different location.
Good luck!


Simple use case for self-modifying programs

I didn't write any myself, but I encountered several self-modifying MS-DOS batch files (this is possible due to the OS closing the batch file before executing each line), especially during the $1980$'s. I'm not sure if batch files fit within your definition of "programs", or if this usage was from too long ago since the needs & reasons for this (i.e., primarily due to only a minimal amount of memory being available) don't generally apply now to modern computers. Nonetheless, having batch files modify themselves is a relatively simple concept, and was similarly done for fairly basic reasons as well, so this might make good examples for teaching purposes.
I recall self-modifying batch files were used in several situations, but the main one was to change options based on user feedback. Wikipedia's Self-modifying code gives an example where a batch file runs a program that changes the file itself to next run what the user requested. However, I also recall seeing & using a batch file with a fairly complicated (at least for a batch file) menu type system, with the commands directly modifying the file itself based on user feedback, return codes from the menu and/or other programs which were run. I no longer have a copy of this batch, or any other related, files. As this was over $30$ years ago, I don't recall any other details. Also, I haven't been able to find any such similar example online. Nonetheless, in Changing a batch file when its running, several answers, such as the answer by dbenham and the answer by jeb, give other examples of direct self-modifying batch files.
Note that, as the Wikipedia article section states, these batch file self-modifications were done primarily due to how limited memory generally was in personal computers back then. Most, if not all, of the other reasons people wrote & used self-modifying batch files back then, as I recall, were also due to these significant memory limitations.


Should I have written tests on basic programming skills?

As a tool for differentiation, writing out code by hand is absolutely worthwhile. I taught this year in a classroom with whiteboard top desks, and students loved a) getting to writing on their desks (even being encouraged to) while b) learning syntax through multiple modalities. What might catch a student's eye or get instilled in her memory through handwriting is not the same as what she might see in her code in an IDE.

On a pragmatic level, the AP CS A Exam requires students to answer free response questions, so it is essential that they be prepared for this task. I would be doing them a disservice to not require some form of written examination.

That being said, the extent to which you grade this might be the determining factor in its success. As a formative assessment of syntax and of logical thinking, it works great, but again, unless its specific exam (or interview) preparation, it seems less effective or worthwhile.

As noted above, students have to learn how to debug by reading and analyzing error messages. Nonetheless, I don't believe it's so much an either/or here. Use the handwritten assessments to inform instruction and re-teaching and to teach and reinforce concepts in a differentiated manner.


A quick online search led me to this.

A Beginner's Guide to Access Technology for Blind Students

It covers all the essentials

Screen Access Software
Braille Embosser
Notetaker
Scanner and Optical Character Recognition

I am essentially listing things from that article It seems like something that was written years ago, but I assume, it should be a good starting point for you.

Further, the city I live in does have a national institute on speech and hearing, which includes folks who are sight challenged. If this is something serious, I can drive up there and talk to someone and hook you up with a professor or something.


What is a good analogy for the Object Oriented paradigm?

I've got to jump in here and talk about my experience having to help a former boss understand why the project he wanted to do wasn't possible in the time available. It came down to incompatible data types and he just couldn't see why I couldn't convert from one to the other (he wanted to do real-time motion capture using an XBox Kinect to animate a 3D mesh of the circulatory system and thought this was easy).

Ben I.'s answer touches on this too, but I can add to it.  He says this:

  The objects keeps track of some kind of information (instance variables), can be interacted with only in specified ways (interface), have setters (switch/button) and a getters (lights, your eyes).

There's more to it than that.  In this electrical engineering paradigm (which should be familiar to most), a light switch that has two states is the most basic example.

It has output: bool isOn()
It has a method of supplying input: toggle()
Underneath it has an implementation of what toggle() does and how that affects the return value of isOn()

Buttons can also be described in this manner:

It has output: bool isOn()
It has a method of supplying input: push()
Underneath it has an implementation which differs from Switch slightly: after push() is called the output is true for a short duration, then automatically returns to false. That is, the user must continue to interact with the button in order for the output to be true.

A knob also has similar features, although different types are involved:

It has output: float getValue()
It has input: twistTo(float v)
Underneath it has an implementation

But here's where it gets interesting:

What happens if we define an object that implements both Knob and Button? We should expect the following description:

It has output: float getValue(),bool isOn()
It has input: twistTo(float v)
Underneath it has an implementation
After input is supplied, isOn() becomes true, then after a duration becomes false again. In order to keep isOn() returning true forever, we must continue interacting with the object.

What do we end up with?

We can twist it to set the value, which turns the output on and displays the value. Then after a duration defined by that value it turns itself off again. As the homeowner we don't care how it was implemented only that they can interact with it in a certain way (defined by those interfaces) to get the desired behavior.

And yes, I'd present that to students in that manner. Describe the simple items (button, toggle, knob, timer) and then ask the students to figure out what happens when two of them are combined. The epiphany moment when it clicks will do wonders. That's the difference between being told and being taught.

You can expand on this analogy quite far, as well: Three-way switches, time-locks, missile launch confirmation (you need to press two buttons at the same time), sliders, gauges...

And then...you can get to events. Instead of treating the wires in the analogy as hard links in code (while(switch.isOn()) { ... }), you can treat them as events: when the switch changes state, that update propagates to all objects listening for it and they handle the state change as their implementation dictates (switch.addListener(this.doWhenToggled)).

The classic "cats are felines, felines are mammals, mammals are animals" hierarchy only gets you so far and provides a very poor and rigid understanding of Object Oriented Programming that causes new programmers to tend towards Do-Everything Objects (where do float planes fit in the "boat extend vehicle, plane extends vehicle" hierarchy? Clearly the only solution is to make all vehicles drive, fly, and float and just disable the ones we don't need!) rather than through a composition of interfaces (say, FloatPlane extends BaseAircraft implements IWaterCraft).

I know that sort of thinking messed me up for a number of years. Heck, I'm still recovering from it: I still can't read inline lambda expressions natively, I have to decompose them, and it often takes me several minutes. Same thing goes for creating interfaces, I often have to go the "cats are felines" road until I hit a spot where I realize "I want to use this code on both cats AND cars" because they both share some property that doesn't exist in the common class (and shouldn't) and I have to refactor.

Of course, refactoring is a good thing. Give your students a powerful IDE and teach them how to use the refactoring tools. Eclipse is the god of these , offering an astounding fourteen different options, including "Extract Interface" and "Use base type where possible."  Even if they make a mistake, now they know how to fix it in moments rather than hours. No one wants to (and no one will) spend hours fixing an inheritance problem that can be solved by a quick copy and paste; "code duplication, meh, never hurt me."


Distributed Pair Programming in distance education

My suggestion would be to utilize seprate tools for elements of the process rather than try to find a packaged solution, or modify an existing tool which is 'not quite right' for the task.

Quick summary is:

use Discord for communications, text and/or audio

Restricted channels for each pair to utilize while coding
Open channel for students to contact the instructor

use the GoLive feature of Discord for the "driver" to stream their active IDE to the "navigator" (GoLive will stream a "terminal" window, it does not have to be a game.)
use git to "lock in" the code between role switches with commits
use GPG keys for signing of commits and to authenticate the SSH pushes
use GitLab as the remote repository

Use Discord for communications

As the instructor:

Create a Discord server
Create a public text channel for the students to reach you in
Create a public text channel for the students to share in (you can monitor, but don't communicate here)
Create a role for each assigned student pair
Create a private text channel for each role above
Create a private audio channel for each role above
Enable each role to send/read messages, or connect and use GoLive, in the role-specific text and voice channels
As students join, however you get them to connect, assign them to the role which matches the assigned pairings

As the owner of the server the instructor will be able to read the chat in all text channels, hear the conversation in any audio channel, and view any of the windows being streamed. Instructor preference and style take priority, but my suggestion is to limit any messages sent by the instructor to the designated channel. Moderator type actions can, and of course should, be taken in any channel. Going remote still leave "classroom discipline" in the instructor's hands.

As the school term progresses, it's likely that pairs are reassigned frequently. Perhaps as often as each new project. Once a project is graded, the associated text channel could be reset, or removed.

Use git

While git may not be The one true source control system, it is a popular one. The command line use of it can be quite complicated, especially for advanced purposes. The basics of it, however, are quite manageable for students. GUI tools also exist, though I'm reluctant to endorse any one, or even recommend their use. With students learning to use git it is probably better for them to learn the CLI commands, which will work on any OS, and on any system with git installed. The GUI they learn might not work on the system they have to use later, for work or for advanced classes. The GUI probably won't work if they have to use SSH for any reason as well.

Using git, as long as both students have access to the repo, allows for one to make changes, commit the results, and pass control to the other when they switch roles. As an extra benefit, since the current "navigator" will have the last committed version locally, they can scan through the file(s) to review other parts while directing the "driver". Ensuring that identifier names and parameters are used correctly, for example, without disturbing the "driver" with those details, allowing the driver to concentrate on the section of code being changed.

As a benefit to the students, they'll have the ability to unroll changes that were leading down a dead-end. As a benefit to the instructor, each commit will be blamed to the student driving. Additionally, by following the diffs, it's likely that when the team gets lost in the weeds, the instructor can see what thinking started the problem, and help them to see the way out.

Use GPG keys

The "remote" aspect of this is challenging for instructors to "watch" the students work. Having to worry about who is doing the work and who is not only adds to the work load. Requiring that the students GPG-sign their commits can help with that some. Not only will the repository assign the updates to the user, it will also verify that the user claiming the updates is the same one who signed them. There is no encryption involved, just a signing of the commit to prove who made it. Using it, however, might require the students to install GnuPG on their systems. Encouraging them to do so shouldn't cause any issue, and it can be a good habit to develop for later as well.

The process of setting up a key for use with the git program, and for connecting to the remote repository is fairly simple. Even from the command line.

Generate the key pair to use. The key pair needs to have both singing and authorization capabilities.

gypsy@spellweaver:~> gpg --quick-generate-key "Student Name <email.name@some-school.edu>" future-default auth,sign
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key A822359C643A77A4 marked as ultimately trusted
gpg: revocation certificate stored as '/home/gypsy/.gnupg/openpgp-revocs.d/11716FF672B9DD368C174F26A822359C643A77A4.rev'
public and secret key created and signed.

pub   ed25519/A822359C643A77A4 2020-03-19 [SCA] [expires: 2022-03-19]
    Key fingerprint = 1171 6FF6 72B9 DD36 8C17  4F26 A822 359C 643A 77A4
    Keygrip = 92F62A329D3CBBBE64BFA8DABC6F4348623AB256
uid                            Student Name <email.name@some-school.edu>

The ASCII version of the public key will be needed when setting up the repository.
This block will be copy-pasted to the repository within the user's account settings.

gypsy@spellweaver:~> gpg --armor --export A822359C643A77A4
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEXnMHZxYJKwYBBAHaRw8BAQdAjh6qOGnp5b0GTNZEHL4wIrIljwxLlxfU8/F5
l8TZVNC0KVN0dWRlbnQgTmFtZSA8ZW1haWwubmFtZUBzb21lLXNjaG9vbC5lZHU+
iJ0EExYKAEUWIQQRcW/2crndNowXTyaoIjWcZDp3pAUCXnMHZwIbIwUJA8JnAAsL
CQ0IDAcLCgMBBAYVCgkICwMFFgMBAgACHgECF4AACgkQqCI1nGQ6d6RXEAD/Rdhz
kh+gNvnO367JYqdoIwFiIsW4a2mq3d4nqNE6migBAM3m8cMO2Ww2u5+O7l8P4GuI
EMTlK2WWckAEJUGS1pMO
=6LSb
-----END PGP PUBLIC KEY BLOCK-----

The public key needs to be saved in SSH format.

gypsy@spellweaver:~> gpg --output id_ed25519.pub --export-ssh-key email.name@some-school.edu

The public key will be needed when setting up the repository on GitLab.
The last line is what will be copy-pasted in the settings of the repository for the SSH key.

gypsy@spellweaver:~> cat id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII4eqjhp6eW9BkzWRBy+MCKyJY8MS5cX1PPxeZfE2VTQ openpgp:0x643A77A4

the git program needs to be set to always gpg-sign commits and told which key to use

git config --global commit.gpgsign "true"
git config --global user.signingkey "A822359C643A77A4"

Use GitLab as the remote repository

Usually GitHub vs GitLab is more about personal preference than any project-based requirements. The granularity of permissions in GitLab is better than GitHub, allowing the instructor to grant access to the assignment repos on a per-user basis. GitLab allows for unlimited private repositories without having to create a paid account. Let's face it, as a rule educators don't have the spare funds to support enterprise level tooling. GitLabs give for free what GitHub will charge for. As it is student work, private repos seems more appropriate on two grounds. First, normally student assignments are not available to the general public. Even more so when dealing with under-age students. Second, by having private repos, with only the pair of students working on it being granted access, the ability to copy one team's work by another team is greatly reduced.

Three additional factors available from GitLab which might be useful are: 1) Discord Notifications, 2) their Continuous Integration (CI) pipeline, and 3) the ability to install a local, or self-hosted, GitLab for greater security. Depending on the language being use, the CI pipeline might help in keeping variations in build environments between student systems, or between their system and the instructor's system, from hiding or creating errors.

Tidbits and Notes

One possible downside to Discord is that it can also be used for video calls. That, however, is a something which is available through the "friends" section rather than in the "server" you would be responsible for, so it shouldn't count against you, or the application.

A bonus for Discord is that the odds are high that most of the students already have it installed, and know how to use it. They probably know how to use it better than the instructor would.

For the current crisis (COVID-19) Discord has increased the size of GoLive streams to 50. That shouldn't matter unless it's decided to us the GoLive feature for the instructor to do demonstrations, which is also a possibility.

If the students have an assigned email account from the school, it is probably a good idea to require that such email be the one associated with the GPG keys and the accounts on GitLab. Official required communications should be done by email using that address as well. Assignment instructions, due dates, grades, etc., rather in the untracked space of Discord.

To "invite" the students to the Discord server, create short-lived, single-use invites for each student, and send that in an email to them rather than a general invited for the class.

For most Linux systems, git is a simple install, directly from the default software repositories. For Windows it takes a bit more work. A guide, which seems to be pretty good, is How to install and use Git on Windows.

An advantage, and possible disadvantage of using the GoLive option is that each student can have their own version of the IDE, customized to their preferences. It's even possible they could use a different IDE than they would in class, and different from what their partner is using.

The potential problem with this is that they could become lost in the IDE and the instructor, having never used that one might not be able to help.

An unplanned benefit could be that new insights into student preferences, including IDE choices, can be obtained by noticing which IDE students gravitate towards, and how they use them. Once classroom instruction is able to resume, a change of IDE for in-class use might be in order.

The 24/7 availability of the tools can get the students into the habit of "calling" the instructor an anytime, without thinking that there are other things to do, or classes to work with. Setting a time for "class" where you will be available on the server for direct contact, perhaps during the same time-span as class was held when it could be held. To avoid the appearance of always being available it might be worth creating a different server for each class, keeping your "office hours" on each server in turn.


Yes, Greenfoot certainly has interfaces. I doubt that they would take them out. The people who built greenfoot are likely as appalled as I am about the College Board action on interfaces. But there is no UI element that specifically adds a new interface to a project.

But they may not appear in the same place that most classes do in the sidebar. Look at the bottom of the list.

Use the menu option to create a "New Class". Edit the resulting template to change it to a legal interface. Compile and save. This was with v 3.5.

You can do the same with other "class-like" things such as enumerations. The compiler hiding behind greenfoot is all of Java.

You can also go to https://greenroom.greenfoot.org and ask such questions there (after joining).

Also, many of the labs that you find on both the greenfoot and greenroom sites will use interfaces.


Is it bad to force my students not to return early?

Actually returning early should be the norm. Return as soon as you can. There are at least two reasons for this, of which the first, efficiency, is the least important. But if you return early then needless statements won't be executed. Nor will you need to devise some special code to get to the end just so that you can return.

However, the biggest and most important reason for returning early is that the programmer can put a limit on what she/he needs to retain mentally about the state of the computation. This is especially helpful in a sequential if situation. There is actually an Elementary Pattern about this ("Return, not else") that says that if you know what should be returned at the end of an if block, don't use an else, but instead end the block with the return. The reader/writer/updater then gets to ignore the previous state and start over in their thinking process.

If you return only at the end, say "return result;" then you have to track all changes to result that might occur anywhere in the function/method. You have to understand it "as a whole" rather than incrementally. But the reading itself is normally sequential and incremental.

Of course if you always write three statement methods, this won't occur, but few have the discipline to really do that. Sadly, some programmers can't understand their own code when it contains very many nested structures and tests.

I'll also note that this is somewhat related to the idea that we generally try to avoid global variables in programming. Too much extraneous information can impinge on understanding. Being able to comprehend a program "one block at a time" without reference to others, even containing blocks, is a big advantage.

Caveat. Of course, the code should be as clear as possible. If returning late makes it clearer, I wouldn't forbid it. But I think that is seldom the case. Forbidding early returns, however, is counterproductive.


How should I respond to a student who proposes a "weak" analogy?

The concrete example:

Your student is right. At least, I agree with him, because I think of event listeners in the same way.

When multiple callers register for the same event, and the event triggers, it "calls everyone back". Functionally, it's similar to how an array or list is processed, e.g. :

foreach (var caller in callers)
{
    caller.Call();
}

The thing about abstract fields such as programming and mathematics is that people will find what works for them. Not everyone sees it the same way.

I may be biased because me and the student apparently see it the same way; but I'm actually having a hard time poking holes into his argument, without having to resort to fairly avanced event handling (and even then, the analogy sort of works).

Anecdotally:

A simple example for math applies to me. When considering the average of two numbers, most people think to themselves:

average = (A + B) / 2;

However, I instinctively used another pattern:

average = A + (B-A)/2

Note that A is always the smallest number.

This looks a lot more contrived. I agree. But to me personally, it was easier to do it like that. I'm someone who uses number forms to visualize numbers in my head, which means I do simple calculations visually (sort of, it's hard to explain).

When you ask me to calculate the average of 45 and 51, what I see in my head is:

  ... 43 44 45 46 47 48 49 50 51 52 53 ...

I take the numbers between the boundaries:

  46 47 48 49 50

And I find the middle number.

  48

When you look back at "my" formula, maybe you'll see that the order of operations is the same as this visual example. Take the difference, split it in two, find what's in the middle.
To me, it makes perfect sense, and I am considerably faster when calculating averages (of 2 numbers) this way.

I reverted to using the more standard approach when math classes started requiring us to calculate the average of more than 2 numbers. But for finding the average of two numbers, I still use my own method to this very day.

How to respond:

Even though the student is correct (in his own way), if you simply agree with his stance, others may misunderstand him (because they e.g. think of arrays in a different way than the student who raised the analogy).

You need to approach it correctly, because you can't err on either side:

If you tell the student he is wrong (for the sake of the other students), then he will be incredibly confused. I've been on the receiving end of this, and it took me some time to regain the confidence to use my own averaging method.
If you tell the student he is right (for the sake of the student), then the other students may end up incredibly confused.

So when you respond, make it clear that you understand what the student means, but it's not exactly the same in every way.

For example:

  I see what you mean, and this particular case does indeed behave similar to an "array of listeners". But there are other cases where the analogy doesn't quite work, so be aware of that.

Or:

  I can see where you're coming from. As you now understand it, there are indeed some similarities. However, once we delve into more advanced examples, you'll start to notice that it's not quite the same. Try to not stick to the analogy because you'll end up expecting different behavior.

I think this sticks to the middle of the road:

It confirms the student's basic interpretation of the code's behavior.
It highlights that the analogy is not perfect and flawed when applied to other cases.
Other students who have no idea what the student was talking about (because they understand it in a different way) will understand that the analogy is flawed and not generally usable, so they won't fixate on understanding why this analogy sort of works and will instead be more likely to ignore it and move on.

There are of course countless ways to respond, but you should always try to find a compromise that both confirms the student's vague suspicion, suggests that it only works in particular cases, and it avoids creating confusion for the other students.

Specifically for this example, my response would be:

  Yes, even listeners can be considered as an "array of listeners" where you can add/remove listeners as you please. However, "an array of something" is an incredibly common concept in programming. Whether it's getting data from a database (a table is an array of entries) or parsing a string (which is an array of characters), you'll find arrays and lists everywhere you look.
  When we get to the more advanced part of the curriculum, almost everything will use an array-like approach at one point or another.


How to stress the importance of testing code?

Introduce test-driven development.

TDD and agile methods of development are very popular at the minute, and for good reason — you know, ahead of time, exactly what each part of the program must achieve, and you can confidently say that the program will work as intended as long as your tests are thorough.

I think that sometimes, the confusion begins when students aren't actually sure what they're trying to achieve in the first place, so they're reluctant to test because the code is already so fragile. TDD helps to ensure that there is a clear specification of behaviour for the code, so the students are clear on what should happen, and that the code they're written fulfils the specification.

Make it clear that testing is part of the project in your lessons, and it should help to solve some problems. When students are asked to write a program, they may not realise that writing some tests along with the project (or even beforehand, as in TDD) is a good idea. Having the red-green-refactor cycle would seem helpful here; it will give your students confidence that their code works as intended, and then the ability to clean up and improve their code without breaking it.

Test-Driven Development Goes To School was interesting reading while I wrote this answer. They evaluated the effects of teaching using TDD at several university courses, with generally mixed/positive results. At Virginia Polytechnic Institute:

  Code correctness measured as the number of defects per
  thousand lines of code was only 38 for the TDD group compared to 70 for those not using
  test-driven development
  65.3% of students either agreed
  or strongly agreed that TDD increased their confidence in the correctness of their code.
  67.3% either agreed or strongly agreed that TDD increased their confidence
  when making changes to their code base.
  Test completeness was 93.6% for
  TDD; 90.0% for non-TDD.

Of course, there is the overhead of writing the tests and understanding how to use a unit testing framework. For smaller projects, this might be an excessive overhead, but for most non-trivial projects, test-driven development can still be useful. If you're only developing a few functions, you might only need a few tests, and it's great preparation for industry, where TDD is very common.

So, in short, don't just stress the importance of testing and hope they listen, integrate it into your teaching. If writing good tests is the norm in your class, it's far more likely that rigorous tests will be written.


Debugging a submission that works well on student's computer but not on my computer

You've said that having an identical environment for everyone would be an incomplete solution, since students' code could still work "by accident" in that environment. One option would be to provide access to two or more sufficiently different environments which would be the same for everyone; such environments could be provided in several ways, for example:

Distribute virtual machine images, with instructions for how students can use them to test their code.
Provide access to virtual machines through a paid service; for example, Codio is specifically designed for use in CS education.
There are some web services such as repl.it, which compile and run your code, and show the results in a console.
Some universities have student-run computing societies offering accounts for students on a shared server.
Different environments may already be available if students are on campus, and the campus has enough different computer labs open for student use at some times.

To catch undefined behaviour when grading submissions, you could test their code in the same two (or more) environments that students have been encouraged to use. Assuming you have a script that can automatically run all submissions, it shouldn't be a lot of extra work to run that script twice.

Another option is to provide students with a software tool which can detect and report undefined behaviour, as discussed in this Q&A on Stack Overflow. Such a tool could also be used to give feedback to students whose submissions fail on your machine during grading; although static analysis and other techniques won't generally be able to detect all kinds of undefined behaviour, the kinds they do detect should cover most or all of the mistakes that students are likely to make.


Where can I find a breakdown by race and gender of US CS bachelor's degrees?

the Taulbee report An-In Depth Examination of Data and
Trends Regarding Women in Computing provides summary data on computing degrees by ethnicity & gender for 2013 in Table 2 on pg 20 and cites the Integrated Postsecondary Education Data System (IPEDS) as their data source. You can either filter through their data online or download it:

  Data are available starting with the 1980-81 collection year for the Complete data files and Custom data files functions, which zip the data into comma separated value (*csv). Beginning with the 2010-11 collection year, data for each collection year are compiled into an Access database.

Some tips for using their online data statistics:

Try using the 'Statistical Tables' option on the 'Use the Data' page
When select institutions, if you select 'By variables', there's an entry called 'Completions' which has an option for reporting 'Number of students receiving awards/degrees, by race/ethnicity and gender'
After that, select the specific gender/ethnicity info you're filtering for


I like your locksmith comparison, but I don't agree with the following assertion:

  From there, we arrive at this fine distinction: if a security feature is designed to keep you out, even if that security feature is very poorly implemented, then it is almost always unethical to circumvent it. Therefore, we should only study hacking using "practice locks", such as programs in our virtual machines.

What is wrong is to use your hacker skills in order to perform unethical actions. Hacking per se is not unethical, as it is not ethical or unethical to use a key to open a door. For the sake of comparison, a locksmith can ethically use her skills to open the door to your apartment... if you called her after you lost your keys. But if she opens the same door when you're away in order to steal your stuff, the same action becomes unethical, because the goal is now different.

Aside the goal, one has to think about the yield of a hacking attempt, i.e. what one would do when he actually found a weak point in a system. Let me illustrate this with an example.

When I was a student, I was talking with my friend about IT security and we started talking about SQL Injection. Long story short, I tried to connect to the University website using his name and " OR 1 = "1 as a password, and it worked. I got access to his account, his personal information, and, if I remember well, his e-mails. This is the actual hacking action, which, by itself, is not ethical or unethical.

From there, I had an ethical choice:

I could behave unethically and use this weak point to my advantage. For instance, I could push further, trying to connect to the system as a teacher, in order, for instance, to change my grades, or even sell a service to other students to “improve” their grades for a small fee. I could also spy on other students, stealing their personal information.
Or I could contact IT security staff, telling that they have a slight issue. This would be ethical.
Or I could do nothing, which would be an ethically-neutral action.¹

Same hacking action leads to three different yields with very different ethical aspects associated with them.

  if a security feature is designed to keep you out

What about a system which has no security features? Would you feel ethical doing whatever you want simply because security was not implemented?

Take an example of online games where each player competes against others. One system implemented a cheat protection system which could be easily circumvented given enough programming skills. Another system has no cheat protection whatsoever. How would cheating be unethical only in the first system, but not the second one?

Taking the same example of video games, imagine a different game where the competition notion doesn't exist—there is no online mode, and the score of an individual player is irrelevant for others. The system has a cheat protection system. Why would hacking this system be unethical?

  Therefore, we should only study hacking using "practice locks", such as programs in our virtual machines.

What about the locksmith who's opening the door of my apartment because I lost my keys?

¹ By the way, I did the ethical choice and contacted the staff. The staff never replied, not even to thank me, which taught me two things: ethical choices are rarely rewarded and if someone is acting ethically just to get a reward, he's not that ethical after all.


The ?: operator is not syntactic sugar (OK in most languages it is, and no guarantees/checks are made). It is a different construct.

if predicate then action1 else action2 is procedural

predicate ? value1 : value1 or value1 if predicate else value2 is functional

The first does something, the second evaluates to something. The value is that the functional form tells you that you are doing something functional, that there are no side effects. Thus making the code easier to read (once you have the vocabulary).

In this example

int x;
if(condition){
    x=5;
} else{
    x=2;
}

the reader must ask, can x remain uninitialized? What are all the values that x can take? Does anything else change or happen?

Where as for this example

int x = condition ? 5 : 2;

We see that we initialize x, to 5 or 2. That is it. We could also write

const int x = condition ? 5 : 2;

This tells us that x is x: it never changes.


Goal-oriented action
Part of this really depends on your goals in administering the exam.  If your goal is the traditional idea of creating a nice bell-curve to rank students, having a study guide makes very little sense. You can separate the wheat from the chaff without providing any assistance to the students prior to the test.
However, if you want to utilize the tremendous cognitive benefits of testing to actively help your students learn, then you're looking at a whole different set of priorities.  There is a lot of research on the benefits of testing in the learning process.  Unfortunately, I don't have access to my bookshelf right now, but the incredible book How People Learn summarizes the results very nicely.1
How do tests help?
Basically, tests accomplish two things that really help us to learn.  First, there is retrieval practice, which is simply giving the brain a chance to practice holding on to (and recalling) information.  The second is emotional: by giving the information heightened emotional importance, we increase our chances of actually encoding it.
So, where does a study guide fit in?  Having a list of topics isn't as useful as you might think for an examination. If I tell you that you're going to have an examination on "Operating Systems", there's not a lot to go on.  You might get to the exam and find questions about threading, or disk management, or you might find questions about how to transfer photographs between an iPhone and a Linux box.  There's little to focus your studies, and you may find that you have expended a great deal of effort studying things that your teacher does not consider to be the core, central ideas of the course.
My example is over-the-top, but this is done purposefully to illustrate the problem.  Your subtopics may not seem as broad as "Operating Systems", but in a field of effectively infinite knowledge, you are presuming that students have gleaned what the important core ideas are for your class from readings and from listening to you during your lectures.  For some kids this will work.
But what about the kid who missed something?  Perhaps they didn't understand something really fundamental about one of the sub-topics.  Or perhaps they got sick and missed a class.  Or perhaps they've just forgotten some things thoroughly enough that they really can't recall what the important ideas were.
Creating a good guide
A study guide is your chance to give some very gentle guidance.  Take your syllabus, and write a sentence or two for each topic that starts with, "Make sure you understand ..." or "You should be able to ..." or "The most important idea here is ...".
This is a relatively easy task, but even this small amount of guidance will help your students to focus their studies on the most important ideas of your course.
You can actually go a lot further with this effort if you want to, and there are good reasons to consider putting a lot of effort into the guide.  Your efforts here can have an outsized impact on your students.  This is what they will study, so what you put here is what your students are likely to remember when they leave your classroom for good.

1 - All I could find online were a few articles about single studies here and there.  This is probably the best I can do for now.


How to give students practice with streaming computation?

Java has a Streams API that works with all of its collections.  You create a stream with a source, transform or filter it with intermediate operations, and do something with it using a Consumer.

All Collections in Java have a .stream() method that creates a stream from the collection.  You can also create streams from files, as well as creating streams of random objects from a Random.

Intermediate operations include filter, which accepts a Predicate as an argument, and map and friends that can transform objects into objects of other types or primitives.

Consumers include facilities to place the contents of a Stream into any Collection, System.out::println, and other pure side-effect operations.

This requires an understanding of lambdas and functional interfaces (our second-trimester course in Java covers these).  This mechanism is powerful and succinct, and it does not alter the collection the stream is attached to.


How to handle objections to the wording of test questions or answers?

I am not sure what you mean by a "useful test" in this context.  If your goal is to create a bell curve with English speakers at the top, you could administer the verbal section of the SATs.

You say that your students are complaining because what you actually wanted from them was unclear without an eagle-eye reading (and from your own accounts, it sounds like this is the case).  If this is the case, then their complaints are legitimate.  It is perfectly reasonable for them to be upset that you are trying to trip them up in a manner orthogonal to what they are actually studying.

I'd like to differentiate two different forms of testing.  The first is meant to enhance pedagogy by plumbing the depths of a topic.  A great pedagogic test creates an occasion for students to consolidate what they know, but it also provides a means of discovery.  Almost everyone that I have ever spoken to about this can remember testing events when, after reading a question, they suddenly understood something that they had been missing about the topic itself.  This sort of test simply allows students to demonstrate whether or not they understand the material, which forms a sort of philosophical boundary.  If all of the students understand the material, all of the students will achieve close to top marks.

There is another form of test which is designed to rank students.  The boundaries here are different, and there is some psychological brinksmanship involved. Even if all of the students understand the material, they will not all achieve top marks.  There are a number of ways to accomplish this.  One is to simply ask a lot of tiny, very detailed questions.  Another is to use questions about the subject that don't even have to be particularly hard; you simply have to set enough traps.  The best and most capable students fall for the fewest traps (or so the thinking goes). Of course, using this second method causes resentment.

But very fundamentally, the goals and means of these two types of tests that are fundamentally different from each other. By trying to combine them, you ultimately wind up with a test that is good at neither.  And if students expect pedagogical tests that are designed simply to test knowledge, but instead they receive ranking tests, they will feel that their trust has been breached.  When students do not trust their teacher, learning is dampened.

We should not resort to verbal trickery to differentiate between students.  Make the questions harder by forcing them to integrate the material more deeply, or use it at a more advanced level.  They can reasonably become confused about how to accomplish the difficult task you have set before them.  They should never become confused about what that task is in the first place.


What kind of game (in Scratch) would require use of a list?

A variant on the usual random drill and practice test would be to pre-populate with the questions and answers, then remove question and answer from each as they get answered correctly, allowing players to get more practice on the questions they get wrong. Here's an example for times tables.

You could try something for an adventure game, building up an inventory of items collected in a list. Another possibility would be an adaptive 20 questions style game, adding additional questions into a database (of sorts) as the player gets to the end of a branch of the tree.


Best puzzle type to foster logical thinking

A fun and useful puzzle type is logical operators. Anything and everything that uses logical operators, and the more complex your operator, the better.

Working out how a mysterious logical operator works is a great way to increase, well, logical thinking. You really have to figure out what's the logical output.

An example puzzle would be:

Input: A B C (binary values)

(((A or b) or (not C)) and (C or (not (A and B))))

And then they need to figure out how this thing works. Building a truth table, figuring out tautologies or how one parameter can completely change what the operator does. ( I think C is like that, in the above example).

A very, very important skill this teaches is tautologies. Sometimes programming needs to be tautologous. The question of whether the program works should be true for every input which is allowed. While that isn't always possible (practical-wise), striving for bug-free code is, as I see it, a good thing.

It's also interesting to show the students how a very simple set of blocks (and,or,not) can be used to construct unbelievably complicated things; and to work out how those things work, the students have to develop logical thinking.

So logical operators overall improve a number of aspects of logical thinking.

(It doesn't add too much, but my personal experience has shown me that puzzles such as these are one of the only things that taught me logical thinking).


How many projects(within the same organisation) can one apply for in GSoC (google summer of code)?

For the Google Summer of Code I would interpret their student advice from the FAQ to imply that you can apply to as many projects as you like, but can only be accepted in one. It doesn't seem to be the number of organizations, but the number of projects.
Caveat. I don't make the rules. But given that Google is pretty experienced in such things, I'd guess that if you apply to more than you should, that the system will kick out the extras.


How to teach a person to enjoy programming?

Meet him where he lives. Take something he's already interested in and use programming to accomplish some goal within that interest. The act of coding is not the end goal, the final "product" is the end goal. Make it about that.

For example, you've said your son is interested in game development. Encourage him to create a simple game using a language like Processing or a tool like Game Maker. The keyword here is simplicity- your son will probably want to make Call of Duty or Minecraft. Encourage him to start with Pong instead, and work his way forward from there.

Maybe participate in a "game jam" like Ludum Dare together. The idea is to spend a weekend creating a game around a theme that's announced on Friday, and you can participate from your own home. The next official event isn't for a couple months but they run "mini jams" every other weekend.

It doesn't have to be game development though. The idea is to use programming within his existing interests so he sees the fun and utility of code naturally. If he's into sports then maybe write a sports simulator. If you travel then maybe have him create a travel log from Google Maps API. If he's into music, create a music visualization. If he's into movies, point him to video processing libraries.

But again, the projects you give him should be simple, so he can make visible progress on them in a short amount of time.

You might also consider being an example: what cool projects are you working on that you can show him? Can you give him a simplified version of something and have him "remix" it by changing variables and logic instead of needing to come up with everything himself?

Related questions:

How can I determine if a student would enjoy or has an aptitude for CS?
Which non-programming skills help make a good programmer?


What is a real-world (production-code) example of a function having default arguments?

I recently used default arguments to write an API method for a mail sending library: The method needs a subject, a body and a "To" recipient, "Cc" and "Bcc" are optional:
def send(subject, body, to, cc=None, bcc=None):
    """
    Send a message with the given data using the earlier configured SMTP server and the earlier configured from address.
    :param subject: The subject (one-line string)
    :param body: The contents (multiline string)
    :param to: Recipient address (string)
    :param cc: CC address (string or None)
    :param bcc: BCC address (string or None)
    """
    # The following to helper functions are omitted for brevity
    msg = _create_message(subject, body, to, cc, bcc)
    _send_message(msg)

I also quite often use this to specify default constructor arguments for machine learning setups, so that I can change the parameters when experimenting, but have a default variant during development:
import random

class MulticlassPerceptron:

   def __init__(self, epochs=100, learning_rate=0.9, random_seed=15):
      self.epochs = epochs
      self.learning_rate = learning_rate
      random.seed(random_seed)
      ...

   def train(self, training_data):
      for epoch in range(self.epochs):
         for datapoint in training_data:
            ...

train_dataset = ...
m = MulticlassPerceptron()
m.train(train_dataset)

Generally, I make quite heavy use of default arguments whenever I write scripts for myself, because for me they are a perfect compromise between those two objectives:

No one else than me will use the scripts, and my configuration is pretty constant, so there is no need for complex Config objects etc.
It is bad practice to hardcode things that are technically changeable parameters.

So what I usually do is write methods that have only default arguments which store my default configuration: This is an easy way to store a configuration (satisfies objective 1) but could be changed if the need ever arises (satisfies objective 2).
Does this help you? If not, I'm happy to add more examples.


Should test cases be made available to students for assessed assignments?

My best practice would be to provide students with test cases and require them to submit additional test cases with their code. Then run everyone's test cases against everyone's code. Let the students know that they will get extra credit if their tests break anyone's code. That will put them in a mindset of creating tough tests and writing bullet-proof code, rather than stopping when the pass the provided tests.


How do you deal with Lone Rangers in group projects?

This is really a separate approach from my first answer, which has received some push-back.

It's worth noting that many of these loners are simply students who are substantially ahead of the curve.  One way to really want to engage such students in pair programming is to pair them with each other.  This will create something of a Dream Team.

Give them the assignment, but tell them that their goal is to produce the coolest thing that they can that utilizes the concepts that the lab is developing within the time before the lab is due.  Tell them you're excited to see what they can come up with, that you'll allow them to present their work to the group at large, and that if it's a cool enough idea, you may use it as a launching point for a future lab for later generations of students.

As an aside, there is no reason to restrict this approach to the high-fliers.  It can be reasonable to allow students to propose modifications to the labs if these modifications excite the students.  It involves more work on your end, but you'll get better output and (more importantly) more engagement and buy-in from your students overall.


What's a good unit testing assignment for Android?

I assume that there is some logic in the app, somewhere. Hard for me to imagine it otherwise.

If you build the client side with a Model-View-Controller architecture, the testing can be done on the model (as is most natural) and possibly on the controller.

If the server side is also built by the students, then it may also require logic beyond data access. So that can also be tested, either directly on the server side, or with mock clients. Maybe both.

I admit, though, that I don't build these things.


How to avoid getting emotionally attached to my students' projects?

I think this an essential and main part of teaching programming and cs (and teaching in general). The ability to hold the answer and guide the student to it.

What I do is try to follow the thought process of the student. When working with them to help them find the problem, I ask various questions (usually "what do you thing is causing this?" etc.) and by their answers it's possible to see what sentences would guide them to the solution.

This method works great (that sound out of the sky but it's based on student feedback) as it allows the student to feel that they found it on their own. I find that they also learn to spot issues on their own afterwards.

Additionally, it's worthwhile remembering that you are the instructor, and not the student. And that the project is a student's project, so keeping that in mind often helps with holding back from doing the work yourself.

However when all else fails, showing the students how you might do it could be a last (last) resort. Just be sure to explain every step you're doing, so that the student understands. I cannot express enough how bad this last resort is. But if it gets to that, make sure you're not doing their work, but rather show them something similar


How to introduce Scala to a team of Java developers without being boring?

I'd start with something useful that takes yards of code in Java and only a few lines in Scala (assuming there are such things).

After two or three examples like this, you'll have hooked your audience. Move into a compare/contrast of language features. Talk about what's easier in Scala. For fairness, talk about what's easier in Java. Then move to how/whether you might adopt Scala in your workplace - or why it wouldn't be practical now but under what circumstances it might be.


I'm going to offer an answer that is orthogonal to your question by looking at a deeper question. The "work-flow" you seek may actually be irrelevant to the problem of (a) being effective with your students and (b) being efficient with your own time and effort. Hopefully, the answer here will be valuable to others who don't have quite the same context that you do. I'll focus on the small number of students and the long daily sessions, primarily. The answer will be less valuable for larger groups and/or shorter sessions, but some of it might be adapted.

tl;dr: Keep continuously aware of their progress, day to day, with short conferences. Restrict your evaluation to the most important issues as they evolve.

With only a few students and long sessions, there is really little reason to have to look at everything in detail, captured by GIT, or otherwise. This is one situation in which printouts sounds like a terrible idea also, though that is often the most efficient method of looking at student production.

You can both reduce your work and be more effective if you require some sort of teamwork, such as pairing. If you only have five projects to keep straight it is much easier than ten. You can, in long sessions, set aside say one hour in which each team consults with you for a few minutes on their current work and issues. They show you their current product and you give them advice. But if they are pairing, they will need less advice.

One concern you likely have is honesty. Looking at each student's (team's) work for a few minutes each day (or so) lessens the likelihood that you won't notice bad behavior.

One thing that will help you keep track of the students and keep them on track as well is to keep a running record of their progress. A Hipster PDA (discussed elsewhere on this site) is one way. A spread sheet is another. Decide before the course starts which low-level results/behaviors/activities are to be encouraged and valued and keep a record of these for each team, each day. A check mark is all that is needed for many things, though occasionally a written note (to them and/or to yourself) might be valuable. It is a continuing and cumulative process, not an all-or nothing evaluation at the end.

If students work in teams you can also keep yourself aware of each student's contributions to the team simply by listening to how they interact when you confer with the team. A quick notation on an index card captures your impressions for re-confirmation later.

If you need to give advice on code quality you don't need to look at it all at once, but can look at fragments (one class, one method) in a review and get a sense about whether they have it right or not. You won't catch every flaw, but you aren't guaranteed to catch everything in an overall review either. If several teams are going wrong in the same way you can alter your "lectures" to guide them back. If a single team/student is off the rails you can focus your efforts there, instead. None of this requires that you capture everything in a repository or even that you comprehensively review their work.

If design is one of your goals, you can focus your daily review on that, warning them the day before that you need to see designs, either on paper or otherwise.

Even if you don't want the students to work in pairs/teams, you can still use a different form of teamwork. You can, for example, set up a rotating peer review system in which each student briefly confers with another on each student's work. Each can give advice to the other. I suggest that the advice be written, say on index cards, with both student's names listed as well as the questions/advice/etc. You can quickly review these cards and can give credit to both the one receiving the advice (for responding appropriately) and the one giving it (for being a good colleague). You can use this instead of conferring with the students/groups yourself on some or all days. Students can teach each other and will if you give them the opportunity and encourage good behavior.


How to motivate game design/development students to do more than the minimum on homework

Something I wasn't sure about when I was reading your post was if the problem is whether the issue is if students lack motivation or if they lack the ability to succeed in your course.

If 30% of your students are consistently failing your course, then I genuinely do have to wonder if the latter is the case. If so, I'm not sure this is a  problem you can easily fix within just within the context of your course.

For example, I'm assuming the students are expected to complete a few pre-reqs before they can take your course. Why aren't those pre-reqs adequately preparing your students? Etc.

If the students are genuinely under-prepared and have "given up" and are just going through the motions so they can graduate, then the best fix is probably to try and systematically repair your entire department. Perhaps that might mean finding more ways to add in support (especially in the intro courses), making sure students know where to find support, raising the bar on core classes...

It could also be the case that the pre-reqs listed for your course aren't actually enough, and that you need to add another pre-req class or two to make sure your students are prepared.

If it's the former (your students are capable but simply aren't motivated), then here are some thoughts:

  We have tried things like offering a bit of extra credit for turning it in on time or going above and beyond on the assignment

Offering extra credit for going above-and-beyond is entirely normal and expected, but I think offering extra credit for turning assignments is counter-productive: it sets the expectation that turning in assignments late is ok, further normalizing that behavior.

In fact, if you're lenient about lateness, it would be stupid for a student to not take advantage of that leniency. The student is probably pretty busy/juggling a bunch of classes and other responsibilities, so naturally they'd want to use whatever advantage they can get.

Instead, I would institute a strict no-late-work policy (perhaps with some mild leniency -- give students a fixed number of late days they can use or something).

  Attempt to do more than just the bare minimum.

Same sort of thing as before -- if you're a busy student, then it makes sense that you'd do only the bare minimum needed to pass the class. In particular, the students probably aren't thinking of the work they need to turn in as the "bare minimum": they're probably thinking they're turning in exactly what's expected.

In that case, one thing you can do is to raise your expectations. Make the assignments harder, or (if there's room for creativity on the assignments) show students examples of good projects other students have completed in the past. Maybe tell students that they're required to complete at least one item from the "above and beyond" section (though they're free to chose which one they want to do).

You can also perhaps try motivating the students in other ways by explicitly telling your students that the purpose of this class is to help them build a portfolio they can show employers so they should put their best foot forward.

Making the assignments more interesting, as ctrl-alt-delor suggests, would also help. Making your assignments group-work might also help (and help partially compensate for the added difficulty).

  Listen to feedback for on-going assignments.

Getting students to listen to feedback is always challenging. I would first double-check that:

You aren't overwhelming the students with feedback -- if you give too much, they tend to ignore it altogether (I learned this the hard way).
The students are actually aware that they're given feedback, and that they're expected to read it. I'm not sure how exactly you're returning feedback, but if it's through some website, perhaps that website's UX is bad.
They're aware that the feedback contains info they're supposed to apply/contains warnings of things you're going to continue deducting points for.

Beyond that, I suggest telling the students about the "growth mindset vs fixed mindset" thing, as ctrl-alt-delor expects.

A somewhat more blunt tactic would be to modify each assignment (apart from the first one) and ask students to answer a question about their feedback -- something like "Summarize the feedback you were given on the last assignment. How did you apply what you learned while reading that feedback on this current assignment?". Basically, force them to at least think about their feedback, instead of avoiding it.


Multi-client to server connection demonstration

If your students are old enough to own phones and send text messages, then perhaps you could use group-texting as an example?  One person in the group sends a message to the others; the message goes off to the company's server, which broadcasts the message to the people in the group?  Depending on their age, that might be an example to which they could relate and that would engage them...

I guess it depends on how deeply you want to go.  You could delve into the details of broadcasting vs multicasting, in which the sender of the message (the server in your example) sets the correct bits in each packet and the underlying network takes care of ensuring that the right packets get to the right clients.

If there is no network-level support for broadcasting or multicasting, a "broadcast" among N clients can still be done fairly efficiently in a distributed manner, without involving a server. For example, suppose N is 8, the clients are numbered 0-7, and 0 (which could be your server) wants to broadcast a message.  Then...

At time 1: 0 sends the message to 4
At time 2: 0 sends the message to 2 and 4 sends it to 6
At time 3: 0 sends the message to 1, 2 sends it to 3, 4 sends it to 5, and 6 sends it to 7

This approach can "broadcast" a message among N clients in O(lg(n)) steps, so long as the network allows different clients to send simultaneously.  What's happening there is quite different from your cups-and-string demo...


In self-teaching, how can I move from basic tutorials to more complex work?

The short of it

There are three techniques that should serve you well in this, and future, endeavors to learn practical application of complex subjects:

Apply it,
Dissect it,
RTFM

The long of it (tl;dr)

Apply it

Install a database manager on your own computer. (Your personal home computer by choice, but a work computer is possible if the learning is sanctioned and supported by the supervisor.) It does not need to be the same system you have at work, or the same one you want to eventually "know." There are quirks to every DBMS, yet they mostly try to follow the SQL standards.

If a local install of a server with T-SQL is not possible, a good choice, in my personal opinion, is MySQL. MySQL has a developer and user community that is often helpful. The manuals, for many versions, is available online, or downloadable for local use. The manual includes explicit statements of how MySQL deviates from ANSI/ISO SQL standards. Having those differences delineated allows you to know what to watch for when developing advanced statements yourself. (There are serious syntax differences between ANSI SQL and T-SQL, but the logic behind what you do is what you need to learn more than the syntax, it seems.)

Take what you know about the SQL so far and rework old projects you've done using your new SQL knowledge.

The size of the old projects can grow as you work through them, but isn't all that important. It also doesn't have to be a project that requires a database, only that it could use a database. It's the long way around, and usually not needed, but a database can hold configuration information and initial state values. Doing so can even increase the re-usability of the original code. Since it is a project you've already done, the algorithm and program logic is something you already have a handle on, and applying the new knowledge to the old problem lets you focus on the new knowledge.

If you don't have any old code-based projects of your own, which is likely in you case, then you can still use an old "problem" from elsewhere. You don't need to have a program that uses the data, since learning the C# or Perl is not the objective, only the SQL. (Often the DBA has very limited skills in other languages, but is excellent at the SQL for their system.)

Dissect it

Obtain real code from existing projects that use the SQL that you want to learn. Read the code and learn to follow what the original coder has done. Try to figure out other ways it could have been done, and then figure out why they choose the method they did.

Next, look for things that might change in either the dataset or the use the data is put to. Figure out how to rework the existing code to accommodation those changes.

Next, develop the requirements for a new dataset to apply to a new problem. If it's useful in your work environment, that can be a plus for later, but it could equally be useful at home. (Movies: plots, actors, directors, awards, reviews, and your collection could make a useful project.)

As a part of "dissecting" what you want to use, learning to use a different system, such as MySQL or Oracle's database, can help by highlighting the differences and similarities. Looking behind the syntax to what the DBMS "does" to fulfill commands can help you make more efficient use of the commands.

RTFM (Read The Fine Manual)

In this case, the Manual includes any community that has developed around the server you're using. If you have installed one DBMS at home and another at work, then you have two communities to draw from. You can also use some SE communities in your learning. [dba.se] is one that you might find helpful, as well as the usual ones for developers.

Often, in the manual proper, or the community around the system, there are tips, tricks, and warnings that can make significant improvements in your understanding of the system once you can fathom the how and why of the given tips, etc.

The short of it (redux)

Take what you know, practice it, explore other uses, and practice some more.


Where, sequentially, do Interfaces sit in an introduction to Objects?

Ideally, interfaces come first. Before Classes. Interfaces define concepts. Classes implement those concepts. Don't think of them as an add-on to OO programming. Think of them as the essence.

In fact, if you present a pre built class to students, my guess is that you already, probably informally, give the interface first. Here is a class with public methods "accept" and "spitOut", or something like that. You probably talk about the public methods first and the necessary parameters and return values. More importantly, you probably talk about the intent of the class and of the individual methods. Most likely, and I think most common, only then do you discuss the implementation of the methods along with fields, etc.

If you start your discussion with the fields, on the other hand, you are (IMO) making a big mistake and that students will start out by thinking at too low a level and will write their code too often in terms of getters and setters. In other words the encapsulation will be inconsequential and possibly leaky. Then, in a program with a few tens of classes and a few hundreds of objects, but, perhaps thousands of fields, they will be thinking about the fields and how they mutate, rather than the concepts represented by the objects in the system. Their thinking will be at a lower level than is efficient (or even possible, in some complex programs).

But if you introduce the concepts first, and get them to (a) think in terms of those concepts and (b) implement those concepts faithfully they will be naturally led to think at a higher level of abstraction, which is really what programming languages are for in the first place.

Some rules that I'd adhere to with rare exceptions and no exceptions at the start.

  When you implement an interface don't give the class any additional public methods. Thoroughly document the intention of the interface and its methods.
  When you build a subclass of an existing concrete class, don't give the subclass any public methods that don't have signatures in the superclass. (Abstract classes can be a bit different, but it is dangerous and adding public methods should be delayed.)
  If you need new things in a subclass, extend the interface instead, as it represents a new concept, and implement that, rather than just extending the superclass, though you can also extend as an implementation strategy.
  Prefer composition of objects over inheritance. An object is composed of other simpler objects (representing their own concepts). With composition you will probably be able to

    a. Write simple classes (a few public methods)
    b. having simple methods. I get antsy when a method is more than about 4 lines or has any nested internal structure.

  Use simple design patterns to make it fit together. These are just another sort of concept and are themselves normally defined with interfaces.
  Avoid getters and setters (in interfaces and classes). They lead the student to think of everything in terms of mutations of implementation, rather than at a high level. I use accessor for a method that returns information (possibly a field's value, but not always or often), and mutator for a method that somehow changes the internal state of an object. A mutator might in fact have nothing to do with fields and might pass on a message to one of the implementing objects or set up a chain of mutations. Thinking in terms of setters is too narrow, but also too low level.

Some modern OO languages don't have formal interfaces, but you can normally simulate them to separate out the ideas from the implementations.

Note that the Standard Template Library (which I haven't used in quite a while) was, itself defined in terms of concepts and the term was (maybe still is) used in the literature. This was just a placeholder for interfaces that C++ didn't support.

The idea here is to build a software system in terms of readily understood concepts. The resulting system has its complexity in the interactions of simply understood things, rather than in the things themselves.

Note that I often write an interface when I intend only one implementing class. Capture the concept first.

Again, note that I often write an abstract class that has protocol (abstract methods) for every method in any intended subclass. This lets me capture a common implementation, but keeps my concept clear as I subclass. I never need to ask instanceof and I never need to cast an object reference. Everything naturally fits together freeing my mind to think of other (higher level) things.


How can I build up the understanding of a project?

I think it would be improper to give you advice on the content of your project. Your professor assigned it so that you would learn something and you will learn more by doing that part yourself.

However, I think you are making a mistake by assuming that after the original instruction from your professor you can't go back for more advice. But if you just ask for help you may get less than you need. Again, that is because the professor wants you to do the work.

I suggest you do this. Before you actually start the project, write up a detailed proposal for what you think you should do based on the studying you have already done. "This is what I understand. This is what I propose to do." Use your own judgement about what are the best steps to take. You may be correct or not. Doing it will help you refine your ideas, of course.

Then, show that to your professor and ask for advice on it. If you make it clear that you have "done your homework" you are likely to get better advice. If you can do this in a face to face conversation you will also get to ask some questions about what you still see as gaps.

It isn't necessary to go from point A to point Z without any intermediate steps.  And it isn't precisely correct to ask others to fill in those steps.


Ways to advance the field of computer science education as a non-researcher

Actually

(a) you don't need a doctorate to do research,

(b) most university faculty don't do research in CSEducation, but in CS,

(c) most conference committees don't care much about the formal credentials of those who submit papers to the conference. SIGCSE, for example, has quite a lot of work by people without doctorates.

However, what you probably do need is contact and communication with like-minded people with an interest and some writing ability.

I hope this doesn't become just a list of options, but there are quite a few.

Probably the most productive line for a person at a smaller institution is to try to make contacts with those writing and doing research in a field that interests you. If you express interest you might get included in their normal communication mechanism. Often people need to work remotely from colleagues, so you have no real disadvantage there. Find a paper that interests you and write to its authors to ask what they might be working on that you might contribute to.
If you are in an area with quite a few educators you might try to found a discussion group among teachers in similar positions. It could lead to bigger things, but you need to be able to keep up with what is going on through reading. Once established you might be able to invite a university educator to one of your meetings, spreading your contacts. You might also be able to extract an invitation visit any working groups that the University might have.
Try to find a way to go to either a national or one of the regional conferences of educators. You will meet a lot of people. The Consortium for Computing in Small Colleges holds a conference annually in each of the major regions of the US. I expect they will be happy to ignore the fact that you might be a secondary educator.
Get involved in APCS, not just as a teacher, but as a contributor. One option, if you have the time is to become an AP grader. This is an annual event in which you will work hard, but also meet a large number of people interested in CS Education, some from the Secondary Level and some from Universities.
One of the groups that should probably interest you is the people who write Pedagogical Patterns. These are based on experience, not research, and go through a vetting process to validate them to the community. Among other things they do is help one another write (shepherding) and a formal process of feedback at the periodic conferences (workshopping). Any pedagogical pattern you are likely to see has been re-written a dozen times with feedback from, perhaps, a dozen to twenty people. It is a vibrant community.


What resources would you recommend for K-5 Computer Systems Concept of the CSTA K-12 Standards?

I haven't seen a lot of resources in the US for that age group, though England seems to publish a great deal of high quality KS2 (Key Stage 2, ages 7-11) material.  What's particularly nice is the focus on Computer Science concepts and computational thinking over simple programming exercise, even at this young age.  Take a look at these BBC Resources from the "Bitesize" Series, which is a series of instructional videos appropriate to those ages).

There are also collected resources here, which includes such regulars as Scratch, but also points to some lesser-known resources, such as Code Club, which has projects appropriate for the age in various languages, and Kids Ruby, which teaches kids to program in the Ruby language with guided tutorials.


The only way to learn a lot of things, maybe most things, is practice and feedback. In a standard course (not online), the professor assigns some work to do - homework, projects, .... The professor then gives you feedback on it - grades, but hopefully more.

To learn on your own, you want to try to simulate this as much as you can. So, to learn something, you not only have to see and hear about it, or even read about it, you have to do it. Moreover, you need some way to get feedback on the success of your efforts.

If the videos don't suggest projects then you will have to find them elsewhere, perhaps in a textbook. Do a lot of small and large projects.

But then the feedback part is just as important. One possible way to simulate that is to work with a friend in your learning. Each of you does the same exercise separately and then exchange your work and each comment on and improve the other's work. This isn't perfect, since the other person isn't an expert, but it is better than nothing.

You might even be able to use an online forum to get comments on your attempts. The Code Review here, might work for you, though I don't know how welcoming they are of novices.  Be sure to see their "help center" for guidance.


Suggested fliers for high school career fair?

All of the best fliers I found were at the NCWIT website:

Computer science is for everyone, pp. 13-16
Why Should Young People Consider Careers in Computing and Information Technology? (also in Spanish)
Community College Pathway to IT and Computing Careers
University Pathway to IT and Computing Careers
Which computing pathway is right for me? (also in Spanish)


How to verify that code you write is not copyrighted anywhere?

Don't worry about "similar" code. Copyright is about copying, not about similarity. If you wrote it independently of any other, then there shouldn't be an issue.

But there is also the rule that in some situations there is "only one way" to say something. So if some phrases (or coding patterns) appear in several places it isn't evidence of infringement. The number of ways you can write an iteration through a list is pretty small, after all. Problems recur in computing. So the "natural" programs that solve them also recur.

Also, copyright is about publishing. If you don't publish your code then it won't be an issue either.


What ethical practices do students (as potential software engineers) need to be trained in?

I'm going to begin by quoting Ken Thompson's Turing Award Lecture "Reflections on Trusting Trust" (link).

  To what extent should one trust a statement that a program is free of
  Trojan horses? Perhaps it is more important to trust the people who
  wrote the software.

In my mind the first and most foundational lesson to impart is this: software, computers, technology -- these things are more about people than about code. There is a trust from the end-user, whoever that user may be, that must not be violated. Users are not means to an end; they are the end. The code is the means.

I am reminded of the Second Formulation of Kant's Categorical Imperative:

  Act in such a way that you treat humanity, whether in your own person
  or in the person of any other, never merely as a means to an end, but
  always at the same time as an end.

In terms of integrating ethics, the way to start in my mind is discussion. Early and often. Share news stories. Discuss implications of new apps students download. The first 12 minutes of this CS50 lecture cover the the Volkswagen/EPA scandal from 2015 and mention Ken Thompson's lecture. It is essential that awareness is built right from the beginning that software is everywhere and there needs to be an ethical code to guide that development. In my mind, while I wouldn't consider myself Kantian, I do think his point about means and ends is essential.

The AP Computer Science A curriculum outlines the following requirements under the major topics of the course:

  VI. Computing in Context

  An awareness of the ethical and social implications of computing
  systems is necessary for the study of computer science. These topics
  need not be covered in detail, but should be considered throughout the
  course.

  A. System reliability

  B. Privacy

  C. Legal issues and intellectual property

  D. Social and ethical ramifications of computer use

Similarly, in AP CS Principles, students, as a part of the Explore Task, have this on their rubric for the assessment:

  Analyzing Data and Information: Identifies one storage, privacy,
  OR security concern. Explains how the concern is related to the
  computing innovation.

The moral of the story here is that ethics must be discussed with students as soon as possible whether it is a high school AP course or an introductory computer science course at a university.

This idea of trust must be imparted to students, and it must be emphasized that the world of software engineering and computer science in general is not in a moral vacuum. It does no good to address a particular issue, say data privacy, without first contextualizing it within a larger ethical system, one that sees each user as an end, not a means, and as someone who is placing trust in you the developer.


Should students be taught to be first and foremost: scientists or mathematicians?

This answer addresses something very different from the other answer I posted on this question, which is why it merits its own answer:

Almost every field in computer science is built on some mathematical theory (this sentence is the only overlap between answers):

The most basic: the number of options that an $n$ long binary number is $2^n$, and that's where it all starts (until Quantum computers come along, but that's something else)
Algorithm correctness: proof by induction.
The entire field of boolean algebra. Need I say more?
The entire field of Machine Learning is nothing but computations of mathematical models (Neural networks are nothing more than the simplest of arithmetic calculations - weighted sums of weighted sums of...)

This list can go on and it strengthens the point that, regardless of learning mathematics before learning Computer Science (that is, learning math with the intent of learning basic Computer science), most applications of computer science are implementations of mathematical models.

This means that when learning a subfield of computer science, an introduction to the relevant mathematics is almost always necessary.

That being said, being a talented mathematician surely would not harm one's level of understanding of those subfields of Computer Science.


Looking for good Master Theorem examples

A famous example is Strassen's matrix multiplication algorithm, whose running time satisfies the recurrence $T(n) = 7T(n/2) + O(n^2)$. A similar example is Karatsuba's algorithm for fast integer multiplication, whose running time satisfies the recurrence $T(n) = 3T(n/2) + O(n)$. Other algorithms for multiplying matrices or integers supply even more examples of this sort.
The running time of the median-of-medians linear time selection algorithm satisfies the recurrence $T(n) = T(0.2n) + T(0.7n) + O(n)$, which might be too challenging to analyze.
FFT is a classical example of an extremely useful divide-and-conquer algorithm, whose running time satisfies the recurrence $T(n) = 2T(n/2) + O(n)$.


How is your teaching affected by how you learned?

Basically, you have to throw away your preconceptions and develop and refine new intuitions based on your teaching experience and your students' backgrounds.

When I started off teaching I was severely limited by an expectation that I'd be teaching students much like myself - students who enjoyed math and abstract problem-solving, and who had some kind of background or at least prior interest in programming (I started off at age 10 in BASIC on my Commodore 64).  When that wasn't the case I found myself in a bit of trouble.

The way I teach now involves collecting and analyzing student data to find out what their challenges are and experimenting with different ways to help them overcome those challenges, and also what their interests are and how I can change the course to cater more to those interests.  I collect feedback in the form of quizzes and projects but also I just ask the students what was easy for them and what was difficult, what they liked and what they didn't like, and then the next year I modify the course slightly to take all of this feedback into account.

Over time, the course gets better.  I find ways to work around the most difficult material until the students are both conceptually ready for it and confident enough in their programming abilities to actually attempt it and not give up right away when they hit their first bump.  I find ways to include more things of the type that students like and find fun and interesting, even if I personally don't find those things fun or interesting at all.  Programming is so big and flexible that there are usually numerous ways into a problem, and luckily I get to make my own curriculum so I am free to explore all of those ways.

For one example, I've found that my students find variable manipulation and iteration monstrously difficult but have no problem with event-driven programming.  I've therefore had more success when starting students off with simple event-driven projects (like, make a browser-based multiple choice quiz in JavaScript) than with the kinds of math challenges (calculate the nth Fibonacci number) that I enjoyed as a student.  I personally find math problems easier and more rewarding than messy UI stuff and JS DOM manipulation, but the kids seem to really enjoy making a nicely decorated quiz to show off to their friends.  Also, most of my kids hate and fear math, which I find sad but have very little influence over.  I later try to work in simple variable manipulation and iteration by building on students' already successful projects once I have their interest and confidence.

So as a general strategy: Try to vary the order in which concepts are introduced and see if one order works better than another.  Try to identify the conceptual building blocks that students who fail to learn the concepts are lacking, and try to find ways to teach those building blocks - or put off teaching more difficult concepts until students have more confidence and problem-solving experience.  Try to give students projects that both motivate them and teach concepts and skills that you want them to learn.  When in doubt, simpler but more feasible and authentic projects are often better than more rigorous/complex projects that students may not even complete or will complete and then never look at again.  You'll know you're successful when students tell you something like "I made a quiz to teach my little sister the 50 state capitals".


How do you distinguish jargon from normal language in explaining a concept?

In direct answer to your question: not much.  I keep my approach here very simple.  I do as I would for any other time that a word could have two meanings.  If the word use feels ambiguous, I clarify which version I mean.  If it doesn't, I let it stand.

It sounds like you're trying to put a lot of careful discipline into your speech patterns.  There's nothing wrong with that; it's admirable!  It may even help to stem a bit of confusion, but I honestly haven't found that being more relaxed (and clarifying as needed) has caused many roadblocks for my students, so I don't worry about it too much.

I do occasionally discuss trap words when first introducing them, just to make clear to my students that there are now two meanings in play.


How useful is English (pseudocode and documentation) in aiding understanding?

Funny, I came here to look for advice on getting students to write pseudocode, because mine struggle so much to do it. So here is why I want them to do it. If I set the activity up properly, and they engage with it, then they will really be planning their program before they start to write it. There are different reasons people like to "dive in" to code. Sometimes an entire solution just occurs to you and there's no reason not to start right in. But sometimes, it's because you don't know any other way. Just start typing and see what pops out. This leads to "programming by perturbation", where you arrive somewhere kind of close to a solution by a mix of chance and lucky guesses, and just kinda change symbols here and there until it "works".
I've tried assigning flowcharts over the years, but I think pseudocode works better for my teaching style. I can explain more clearly what I want the students to try to do. They still resist, and because the little details (like for loop fiddling) are still more enticing to think about than the big picture of how the program will do its job, I still have to nudge them and encourage them to keep the birds-eye view. So for me (and perhaps this also addresses other comments on your question), it's not so much that pseudocode is really a great way to think deeply or at a high level. It's that insisting on a natural-language description of the problem and its solution seems to be an effective path toward my goal. And what is the goal? To make sure that the learners have a mental model of what their program should do—all or most of the way through, not just the first step, and perhaps even anticipating some tricky edge cases—before they start nesting up a bunch of for loops and break statements. That's the first thing, the immediate goal of the lesson.
Now to really answer your question, my experience suggests that learners can learn the most when they explain their solutions to others. This is not really possible to do, unless you've practiced the kind of communication we're talking about. You don't explain your program by reading the listing verbatim. You have to paraphrase it so that its parts correspond to your mental model, because the model is ultimately what you are conveying to the listener. In fact, I'm much less interested in whether students can produce programs that solve the problems I pose than in their thought processes along the way, which they can only convey to me by explanations in the natural languages we share.