Problematic student at a very high level I teach a high school student who has already developed an understanding of the language used in my curriculum and causes difficulties. The lectures and programming projects in the curriculum bore this student, and as a result, he doesn't cooperate when it comes to doing the coding labs and projects. He simply doesn't agree to do the work. An obvious "solution" is simply to give him a low grade, but it is not an ideal solution, because he has readily mastered the material.

Specifically, what techniques can I employ to encourage him to work on projects and to cooperate? Alternatively, what changes can I make to project guidelines for such students?

Tests reflect that the student knows the material (though it is clear that he is disdainful of the way it is taught).

The best way to deal with this kind of student is to head it off at the pass.  If you can get the student at the beginning, you can often prevent the problem from festering in the first place. I have a student coming in next year who I have already been warned will have this problem, and I plan to show this to my class on the first day:

I will then say something like, "For whom is this situation unfair?"

When the kids point to the fish, I will point out that it is just as unfair to the monkey.  I will then ask them to talk to a neighbor and figure out why.

I will finish up by saying that I have a promise for the fish of the class: everyone who puts in the work will be able to climb the tree.  That's MY job.  However, I have to find a way to be fair to the monkeys as well.  That means that I must reserve the right to try to find ways to push them to get better in my classroom.

If they are in that position, and can get the work done very easily, and find that I give them harder work, I ask a few things of them: (1) understand that this is fairer than it may initially feel, and (2) understand that this comes from a place of actually caring about them as people. Making more appropriate assignments for them is harder for me as well. If I didn't care about them as people, I could just let them get away with the minimum.

In essence, then, I am trying to recast making differentiated, harder assignments into something that the students will understand as both a loving act, and one that respects them deeply as individuals.


Best book and video lecture series to follow for an "object oriented programming" course for advanced undergraduates I am looking for an elegant text book to be followed for self study in an objected oriented programming course at the undergraduate level. Our course is as shown:

I humbly request to suggest me a book which shall help me in self studying the concepts which are given above, a book which shall be like an instructor and make me understand the concepts excellently. I know the basics of Java but I am unaware of the most the technical terms used in the curriculum attached above.
Our course instructor is a bit weird and she is going on just reading the Java reference book by Hebert Schildt in the slide of each class and she does not explain the points given in the curriculum like iterator patterns, Model-view-controller pattern and others. When I asked her what is iterator pattern, she said that it is a loop, that's all.
I do not want to study the subject just for name's sake (superficially), I always attempt to master what I learn. Please could you help me out?
Moreover, if anyone could provide me video lectures to go hand in hand with a text book, then it shall be helpful for me. I do not like the way I am being taught at our place.
Thank you. Hope you can understand my trouble... I beg to help me out.

[I am not worth criticizing the instructor, but it is my utter frustration which has made me put this question here, so that I can get hold of some suitable and good learning resources.]

Two books come to mind. Both build a project and you learn about object-oriented program design and testing. However, both assume at least a good grasp of basic Java. Nether will cover all of the topics you mentioned, nor do they have videos, but will give you a good idea of how to develop larger programs. You will learn a lot by code reading and osmosis. Both books use Java for implementation.
The first book (https://csis.pace.edu/~bergin/polymorphismBook/index.html) builds a simple four-function calculator. It emphasizes test-driven development and assumes at least a simple knowledge of JUnit testing. The book shows how to decompose a problem into small manageable pieces and take advantage of polymorphism (hence the name of the book). I also like the companion book as it takes a further look at the same problem, but with alternative implementations. Both are paperback books available for approx $20. The author's web page (https://csis.pace.edu/~bergin) also has links to a lot of material he has written.
The second book (http://craftinginterpreters.com/) builds an interpreter for an object-oriented language. It is a far larger and much more complex project. The author does an excellent job of explaining concepts and demonstrating incremental development. If you just made it through the chapter on Scanning, you will have learned a tremendous amount. You will have a much better idea of how Java takes your source files and breaks them down into pieces. Best of all, the book is free to read.
Lastly, if you like videos, check out (https://online-learning.harvard.edu/course/cs50-introduction-computer-science?delta=0). It is Harvard's intro to CS course and covers a whole variety of topics and languages. You can enroll for free and actually do the assignments or just watch videos and work on your own. The instructor is wonderful.


Finishing College with Employable Skills Last week, 4 students from another college approached me with a scenario. They have a year of college left in them. That means, they will be occupied with all sorts of final year things that may and most possibly help with their career.

Now, they want me to help them earn some skills. Something that might help them land some kind of employment. I have seen other posts on the site about the languages taught in the beginning and so on, but these students are not exactly beginners. They have finished 6 semesters and have a half baked idea and some exposure to languages such as C, C++ and Java, and may be even some dot net and Linux. However, nothing is employment worthy.

So, now, I have some decision making to do. What do you ask them (and of course, guide them) to learn? Here are my options (and feel free add yours)

Essential Web - HTML, CSS, Javascript and jQuery. - This is something that is a basic requirement for a lot of jobs where I live. I also believe this is something anybody can learn, even if they are short on time.
Java (with Android) - Learn to build an app. Android is pretty straight forward, and does not really require a thorough knowledge of Java itself.
Dot Net with C# - Tougher to learn, they may just run away with the complexity involved.

So, I am partial to Essential Web because of the simplicity involved both in terms of time, and also cost. A very basic laptop (perhaps even a used one) is good enough to get them started.

Still, what should I do?

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

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

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

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


How to teach the importance of indentation I'm trying to teach why indentation is important, but the student doesn't indent. I asked why he doesn't indent, then he answered "That's because it’s a hassle."
It's OK to say "you should indent", but I want him to understand why indentation is important.

How do you teach why indentation is important?

It has taken me a long time to get to a point where my students regularly indent properly.  I basically use a 4-part strategy.  (My work here in the context of AP Computer Science, so my examples are all in Java)

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

Second, I grade most of their labs right in front of them, code-interview style.  The first assignments are always quite simple, so I focus in on indentation, variable names, vertical space1, and the four Cs: clarity, clarity, clarity, and clarity.

I talk through the clarity of their code in depth and inflict outrageous penalties for unclear code, but allow them to go back and refactor for a better grade with no penalty.  Rinse, lather, and repeat (as needed).  The first lab is always painfully time-intensive to go through, but by lab 3 or 4, much of the code (and the grading!) is fast, smooth, and clear.

Third, I provide a few monstrous code examples throughout the year like this:

int n = 17;
if (n < 5)
if (n > 10) System.out.print("A");
else System.out.print("B");
if (n > 17)
if (n == 17) System.out.println("C");
else System.out.println("D");
else System.out.println("E");

It doesn't take a rocket scientist to figure out that poor indentation is the one and only reason that this code is so difficult to read and understand.  In case they miss it, I also reinforce this point verbally every time I give examples like this.

Fourth, the group work that I give requires them to have to provide code to each other, and make sense of what their peers have done.  Over time, they start enforcing norms on each other.

1 Vertical space, you ask?  Two reasons: first, because vertical space is used to separate ideas, like paragraphs, and second, because the very mention of this problem in their code shocks students immediately into thinking about how everything that they write helps to serve clarity.


Concrete example for polymorphism use? I am preparing a lesson about polymorphism in C++ and I would like to give an original example other than animals and shapes and I am really struggling with it because I realize polymorphism is not that useful for real concrete applications.

Can someone suggest a good example of polymorphism use?

Say you want to present a choice of interactive games

   out.println("Which game (...) ?");
   Game game;
   switch (in.nextLine()) {
   case "HI-LO" :
         game = new HighLowGame();
         break;
   case "Riddle" :
         game = new RiddleGame();
         break;
        ...
   }

Here you are. You have polymorphism. The game variable may refer to objects of different types.

Now, how to play a game (in textual form) ?

     out.println(game.getPresentation());
     while(! game.isOver()) {
         out.println(game.getQuestion());
         out.print("> ");
         game.submitAnswer(in.nextLine());
         out.println(game.getMessage());
     }

Polymorphic code. Now what is in a Game?

    interface Game {
        String  getPresentation();
        boolean isOver();
        String getQuestion();
        void submitAnswer(String line);
        String getMessage();
    }

An implementation ?

class RiddleGame implements Game {
    String getPresentation() {
         return "What cheese is made backwards?";
    }
    String getQuestion() {
         return "Guess it!";
    }
    boolean found = false;
    void submitAnswer(String line) {
        found = line.trim().equals("edam");
    }
    boolean isOver() {
        return found;
    }
    String getMessage() {
        return found ? "you got it:" : "no, it isnt";
    }
}

Boring java details omitted.

[rant]
Most introductory examples for OOP are utterly silly and totally inadequate to explain that classes are here to offer services. This unfortunate fact leads them to a lot of misconceptions.
[/rant]

The purpose of OOP is NOT to build taxonomies of animals, or make container objects with a getter and a setter for each attribute. It is not to model even a simplified view of the real world. It is there to write code which does something.

Oh, well, I see you don't like the RiddeGame because it knows only one joke.  So introduce a RiddleProvider as a parameter, whose job is to supply a Riddle  (question + answer pair).

You can imagine several kinds of RiddleProviders, so it is itself an interface with different implementations.

The simplest is the AlwaysTheSameRiddleProvider, which only know one joke, just like me. Others can run a predefined sequence, or a random choice, from an array, or from a file. Again, they offer a service to be used by another object.


Method for keeping records in a computer science notebook? Which recording method is best used for computer science. The Cornel method or the subsequent method developed by Scott Young who mastered the MIT program in a year.

To be honest, I have problems keeping notes. Or it’s rewritten textbooks. Or it’s rewritten truncated textbooks. Or these are bare examples without explanation.

When conducting a synopsis, my thoughts are not logical and not consistent. Well, speaking in short, when I open my synopsis, I don’t understand anything in it.

Based on what you say about yourself, I'd guess that the Cornel system is probably better than either of the other two described here. But that is just because you suggest that you seem to lack the ability, currently, to pull out the big ideas as they occur and the other two methods depend on doing that.

But, the goal of all of this isn't really effective note taking. You can have the best notes in the world and still not learn anything. The goal is to learn and to do that you need to reinforce the ideas that are presented, not just capture them in notes. But note that the Cornel system, as described at the link, includes this step as an essential part. Review the notes you take.

I'd go farther, actually. Not only review the notes, but write summaries of them periodically. And don't wait too long before doing that, so you don't lose the track of what you were learning in the meantime.

Another reinforcement trick is to write the important ideas on note cards and always carry a few of these around with you, along with a few blank cards and a pen. Then you can review while otherwise spending wasted time waiting for a bus or whatever.

But in a subject like CS or mathematics where you are actually expected to do something with what  you learn, it is also important to do exercises and solve problems soon after any lesson. This will, again, firm up the learning. Even better if there is someone to give you feedback on your solutions. This normally happens when exercises are assigned, but you might have to arrange it on your own for others. Study groups can be useful for this if they are well designed, requiring actual work from every member. Reading solutions is nothing like producing them.

For what it's worth I now just capture ideas on directly on note cards. One idea per card. I can then group and rearrange the ideas by physically manipulating the cards. Summaries can be developed from the cards. Questions can be written on the backs of the cards. Different colored cards can be used for different sorts of things.


How can I help my students to think algorithmically? I teach 13-14 year old boys an "Introduction to Computer Science" course.  For most of them, it is their first structured coding experience.

Before we even touch an IDE, I have them walk through problems like this:

  Devise an algorithm that calculates a user’s paycheque.

  The program will begin by welcoming the user.
  It will then ask the user to input their hours worked.
  It will then ask them to input their rate of pay.
  It will then calculate their total pay.  You may assume no deductions due to taxes, fees, dues, etc...
  The program will then exit with an appropriate exit message.

The correct answer usually looks something like this:

Begin
  print welcome
  input hours
  input rate
  pay = hours * rate
  print pay
  print goodbye
End

A progression to flowcharts then follows.

I guess what I'm asking the group is "How do you teach students of this age and ability to think algorithmically?". I've been teaching C.S. to this age group and ability level for about 15 years or so now.  I find that the problem statement/algorithm/flowchart model is about 95% effective.  I'd estimate that only 5% of the students that I encounter can't break the problem statement/pseudocode barrier. I'm always looking to solve this problem so any constructive criticism this group can offer is greatly appreciated. Even age appropriate resources would be deeply helpful.

Rather than giving them processes to model algorithmically, have them start coming up with algorithms for everyday activities. Here is the formal assignment I have students complete: CS50 AP - Everyday Algorithms.

They begin with a simple pseudocode example:

1   look out the window
2   if it is raining outside
3      put on your rain boots
4      put on your raincoat
5   go outside

After they get comfortable with pseudocode, students write their own simple algorithm:

  Okay, now you’ve learned a lot about algorithms and pseudocode.
  Perhaps we should try writing a few—three, to be precise. First, write
  up algorithms (both in sentence form and in pseudocode) for how to:

  brush one’s teeth
  eat an orange

  Next, think of something that you do every day or nearly every day.
  Write an algorithm in sentence form and in pseudocode for how to do
  the thing you’re thinking of.

Students will take more ownership and may understand it new ways if they are coming up with the processes to model based on something important to them. While your example certainly works well, what about students for whom getting a paycheck is unfamiliar territory? You want to use a student's prior knowledge to your advantage, so the focus is solely on the algorithm, not the algorithm and some other idea.

Another essential element I found to getting students to think algorithmically is to model it in all things I do at the start of the year. Everything is a process as follows: input -> algorithm -> output. Let's say I want to take attendance or assign seats. I think out loud with an algorithmic process. My input is an uncounted group of students, and my desired output is a counted group as a means of attendance. Here's the algorithm I use, which I borrow from CS50's first lecture at Yale:

1 stand up and assign yourself the number 1
2 pair off with someone standing, add your numbers together, and adopt the sum as your new number
3 one of the pair should sit down; the other goes back to step 2

The value of this exercise is it gets student moving. Differentiation is essential for teaching students to think in a new way. Get them moving and talking to each other. Make it relevant to their everyday experience.


Event-driven or polling for beginning programming environments? In beginner programming environments, I have noticed an essential difference in style for handling user interaction. Scratch and Alice are event-driven, while Processing and Greenfoot, for lack of a better term, are poll-driven. In the event-driven case, when the user clicks the mouse on something or types a key, a method is called to handle the event. In the poll-driven case, in order to respond to user actions, the programmer puts if statements into an update method that is called every frame to poll the input.

I like to use these beginning programming environments in beginning classes, especially for game programming. I'm not sure which approach is better, though. Event-driven programming is easier for programming GUIs, but poll-driven programming is better for simulations. Neither one seems best for all types of games.

Which approach will work the best for programming games for beginners? If I wanted to design my own environment, which style should I use? Are there any other styles?

On the face of it, event-driven programming seems far easier to explain. "This code will run when the button is clicked" seems obvious, and similarly, visual environments that favour this technique seem relatively intuitive:

It would seem obvious to explain that the code below that block runs when the sprite is clicked.

Similarly, in Node.js, an event-driven programming language:

app.get('/', function (req, res) {
  res.send('Hello World!')
})

With some basic knowledge of the framework used (Express), you can tell that when the / route is accessed, Hello World! will be sent.

So, without looking too deeply, event-driven programming is the obvious choice. But, this isn't the end of the story. If you're not used to event-driven programming, the fact that your code might not run in the order you expect is very confusing.

fs.readFile('foo', 'utf8', function (err,data) {
    console.log(data);
});
console.log('Hello!')

Two things will print here: the contents of foo and the word 'Hello!'—but which prints first? The answer is: you can't tell, despite the intuition that many students have that would suggest the order is file then 'Hello!'.

Event-driven programming starts to encounter a lot of these 'gotchas' because it's difficult to predict in which order things will happen. Ideally, each event wouldn't need to consider any other event happening, but in practice it is necessary.

Let's say you wanted to end the game if your spaceship was touching two others at once. With events, you could need to subscribe to 'Touching [spaceship1]?' and 'Touching [spaceship2]?' and synchronise them (not terribly straightforward). But polling like so would be far easier—for each update loop, just test if(touching(spaceship1) && touching(spaceship2)).

Getting to your original question, I would personally introduce event-driven programming first, since it's so straightforward for trivial use-cases. As the problems start to appear with events, then introducing polling in an update loop would be wise. Most of the major introductory programming environments seem to follow that (Scratch -> Greenfoot, etc). The same principle should apply to your own environment, I think—consider your audience and what they'll be using your own environment for, and you'll have an answer that suits you.

You might also find Polling vs event driven input on Game Development Stack Exchange interesting for reference on the problems faced by professional game designers regarding events vs polling.

The only alternative, perhaps, would be to batch events from inputs so that they can be handled in the next update loop—that's something to consider if you're looking for another way of handling the issue, but it is more complex than the others.


Why are pointers a key topic in a CS curriculum and oft cited as something people don't get? I was reading a Q&A on Meta Software Engineering and saw some people make reference to pointers, as well as this SE.  I see several Q&A here relating to pointers as well.

I don't understand why people make such a big deal about pointers. Most times I've heard about them, in school or talking to the occasional programmer, it's been made to be a big deal.

Conceptually, it's trivially trivial to understand:

  Go here to get a variable.  Oh, it's not the variable, it's a sticky note telling me where the variable is.  OK, I'll go there instead.  Goes to that other place, gets the variable.  Done.

It's more difficult for me to understand why it's a Big Deal. I've never programmed where I needed to worry about them, aside from in a CS class, nor have I programmed where pointers were not how things were done.

Are pointers difficult to use in practice?  Why is this a cliche topic for students?  I can understand that this was a big deal when it was a new technology.  But aren't most modern languages so much more abstract that this isn't a thing?

This question is actually not so far off from asking why operating system memory management can be confusing to some students.

Ultimately, we only have two fundamental tools for managing memory: pointers, and calculated offsets from pointers. That's it. In spite of GypsySpellWeaver's assertion, they don't particularly support OO, they undergird literally everything.

How does the computer know what line of machine code to execute next? Pointer. How does it know where the stack frame currently is so that it can find your variable? Pointer. How does it know where the system functions are so that it can print to the screen? Pointer. Pointers are not hard at the most trivial level of understanding. They are hard because, when you actually start to look into how they are used (or manipulate them yourself), you wind up deep in the weeds in some confusing places. They are the simplistic entry point to a host of deep, rich, and complex ideas.

Here's a quick "for instance": students don't come in fundamentally understanding the stack and the heap, and without that, much of what we do with pointers doesn't make sense in the first place.

Understanding memory in a computer is not a trivial task.  When I write

int z = -1

... a student naturally expects z to be a number.  But, of course, it's not. It's a reference to a stack offset at which is held a series of ones and zeroes.  The compiler stores z as something like stackpointer+8, and that's what gets written into the compiled code. The name z goes away.

char* x = &z + 1 is literally nonsensical, unless you understand that memory is fundamentally typeless, and what a memory address actually is.  This isn't trivial stuff for someone whose whole experience with computers has been installing and using apps to play games and chat with their friends. Nor is the result of printf(x), or printf(*x).

Fundamentally, a student needs a rich mental model of the whole machine to understand pointers on anything beyond a trivially simplistic way.


Greedy Algorithm Approach One of the popular algorithm design techniques is the Greedy Algorithm.
Do we have real-world examples of Greedy Algorithm which we can teach Undergraduate students?
I know the famous Djikstra's algorithm, Prim & Kruskal, Minimum spanning trees, etc.
I want some examples which are very common in our day-to-day life.

One example which is actually relatively common in everyday life, especially for people who do a lot of traveling (e.g., backpackers and some business people), is the knapsack problem. The applications section gives several other fairly common situations where this problem is encountered. The Wikipedia article also lists a few methods that can be used to determine a solution, but especially for relatively simple cases, something like the greedy approximation algorithm can be implemented fairly easily, and often works relatively well.
Nonetheless, as that algorithm section states, a basic greedy algorithm may sometimes be far from optimal. I don't know of any examples offhand, but I suspect it should not be overly difficult to construct (or perhaps find online) a relatively simple one that would help to illustrate this point to your students.


Explaining how an Interface is a contract When teaching Interfaces (in Java, for example), it is common to describe them as a contract. Which means that if a class implements an interface, it has to use the methods in the interface.

As an example, the students are shown the following:

public interface Edible {

    public boolean hasNuts();
    public void eat();
}

and then

public class PeanutbutterSandwich implements Edible {

    //now  we have to implement the methods in Edible
    public boolean hasNuts(){
        return true; //just as an example
    }
    public void eat(){
        if(hasNuts())
            System.out.println("I contain nuts!");
        else
            System.out.println("I don't contain nuts!");
    }
}

The problem with this example is that students don't always see how the interface acts as a contract. How could I explain the analogy in a better way, maybe with a different example that can show this in a better way?

The students are high school level, and are familiar with polymorphism, but not with abstract classes.

This answer draws on Java examples.

I start the interface discussion with a mechanical SATA hard drive in my hand. I discuss the interface called SATA and its universality across devices. I expand this with some digital images of SATA on an optical disc drive as well as a solid state hard drive. Some discussion follows regarding the variety of brands and companies but also the assurance of SATA's common functionality that makes it possible for everyone to play nice together and make reliable components that work across so many devices.

The students verbally list some functions of the SATA interface. I prompt them by asking what all these devices are required to do: read data, write data. Depending how long you want to spend on this and how it matches your curriculum, you get more information from them - what parameters might those functions have etc. Talk about data storage or bits and bytes if its relevant, etc.

All the while, I've listed these functions on the board. Finally, when I think we're done brainstorming, I wrap them in curly brackets and label it an interface. Be careful not to attempt an implementation of any of the functions. That doesn't belong in an interface. (Aside, digging into some Java interface source code, I was surprised to learn of the default function introduced in Java 8 - a lot of things surprised me really when I started digging into the Java source.)

This is my hook for the interface lesson. Next, I jump into all the textbook examples like Edible, Animal, or whatever other abstractions you're going to see at this point in a textbook.

Finally, whether the textbook likes it or not, I slap a Comparable vs Comparator (Java) problem on all of them and make them sort some Geometric objects or something. I spend the next 30 minutes walking around helping students comprehend compiler error messages like "Triangle and Rectangle don't implement the Comparable interface" or "Triangle must implement Comparable.compareTo" or something like that.

Inevitably, many questions about how compareTo works or should work come up. I explain -1, 0, 1 for <, ==, > respectively but then I will show them the source code for java.lang.String or wherever that is, and discuss how Comparable strings actually use the difference between ASCII character codes to compare characters. If not GeometricObjects, ask them how they would sort themselves - height? GPA? grade level? Obviously we need a Comparator for each property if multiple different sorts are needed. It may help to demonstrate that Collections.sort(arrayList) of complex objects won't work with Comparability.

When trying to nail the point, "Always program to an interface," my go-to example is the List interface. I say "Because it's easier to maintain later. If you change the interface, the compiler will require you fix all the implementing classes." I instantiate a few, Vector, LinkedList, ArrayList, with only the interface on the left hand side of the instantiation, List = ArrayList, for example. I show them the source code for the List interface in Java but with Oracle's comments removed so it's just a list of functions. I then show them the same set of common functionality across all implementing classes, only now it's listed in the Eclipse intellisense. This point about always program to an interface is apparently only worth mentioning because those who stay with programming will hear it again some day and you've laid almost a foundation. It's not a point I would spend too much time on with high school students. I drop the phrase and expect they'll hear it again if they carry on with software development.

... and right before I think they get it, time demands that we move on to something else. Hopefully some later assignments revisit the interface.


Make it easier, and quicker to get to the start When teaching I often have pupils struggle in the first few minutes. When they are setting the computer up, ready to start work. They often have to follow lengthy instructions, that I print on paper, of mostly screen snips (So this also takes a long time to prepare).
What can I do to make this easier for pupils?
For example
I have had a lesson where I have had detailed instructions on setting up Python/Idle: Starting the editor, finding starter code, they contain many screen shots. This took me a long time to prepare, and is not easy for the pupils. They are not productive at the start of the lesson, and get demotivated.
They need to get to:

starter code copied to there personal folder.
idle started and on one side of the screen.
code loaded into idle.
code run.
output window on other side of screen.

Common errors:

running code without idle (so they can not edit it).
running my copy of the code (so they can not edit it).
overlapping windows (so they are frustrated that they can not see, and spend a lot of time moving windows). (This one can be solved with better digital literacy, at the start, or a bit at the start of each lesson.)

I have had the same problems when teaching spreadsheets, and am anticipating it with web design. I was hoping to use the brackets editor. The start state would be.

starter code copied to there personal folder.
brackets started and on one side of the screen.
root folder loaded into brackets.
live preview started.
browser (output) window on other side of screen.

The computers are the schools desktop computers. Unfortunately they are running MS-Windows.

This question seems like a minefield. The obvious answer is "Don't Do That." No group of people, students or professionals, is going to interpret two pages of instructions in exactly the way the writer intends. It isn't going to happen. They will misinterpret individual steps, skip steps trying to optimize, crash the machine when they don't have a conceptual idea of the goal, etc.

In the first place, your instructions may be clear to you, but until you vet them with others they won't be clear to most other people. This is why textbooks have editors and why authors re-write continuously.

There are, however, a few things you can do.

You give one answer yourself here - Automate It. In fact you can improve the automation if you distribute the code yourself and execute it yourself from a central server. Automation isn't foolproof, however, as some of the machines in the lab will, perhaps, have different initialization parameters baked in that defeat your script.
Another possible solution is to decide on a standard startup process and configuration that you always use. The students can learn this and only struggle with it for a day (or week, ...).
Make the startup description shorter. As short as possible. Then a bit shorter. Vet it with someone else who is skeptical about it. Re-write it using their feedback.

But even then, you will fail. Different students will interpret your writing differently. That is pretty much guaranteed. Your writing won't be perfect. Neither will their reading (and understanding) be perfect. If you need different instructions each day and they can't be vetted, I wish you the luck you aren't likely to have.

You can do more, perhaps.

If you can live with students always working in pairs at the machines, then you have cut the interpretation problem roughly in half, maybe more. Only half as many machines need to be set up and there are two minds working on each machine. (Of course they could disagree making the problem harder, but usually this helps.)
If you can manage to have an assistant wander around the room helping the students with the most trouble it can help, though pairing is better. (Paired programming has been shown to be more efficient and require less intervention by the teacher, but that is not quite the same problem you pose here. Students working alone get stuck and wait unproductively for assistance. Pairs work it out.)

There is one special difficulty that you need to address. Minutely detailed and extremely precise descriptions are often especially hard to follow if the person trying to carry them out has no overall context or goal that they understand. The reader likely has no way to check that each step was faithfully executed in the correct order. Any glitch will cause a serious problem for that person. With a group of individuals, there will be many independent problems simultaneously. Whack A Mole.


What student exercises force them to modify and extend their own thinking process and methods? Beginners in CS will generally benefit from changing and expanding their thinking skills. Some of our thought processes may not be intuitive to a beginner and exercises can help them expand their thinking tool box.

Lectures that make these new ways of thinking explicit can help, of course, but exercises can deepen and reinforce the knowledge. Especially helpful are exercises that lead a student to an a-ha moment in which that was unclear has become clear.

In the context of extending their thinking and problem solving skills, what particular problems and exercises would you suggest to use at the novice level for teaching computer science?

In discussions in the CSEducators Classroom it was originally noted that "puzzle problems" may be especially helpful in this regard - especially those problems for which a person's ordinary intuition might not be helpful, but which lead the student to a deeper understanding of the essence of CS thinking.

Since there are two slightly different questions here

one in the topic

  What student exercises force them to modify and extend their own thinking process and methods?

and one in the detail section

  In the context of extending their thinking and problem solving skills, what particular problems and exercises would you suggest to use at the novice level for teaching computer science?

I am going to give an answer about exercises that focus on problem solving skills. The odd thing when I was building this list is how much it reminded me of those aptitude test they give you in grade school.

When it comes to problem solving one first has to be aware that there is no one way to solving problems that always works and there may not always be an answer to a problem or there may be an answer but getting the answer is not practical.

Algorithms commonly used
Depth First Search
Breath First Search
Divide and Conquer
Inferencing - Analogy: Connecting the dots

and also thinking in orthogonality of dimension/field.

For one of the simplest exercises of using depth first search is the game Unium which is to simply draw a line connecting a set of selected squares. This basically has only one dimension, a line and one method, depth first search. The puzzles get harder and harder, but you basically start drawing the line, see a problem, back up to where the problem occurred and then choose a different option and keep going and repeating until you complete the object and onto the next image to cover. This teaches that for some problems you can go back to a decision and change it to get the correct solution.

For breath first search the game checkers works as you can't make your next move until your opponent has made theirs and so can't resort to DFS. OK I know it really is a min-max game but BFS still applies. This teaches one that you have to look at all options available before moving.

For divide and conquer you will needs something that has simple rules and allows you to move off a sub-problem if it is to hard but still allows you to solve the problem. For this MineSweeper is a good game. This teaches that if you get stuck on something hard try some place else and you can still get the answer; in other words some paths to the solution are easier than others.

For something a little harder try A Good Snowman Is Hard To Build as this requires at least one good a-ha moments to build a snowman. The rules are simple but is uses three dimensions. When I did this with my small class it seemed most of the students had the same a-ha when building a certain snow man because the way to the solution seemed illogical, but until one learned to do the illogical they were stuck. I won't say what lead to the a-ha moment but I suspect that if you play the game you too will be saying a-ha at one point.

So far the way of thinking has been procedural but to add some functional thinking take a look at the Great Permutator as this adds functions, e.g. partition using every other, accumulate, dup, swap among others. I like this one also because you can try out different combinations of the function parts before solving the whole problem.

For a game that adds the dimension of concurrency take a look at SpaceChem. While this doesn't look like programming if you know how to program with locks and fork-join you will see the patterns and the best part is that it is visual. If my teacher had used this when teaching OS design it would have been a lot easier.

Getting back to procedural and adding in variables and the Jump instruction take a look at Human Resource Machine. One of the better parts of this is that it has challenges for the least number of steps and the least number of instructions. The answers to these challenges are not intuitive but get you to realize that machines don't have to work like we think to get a better solution.

For more advanced procedural/functional and back to the essence of what a microprocessor/ALU does check out Silicon Zeroes. This one also covers the idea of parameters and state.

To get out of the algorithm type problems have fun with the Crazy Machine Elements collection. This will make you think and sometimes you can even find solutions that don't use all of the parts. What is nice about these problems is that some of the elements affect others in nonintuitive ways like reversing gravity. This teaches that you can't always have orthogonality of dimension.

When you start playing with the dimension of time things really get interesting but finding a game that is simple but alters just time is not so easy to find, but The Misadventures of P.B. Winterbottom seems to do the trick. This game reminds me of a single person composing a song by recording a melody, playing the melody back and adding on another melody and so on. Get one melody wrong and you have to start over. This is interesting in that it teaches one that time is also a critical dimension for solving some problems.

Speaking of playing with different concepts what about having cooperating concepts? That brings us to Portal and Portal 2. I only wish they took the idea of cooperating concepts further and used other fields such as time, color, etc, and also have them competing some how. This is really interesting because it bring lots of a-ha moments if you don't look for the answers online.

The Turing Test changes out different dimensions/fields for solving the problems in different rooms but makes them harder as you go so that you are continuously being challenged. This helps to teach you that different properties of certain things can be used for other than their primary use, e.g. a block has weight but it can also block a beam.

For more of a real world problem but still simple enough for learning an essential concept common with neural networks being classification would be Papers Please. I have not yet played this one, but if it doesn't live up to what other say I will strike it from the answer.

Another game I have yet to check out but seems to deal with graphs which are essential to so many data structures in computer science is Mini Metro.

For the concept of composition I have on my list Infinifactory; again one I have not personally vetted.

So as you can see to learn how to problem solve start with simple methods and limited dimensions and keep adding on slowly with fun using games and one can learn a lot about problems solving.

In the real world when there are known to be exact solutions to a problem I tend to find that brining in combinatorics helps to solve the problem and one puzzle that quickly jumps to mind here is a Rubik's Cube. If you know the basic moves and how to apply them you can even find God's Number which will teach you a lot of good math and computer programming algorithms.

For more look at puzzle and logic problem books as they have lots of exercises. I did one of these books decades ago using Prolog before it had constraint satisfaction and after seeing how constraint satisfaction worked with Prolog find it to be one of my favorite languages for problem solving when dealing with closed world assumptions.

So by now for problem solving with computers you can see the need for algorithms (methods) and data structures (dimensions/fields) which is why the book Introduction to Algorithms is so popular.

If you have reached this far then check out the book "How to Solve It" by G. Polya. While it is useful to both students and teacher, it is limited in that it was written with math in mind.

If you are learning programming and reading this, I can not stress enough how much you should learn other paradigms of programming, e.g. procedural, functional, logic, and other concepts like matrices in MatLab, neural networks and learn as much math as you can.

One last point that AFAIK seem to be the only one I know who uses this rule when faced with a problem I can't solve. Most advise is to back off, break the problem apart and tackle a simpler part. However at times I find that finding a harder problem and reading about it then makes my problem easier and more enjoyable. So go regularly read about quantum mechanics and theoretical physics, etc., and you hopefully you will see that your problem is not that hard.

I can spend much more time on this question but hopefully I have given you enough to get started and shown you the path to expanding on how to build out ones problem solving toolbox.


Recent Graduate becomes a teacher In less than one month I'll be graduating from the equivalent of high school (I'm in Latvia). In my high school you also get a certificate based on which career you choose eg. a Chef or a Computer Technician.

Starting next semester there is going to be a new study called a "Programmer Technician", which I have been received an offer to teach )because I've been working as a programmer since I was 15 years old). How would I go on to teaching, like assess the students, give them homework (eg. how much etc.). How prepared should I be when the lesson happens. Stuff like that.

I'm currently 20 years old, and the students will be 16 year olds

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

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

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

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

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

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

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


Why is the critical-section problem always presented with code in infinite loops? I've noticed that "all" OS textbooks present the Critical-Section Problem with examples of code that are in infinite loops.  E.g.,

while (true) {
    // code here to do the entry section protocol

    // critical section here

    // code here to do the exit section protocol

    // remainder section
}

Why is this?  From my experience there can be many processes that run and enter critical sections (inspecting and updating shared variables) where the code is not in an infinite loop.  This business of always have code in loops seem to unnecessarily complicate matters for students.

Is there something I'm just not understanding about this concept?

One reason infinite loops are used could be so the problem can't be solved by letting one thread complete the code before the other thread starts it. With infinite loops, no thread ever completes the code. Of course, using a bounded buffer has the same effect.


How to bring attention to computational complexity? Many beginners strive to solve given problems, without thinking about efficiency of solution.

Consider such Python code:

data = [int(n) for n in input().split()]
max_el = max(data)

# count multiplicity of every element in data
counting_table = [data.count(i) for i in range(max_el+1)]

This solution seems elegant, but is in fact $O(max(data) \cdot len(data))$, while a solution with $O(len(data))$ is possible.

What heuristics can I teach to detect such code which could be done asymptotically faster? What are the most illustrative examples of how a poorly-crafted algorithm which can't tackle a bit more data than anticipated?

One technique I use for sorting algorithms follows after CS50's demonstrations of the differences among bubble sort, selection sort, and insertion sort. I have 8 students line up in the following order:

4 - 2 - 6 - 8 - 1 - 3 - 7 - 5

Here, 4 represents index 0 of an array of numbers I'd like to sort. I literally walk them through the algorithms, and they can see how much walking I have to do up and down the "array" in order to get it sorted. When it comes time to examine the code for these algorithms, I remark on the use of for loops and how nested for loops lead to $O(n^2)$.

We compare the iterative approach with the recursive approach of merge sort (which certainly could be added to the "walking" demo), which goes back to something we discuss on Day 0 about linear v. binary search. I have students explore this visualization tool. There are also a number of videos on YouTube I draw from that compare algorithms sorting the same data.

Students also have to complete an assignment called Sort Race, which requires them to implement sorting algorithms and test them against data sets of varying types: reversed, already sorted, all sorted but one, and random. When they see algorithms take a significant amount of time on an already sorted list, they get why it's not the preferred solution and can then go back to the code to see what slows it down (and what doesn't slow down others in some cases).


What's a good unit testing assignment for Android? I'm teaching a capstone (the final class in an undergraduate program) software engineering course in which we are developing Android applications in Java. I consider test-driven development and unit testing important but am having trouble coming up with Android-related assignments, since so much mobile programming is about user interfaces and synchronization, neither of which are ideal for unit testing.

The only thing I've thought of is that they could unit test a database running on Android, which would also let me introduce mocking, but that doesn't sound very interesting.

Any suggestions of a small but interesting Android project suitable to TDD and unit testing?

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.


Angular vs React vs Vue For a software course about rich client Javascript applications we want students to be able to choose what framework they will use. Now to give us a little bit of control we want them to be able to choose from Vue.js, React or Angular. As far as I can see Angular and React are both almost equal in technical complexity. But Vue.Js, although it's very popular, seems more flat and shallow.

We want to test students if they are able to build a solution that is:

Modular (components, modules, etc)
Has complex user interaction
Is tested via unit test and UI testing
Follows the separation of concern principle

My question: Can Vue.JS compete with Angular and React based on the criteria listed above?

Yes, from my experience it can.

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

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

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

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

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

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


Items on grading rubric for a coding assignment I'm collecting a list of possible items for grading rubric for a coding assignment. Below is a start. Is this complete, or am I missing important criteria? I welcome other ideas.

Effectiveness

Runs without errors
Passes all unit tests
Handles all typical cases
Handles common edge cases

Elegance

Uses language idioms
Selects correct data structures
Select correct built-in functions
Uses packages appropriately
No unnecessarily repeated work
No unnecessary hard coding
Can scale well with potentially large inputs

Readability

Clear, semantic naming
A single lines only contains a single idea
No unnecessary variables
Style always follows conventions
Consistent formatting/indentation

Documentation

All modules have a docstring
All functions have a docstring
Each line has a comment
All documentation are meaningful and complete thoughts
All documentation are formatted consistently according style guidelines

So, if I were reading code, I would object if someone submitted code with every line commented.  I am not aware of any professional code that does this, and when I occasionally receive code from students where this is done, it is simply cluttered.  I believe that the real criteria here is clarity.  Excellent variable naming will often accomplish this sans comments.
Consider:
if ( maxSoFar < currentValue )

vs
if ( maxSoFar < currentValue ) // Find out if the maximum is less than the current value

Truly, the comment adds nothing to the code here.  As a practical matter, it has been my experience that over-commenting makes my students work difficult to grade by reducing the clarity.
Unrelatedly, a missing criterion is having a run-time appropriate to the desired algorithm.
As a practical matter, you may find this rubric difficult to grade with. You will need to give careful attention to weights, and to how those weights will actually be evaluated.  (e.g. in a 3-point category, what sort of work would grant 3 points, what would grant 2 points, and what would grant 1 point?)


Independent research on bootcamp job placement claims Bootcamps have become an increasingly popular alternative for starting or transitioning to a career in tech over the past 5 years or so. As a result, a common question I get when interacting with beginners is whether bootcamps are indeed worth it.

Unfortunately, after conducting some preliminary research myself, I found it challenging to find hard data that supports a conclusion either way. Most online sources (such as coursereport.com) seem very marketing-y and don't seem to analyze the more existential question of whether bootcamps are a good idea in the first place, compared to other options. And of course, there are plenty of anecdotes, but anecdotes are not data.

Analyzing this situation is complicated by several other factors:

Bootcamps may be suitable for some, but not all: for example, professionals with an unrelated degree trying to transition to tech vs high school graduates trying to enter tech.
The quality of individual bootcamps can vary wildly (but then again, I suspect, though cannot confirm, the quality of university CS degrees can also vary just as wildly).
Bootcamps are incentivized to report skewed data. Even something as simple as "% of people who graduate with a job" can be complicated. (If the bootcamp hires you back as a TA, does that count? What if you get a job in a non-tech field? What if you get a job after a year of additional self-study?).

This brings me to my core question: What research has been conducted so far regarding how effective bootcamps are at helping their attendees obtain a full-time job in tech in a timely manner?

For this question, we can assume that the bootcamp attendees are people who either have completed a degree in an unrelated major and want to switch careers, or are people who are unable to attend a university for one reason or another.

An ideal answer would be links + summaries to reports that conduct a careful, measured, and data-driven analysis and seem to take into consideration factors like the ones I listed up above. I would prefer papers that have been accepted by a reputable, peer-reviewed academic journals or conferences if at all possible.

A nice bonus would be if the reports compared bootcamp success rates to other methods of switching careers (for example, getting a second degree or simply self-studying), but this isn't necessary.

For example, here is one paper that satisfies the above requirements. It'll apparently be presented at the upcoming ACM ICER conference later this month and draws some interesting conclusions -- the paper's main limitation is its relatively small datasize (it tracks only 26 students within a specific geographical location IIRC).

There's not much out there, unfortunately, and what there is is either suspect or sparse.

CIRR has probably created the best data that we have, as they engage in 3rd-party verification. These results are actually rather positive for the industry, although participation is voluntary, and there aren't many Bootcamps that participate.
The US Federal Government created the EQUIP initiative to convince schools to provide government-quality data in return for student attendees being eligible for financial aid.  Only five organizations qualified.  While I have been unable to locate the data itself, I would presume that those five organizations are probably fairly good.
Course Report is an independent organization that creates an annual survey of outcomes, and it shows consistently good results for Bootcamps nationally, but all of the results are self-reported, so they are not entirely trustworthy.  Also, the organization is very obviously friendly to the industry itself, with founders and employees who attended bootcamps themselves. Their "reports" simply look and read like ad copy.
There is a recent initiative by the schools themselves to create more accountability, presumably in order to counteract rumors that the institutions are simply fraudulent diploma-mills.

If you are considering a Bootcamp, I would strongly recommend only considering schools that have good results with CIRR, as that will both discourage fraud, and encourage Bootcamps to partipate in the process.


Why do we count starting from zero? In computer science, we usually count starting from 0.  Is there any effective way to explain why, to new programmers who ask why?

I've read a bunch of different sources that list several reasons for 0-indexing.  However, they either seem unconvincing, or seem hard to explain to a new programmer who doesn't have much experience with computer science yet:

Zero-based indexing lets you write loop conditions as i < n; with one-based indexing, we'd have to write i < n+1, which saves one instruction.  This makes no sense to me; i <= n seems like it would be fine.
In C, we can use *a to access the first element of array a.  This doesn't seem very relevant today for a new student who isn't programming in C.
With zero-based indexing, the expression a[i] compiles to an operation on memory address a + c*i where c is a constant representing the size of a single array element; with one-based indexing, it would need to compile to a + c*i - c.  This reason seems debatable today (couldn't a modern compiler often optimize this away?), but more importantly, I don't really want to be explaining memory addresses to a new programmer who doesn't understand memory layout and maybe doesn't even understand arrays yet.

Is there a better way to explain why to a new student who is just getting started with computer science?

None of the reasons you suggest really get to the heart of why we use zero-indexing in CS. Dijkstra's EWD831 explains why this convention works out the best. It comes down to the fact that we want to represent sequences of integers as half-open intervals that are inclusive on the start side.

  To denote the subsequence of natural numbers 2, 3, ..., 12 without the pernicious three dots, four conventions are open to us
  a) 2 ≤ i < 13
  b) 1 < i ≤ 12
  c) 2 ≤ i ≤ 12
  d) 1 < i < 13

To paraphrase Dijkstra:

(a) and (b) have the advantage that subtracting the bounds gives you the length, which is convenient because you don't need to remember to add or subtract 1.
(a) and (c) have the advantage that sequences starting with zero don't need a negative lower bound -- and negatives are no longer natural numbers.
(a) and (d) have the advantage that if you create an interval that starts with zero and shrink it down to zero-length, you don't need a negative for the upper bound.

Because of the above, we want to write all of our intervals as (a).

Once you accept that (a) is the correct way of specifying intervals, indexing an array of length N as [0, N) is much nicer than [1, N+1).

Two additional notes in favor of using (a) for intervals.

The first point above is important because half-open intervals nicely decompose into other half-open intervals. This makes implementing divide-and-conquer algorithms like merge sort significantly less error prone.

For example:

[4, 14) can be broken into the equal-sized intervals [4, 9) and [9, 14), and the middle index is computed as $9 = \frac{4 + 14}{2}$. This is quite clean and nice.
[4, 13], decomposes into [4, 8] and [9, 13], where you get the end of one sequence as $8 = \frac{4 + 13 + 1}{2} - 1$, and the beginning of the next sequence as $9 = \frac{4 + 13 + 1}{2}$. It's easy to forget to add or subtract 1 somewhere.

It's also a bit jarring to specify intervals with (b), because it feels unnatural to skip the first element when you're writing a loop.

As for how to explain the above to your students, I think that they just need to accept that breaking sequences of integers in half is something they'll do later on, and then a few examples will quickly point to [,) intervals and zero indexing as the most natural choice.


Learning from research papers in a developing field (Note: related question here, not duplicate.)

I'm reading quite a bit about quantum computing, especially optical quantum computing. Part of the problem is even the all-encompassing bible of quantum computing (Nielsen and Chuang, Quantum Computing and Quantum Information) has only 10 pages on this particular physical realization. Other textbooks, by the time they're published, are already out of date. Hello, reading scientific papers!

Of course, there's a problem associated with that - results are retracted, new ones encompass and expand upon old, and papers are rather notorious for being difficult to slog through. Having slogged through a few myself, I can tell you that notoriety is well-deserved. Worse (for the self-learner), most papers are focused on only a specific problem.

As in, I've read 10 pages of incomprehensible text before (think half an hour for the 10 pages, if I'm really, really lucky) just to figure out one fact, and then looked at another paper that casts doubt on that fact. Add the whole issue of paywalls to the business, and it only gets worse. (I'm not a university student, though I am lucky enough to be within driving distance of a decently sized university, but not everyone is.)

Papers often lead me down rabbit holes as well - tracing citations (I could tell a few entertaining stories about that alone), looking up terms ("oh, that's what you meant...well, why didn't you say that?"), and going down that oh-so-fun Wikipedia trail. You know, look up word, read third word on page, click on that, then continue until somehow you end up at philosophy (ironically, the previous page doesn't end up at philosophy, if I did it correctly).

How can learning from papers be made a little less painful? Things like:

What tips do you have to get the most bang for your buck reading a paper and retaining that understanding?
How do you help restrain the rabbit hole?
How do you know when a paper's trustworthy?

Answers don't need to cover all of the above, but be along those lines.

Seems like a developing field is a discussion that a community of researchers engages in.  To participate, you'd need to:

Speak the language, e.g. know about quantum computing terminology.

Know the background, e.g. quantum physics and computational theory.

Once you have some basis for understanding the discussion, then you focus on getting your own ideas straight.  In the end, it's really all about you; sharing research results really isn't a goal so much as a duty to be performed when/if you become the foremost authority on some particular understanding.
If you're a younger student, you've probably got a lot to learn and develop before you can really enter that arena.  But, if you're interested in it anyway, it seems like you could do two things:

Focus on the well-agreed-upon concepts.  You don't need to understand them or even be able to use them just yet, but have them in the back of your mind as you progress in your more foundational studies.

Take note of the skills and tools that seem to be most useful in the current community.  For example, if the field seems to be best-attacked through a particular branch of mathematics or using particular computational tools, then you might want to put acquiring those skills on your to-do list.

Getting to Philosophy

Papers often lead me down rabbit holes as well - tracing citations (I could tell a few entertaining stories about that alone), looking up terms ("oh, that's what you meant...well, why didn't you say that?"), and going down that oh-so-fun Wikipedia trail. You know, look up word, read third word on page, click on that, then continue until somehow you end up at philosophy (ironically, the previous page doesn't end up at philosophy, if I did it correctly).

Definitely, Philosophy is exactly where you want to end up!  Anyone who can't trace their field back to Philosophy hasn't understood it so much as memorized it.
If you know exactly how to get from basic philosophical principles to the current state-of-the-art, then you can really claim to understand the field.
Questions

What tips do you have to get the most bang for your buck reading a paper and retaining that understanding?

Lots of profiling.  For all anyone knows, that random gibberish full of typos and conspiracy theories on Reddit is the deepest, most correct theory of physics ever.  But, since it's probably not and there's only so much time in the day, your bets are better hedged by focusing on content that appears to be of higher quality.
To that end, you should develop a bunch of prejudices over what's likely to be better content, then selectively focus on it.  Sure, if you're truly out of stuff to read, then maybe you'll end up going through that weird Reddit post; or, if you've got too much good stuff to read, you might not even be able to make time for Einstein's words.  It's all relative.
Examples of common prejudices:

Prefer scholarly sources for widely understood concepts.

Prefer blogs and communications from top-experts for the-very-latest commentary.

Well-formatted over poorly-formatted.

Thoughtful over thoughtless.

Analytically precise over vague.

How do you help restrain the rabbit hole?

Follow the rabbit hole down as far as you can go without losing sight of the light of day.

Understand where you've ended up, and build a solid foundation there.

Build back up 'til you're out of the rabbit hole, standing on more solid ground.

Rinse and repeat, iteratively falling down further and building back up more.  The more you do this, the greater your understanding grows.

How do you know when a paper's trustworthy?

They never are.  Whenever you read a textbook - even the best-known ones in well-developed fields, e.g. introductory Calculus - never just trust it.  Put each word on trial, and absorb only the ones that you can't tear down.
You often need to memorize large amounts of content without first thoroughly scrutinizing it.  All of this content should carry a red flag in your head that labels it as unscrutinized claims.  If there should come a time where you really need that information, or want to build upon it, you should really scrutinize it first.


A quick ruby crash course I have some students in highschool who already understand programming concepts (generally), and are fairly familiar with Python's syntax and logic, and have a beginning awareness of OOP in Python. I'd like them to get a quick crash course in Ruby for fun and general awareness of the language. The intent is to be able to write basic code in Ruby, both for web applications and back end applications using Rails.

What would be a web course, or website I could have them read, that would bring them up to speed in the basics of Ruby so they could start writing code in it? I'd like it to be free.

(I'm self-teaching, but this is rephrased as if I was teaching a class.)

This is a different sort of answer than what you may be hoping for, but I'd really recommend that you deepen your knowledge of Python first. Learn to be pythonic, learn its OOP aspects. Learn its dynamic aspects. Become a Python Wizard.

The reason for this advice, since you are fairly new at this, is that there is a danger that you will try to learn too many languages too soon and start to think of them syntactically only. There are a lot of "java programmers" for example, who only write C code.

Let me give an analogy from another field. I used to be a very good photographer. I had one manual film camera with a light meter and three lenses. One was a zoom lens since I wanted to backpack with not too much equipment. At that point I could take really nice photos. Artistic. Later I got lots of cameras, lots of lenses, lots of other "stuff" and my ability to really take good photos went down, not up. Too many tools in your tool box is not a help, especially for a beginner.

So, build skill first, then branch out. One big idea is called "creativity under constraint". How much can you do if you artificially restrict your tool set? It sounds dumb at first, but with fewer tools your brain becomes your best and most powerful tool. Suppose your language didn't have loops. What can you still do? Recursion of course, but in an OOP language there are other options. Suppose, instead, it didn't have any sort of selection statements (if/switch...). Can you still write any program? Some become very difficult to write, but attempting to do this increases your brain power. Big Idea here.


How useful is English (pseudocode and documentation) in aiding understanding? I'm a freelance tutor working with high school students, giving them programming assignments in languages like Python, Java, C++, and others.
In recent months I've seen the value of using English - getting them to write documentation and also to write down rough drafts of their algorithms in pseudocode. I'm wondering what other teachers do with this. (I'll give an example with an Euler problem.)
The goal is to get them to think at a high level. Typically they like to dive into code. It's not concrete to them if they aren't writing code. I get it, developing a higher-level understanding is something that takes time. But I think I need to push it a little - they are just avoiding pseuocode and documentation past the point when they are really ready to use it.
One obstacle is their general writing abilities. The students who don't write well in any context, like English class, find it the hardest to write documentation and pseudocode.
To give an example, let's consider Euler 46, "Goldbach's other conjection" https://projecteuler.net/problem=46
This project involves testing different ways of adding squares and primes, in some kind of nested for loop. Typically they want to start out with details like
for (int n = 0; n < ???; n++)
{
    for (int i = 0; i < ???; i++)
    {
        for (int j = 0; j < ???; j++)
        {
            ??? generate square and prime S and prime P ???
            if (2 * s + p == n)
                break; // and do what then ???
        }
    }
}

Where I have put question marks is where they aren't sure what to put. But they begin wrestling with each place I have put question marks right away. That means they are struggling with low level details right away before they really understand the gestalt of the problem. Also they will throw in a break without having considered ahead of time how that will play out.
What I'm trying to get them to do is write pseudocode like this:
For every N, an odd composition number we are testing, in some range
    For every prime P < N
        if N - P is not twice a square, we found an exception. print or mark it

Of course this is a big leap, so I guide them to it gradually. (The benefits of working as a tutor and not a classroom teacher.) When they think at a high level, they can also see choices available to them. like maybe that pseudocode could be modified to be made more effcient.
For every N, an odd composition number we are testing, in some range
    For every value 2 * S where S is a square
        if N - 2*S is not a prime, we found an exception. print or mark it

They can reflect on the difference long before they have wrestled with the details of for loops. They can think about how they might efficiently test if a number is prime. Maybe they've seen before this idea of generating a hash set of primes and think about whether that's faster than trying to find out if a number is a square (which requires a sqrt operation).
Then there's documentation. The difference between something low level like
// set i to 0. increment i and stop when it's n
for (int i = 0; i < n; i++) {

and higher level like
// loop over possible test values (i)
for (int i = 0; i < n; i++) {

What I'm looking for from the answers is whether other teachers have found it useful to bring English into helping them develop higher-level understanding. "Chunking" concepts for example (thinking with high-level or abstract concepts). And how successful is this? Does it depend on a student's ability to use English in the first place?

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.


App Lab/JS confusion between strings and variables In my APCSP class (using app lab, which is javascript based), I noticed that there are many students who struggle with the difference between a string ("foo") and a variable (foo). I've explained that strings are surrounded by quotes while variables are not, but this is still one of the most common mistakes I see. For example, a programming task could be:

  Create a prompt for a persons first and last names, and then print out a greeting (stored in a variable) followed by the name (last name, first name).

and a student will write the following code:

var greeting = "Hello ";
var first_name = prompt("What's your first name?");
var last_name = prompt("What's your last name?");

var reply = greeting+" "+last_name+", "+first_name;
console.log("reply"); // <-- Here's the problem

I typically see this issue when a student is trying to output information, either to the console or set a GUI element to have that text content. I also see it occasionally in other contexts, such as conditional statements.

What can I do to help students better avoid this mistake?

As always with javascript, show the right&wrong:

Show them, using the exact piece of code from your example, but add another line:

var greeting = "Hello ";
var first_name = prompt("What's your first name?");
var last_name = prompt("What's your last name?");

var reply = greeting+" "+last_name+", "+first_name;
console.log("reply");
console.log(reply);

And run it.

Then they see that when they log something with " ", the output is literally what's inside the quotes.

However, if they have a variable (this is important to note that reply is defined with var), the output is the contents of the variable. Truth be told, the output is the string representation of the object, but I fear that's too advanced at this point.

Further explaining that when they use the word var (or const etc.), you create a something that holds information. On the other hand, using quotes "", you are simply representing that information.

But no matter how well you explain it, it's still far more effective to show examples like the one above, and to give the students exercises that will allow them to experience the point you try to teach.

For example, let them try to do that with a Date object:

As an exercise, teach them about Date in JS:

var d = new Date()

and then explain that d holds info about the date and time that the line was executed.

Once the students understand the very basics of the date object, ask them to print it. The difference between

console.log(d)

and

console.log("d")

are very, very big.


How do you deal with Lone Rangers in group projects? We all have them - students who want to write all the code themselves, who don't want to be part of a group project.  They have poor social skills, or they don't know anyone else in the class, or they don't trust others, or they think other people "slow them down".  So they go home after a group project is assigned, write all the code themselves, and bring it back to the first group meeting, completed.

A typical situation is a group project done in a class or lab period over several days. The instructor or a lab assistant is present to watch over the students and give advice as needed. Different strategies might be needed if the project is done outside the view of faculty on the students' own time.

This could also differentiate depending on whether the situation is the first occurrence (you are surprised by it), or if you are familiar with the Lone Ranger and know he or she has a history of going rogue.

What are your practical ideas for preventing a student from taking over a group project, or dealing with it after it has occurred?

Of note from other posts:

Reading the answers to Techniques for encouraging pair programming and What advantages/disadvantages have you seen with Pair Programming in the classroom offers insight into the problem of encouraging students to actually "work" together, which can be part of the problem here. The real issue, however, isn't that the other students aren't willing to do the work, rather that the Lone Ranger just does all the work, usually before work begins, without the others even having the opportunity to work.

Two other questions, Is it possible to ensure division of labor on a group assignment?, and Problematic student at a very high level, help with creating the environment and assignments to enable group work, and determining if someone has gone rogue and done all the work. Neither deals with preventing the Lone Ranger from repeating once the problem has been identified.

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.


How to learn Java as a beginner? I want to start learning Java from scratch. But as a beginner, I don't know where to start or what to learn first. I have basic knowledge in C++ but Java is an entirely new area to me. Can anyone give me some instructions and good books to start properly?

The first thing you need to understand is that your second language is, perhaps the hardest of all to learn. You already know "how to program" and so the second language seems to get in the way of that. Alternatively you just use the second language in the same way you used the first, resulting in ugly and sub-optimal programs. So, you want to guard agains that.
It is actually somewhat easier to learn a second language if it is nothing at all like the first, since you can't try to impose habits from one language on the other and have to absorb the actual philosophy of the new language. So, Scheme, for example, after C++ (or before) forces you to think in a new way.
So, learning Java after C++ is especially difficult, since the lowest level syntax of the two is nearly the same, but the underlying philosophy (paradigm) is quite different. In particular, Java and C++ both use what they call classes but they are really different creatures.
One book I'd recommend very highly (since I know and trust one of the authors) is by Barnes and Kölling. It does, however depend on also using the BlueJ IDE which they created and is available free online.
The reason I recommend it is that it introduces objects from the beginning, which is the fundamental difference between C++ and Java. So, if you put aside what you think you know about programming and believe in the authors, you should do well. They both have a very (very) deep understanding of what Object Orientation means.

An alternative that would work, if you somehow object to BlueJ is Cay Horstmann's Big Java Early Objects. It, too, starts with objects which is my primary recommendation. I also know Cay. He also has a Late Objects version that I don't recommend for a bunch of reasons, but one is that the first part of that book would be likely to bore you. While it might seem an easier path, it won't take you where you need to go as directly as the Early Objects version.

A third possibility, though it is intended more for first time programmers rather than for someone with experienced in another language, is Karel J Robot by Bergin, Stehlik, Roberts, and Pattis. This book focuses entirely on object oriented programming in Java but does not try to teach the entire language. It does, however, provide a system in which any program can be written. Like Pattis' original Karel the Robot it is an attempt to provide a minimal but complete system including a simulator in which interesting (and difficult) programs can be written.


Learning suggestions for AI and neural networks for a mathematician I am a mathematician who has done programming in Python, Java, and R. I would like to learn to make neural networks and artificial intelligence. Are there any good books for self learning AI for a person like me who loves learning theory behind neural networks, and who can learn by proving theorems and thinking the theory behind AI? When I just read Tensorflow's or Keras's documentation, I found that I couldn't understand how the networks work.

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

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


How can I discourage poor design while using automatic grading of submissions? Automatic grading is great for saving time on marking programming tasks, so there's more time to focus on actual teaching, but I've noticed a few flaws. Since work is essentially marked based on passing unit tests, thoughtful design often gets ignored, and excessively complex solutions are considered just as good as elegant ones.

I recently read this article about how this is a problem on MITx—instead of this solution:

return max(min(hi,x),lo)

A student wrote this:

1 * lo + 0 * x + 0 * hi # too low
0 * lo + 1 * x + 0 * hi # in range
0 * lo + 0 * x + 1 * hi # too high

Automatic testing would find these equivalent,  but clearly one is incomprehensible and the other is relatively logical and sound.

This is also recognised in Using Test-Driven Development in the Classroom:

  Despite its classroom utility, an automatic grading strategy like
  the one embodied in the Curator also has a number of shortcomings:

  Students focus on output correctness first and foremost;
  all other considerations are a distant second at best (design,
  commenting, appropriate use of abstraction, testing one's
  own code, etc.). This is due to the fact that the most immediate
  feedback students receive is on output correctness [...]

Is there any way of evaluating code style and design automatically (or at least detecting very poor solutions)? I've thought about using some static code analysis to try and evaluate solutions (e.g. cyclomatic complexity, or tools like these), although I've not tried them yet. Are there any reliable solutions to this, or must it be done manually? Does static code analysis help in any way?

I am a strong advocate for code interviews.  I make principles of style into about 50% of a lab grade (though I do permit kids to go back and refactor after an interview for full credit.)

For some context, I discuss regularly that there are two audiences of code: computers, and people, and that these audiences have very different needs.

Since my high school class is structured with lab periods, I will grade lab 1 during lab 2 work times (and so on). This gives me class time to get my interviews done. At the start, the code needs a lot of work. However, by the time we have arrived at lab 3, the kids are mostly creating crystal clear code.

Don't drop that autograder! Even with code interviews, it is still tremendously useful. Having a good autograder means that, during the interview, I only need to look for style issues. I can assume that even the strangest of their code (and boy, is there ever strange code at the beginning!) produces the correct output.  That permits the interview process to focus in, laser-like, on how well the student wrote for the second audience.