Should CS students be doing their tests on paper? In some CS courses (especially undergraduate and high school courses) the tests and the final exam are written on paper without the use of a computer.
But if the students are in a CS course, shouldn't they be allowed to use the computer? If some mistakes are difficult enough to not be noticeable while writing code on a computer, they are nearly impossible to be found while writing code on paper.

So, my question is, are there any advantages in doing written tests on paper, and is this the best approach?

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

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

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

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

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

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

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

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

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

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

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

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

The takeaway questions then are:

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

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


Quizzes after lectures I put together elaborate, very carefully planned out lectures, complete with highly distilled exemplars, student teach-backs, and mid-lecture activities to check for understanding.  I've had feedback that my students really enjoy these lessons and appreciate how much work I put in to making sure that my examples are really clear.

However, it has come to my attention that, perhaps due to a course structure which gives students lots of chances to re-demonstrate mastery if they initially struggle, a certain number of the students are only half-engaged with my lecture.  Since I realized this, I have spoken to a few of them, and they agree that the lessons are fun, but say that they are stressed by other courses, and sometimes this causes them to work on other things.

On one level, I don't mind this.  Student stress is real, and I have ample evidence to demonstrate to me (or to others!) that the students ultimately master the material that I teach them.

On another level, however, being lax about this does a disservice to them (as we could progress faster for everyone if kids took the learning opportunity more seriously), and to me, as I have put almost unreasonable amounts of time into distilling rich and complex ideas into explanations that are both beautiful and clear.

I'm further motivated by the fact that I get evaluated by my administrators, and I have now been dinged twice by having some of the kids off-topic for short bursts.

I'm toying with the idea of adding little, basic quizlets to the ends of my lectures for which students would be immediately responsible.

The questions would purposefully not be difficult.  They'd be more on the level of, "were you paying attention to what we just did?"  Basic recall, simple factoids, etc.  I already give a difficult test or quiz at the end of the unit, so I don't need this quiz to do much more than (1) give students a chance to dredge up information from memory1 and to help motivate students to take fuller advantage of the lesson opportunities I am giving them.

My question, then, is two-fold: (1) are quizlets a good solution to my problem?  And (2), if they are a good solution, is there any wisdom from the trenches on how to pull these together so that they are effective without bringing on substantially more grading work?  I'd like to make them as useful in the learning process as they can be, but I have to be careful about what I take on.

1 - See points 2, 3, and 4 for how this directly enhances learning.

I have a few thoughts on this topic. One is a couple ideas about how quizzes could be implemented (if you choose to use them), and the other is some more general thoughts on the tactics that I use to solve problems like this.

Quizzes Without Extra Grading

What are your opinions on peer grading or self-grading? I've seen both work nicely for things like this (short, low-pressure quizzes that aren't too hard).

They require a little bit of logistics, since each student needs a normal colored pen and a "grading" pen, and it's easiest if you supply those. Then you require that normal pens are collected before grading starts, and that students do not have their own writing implements out, and it typically goes well.

This would require you to put aside more time during class, since a 5-minute quiz takes at least an additional 5 minutes to grade.

The pro of students grading their own work is that it becomes a way of reflecting and learning from the experience. If they get a question wrong, they get immediate feedback about the correct answer.

Alternatively, you might want to look into giving digital quizzes. They would have to be multiple choice or fill in the blank, but they auto-grade, saving you the time. I know that Google Forms has a method of doing this, and there are a bunch of other platforms too. Your students could take the quizzes on their phones, or computers.

This system tends to be quick and you can integrate it into the entire lesson, not just the end. I had a professor in my undergrad who would lecture for a bit and then pause for us to answer a question or two. Before continuing. It was her way of doing understanding checks. You could easily establish small point values for each question so that they "count."

To Quiz or Not to Quiz

Personally, I've found that increased examination does not tend to increase student attention. I theorize that there are two reasons for this.

First, many quizzes happen "later" - either at the end of class or even several days or weeks later. Most students (especially teenagers, although adult students as well) have trouble remembering potential consequences that seem far off. If the exam is important enough to overcome this problem, then it's probably invoking some level of anxiety or fear, which is a large detractor from student focus and engagement. It may solve your problem of looking like your students are paying attention, but I believe that it's unlikely to actually increase their learning.

My second theory is that people tend to believe that they are better at multitasking than they are. If you gave an anonymous poll to your students and asked if they ever do work for other classes during your lectures and how much attention they pay to your lectures, I would bet quite a bit that they all feel that they are always attentive, even though you know that not to be the case. Thus, saying "Oh, it's very important to pay attention!" seems unlikely to change behavior because they really believe that they are/can pay attention while doing other things.

So, what are the other options? You could do the honest but maybe frowned upon thing of talking to your students and saying "hey guys. I know you're busy. I know you sometimes finish up other homework while in this class. I'm mostly fine with it on occasion; as long as you get your work done and feel like you're learning what you want to learn, I don't really see a problem. But it makes us look bad when a senior teacher/dean/etc. sees you doing that. So we have some options. I can change something about the way the class is structured (quizzes, etc.), or you can keep the distractions to a minimum, especially when we have guests." Whether this will work mostly depends on your students and your relationship with them. It also obviously depends on the institution you teach at.

A Non-Quiz Suggestion

You've mentioned that you're already putting a lot of thought and work into every lesson. So this might not be a solution that seems feasible. But my personal strategy for student engagement is to keep the students active throughout the lesson. I try to talk for 5-10 minute chunks, broken up by having students work through practice problems or explore ideas. Maybe you can take your current activities and spread them out a bit more throughout the lesson? If students are changing tasks frequently, it will be easier for them to stay engaged and harder for them to pull out something else to become involved in.

If you want more concrete information on what this could look like, pick an example lesson and post another question. I'm sure that lots of people will have a wide range of ideas for active learning.

I hope some of these things help. Good luck!


What should be included in a best practices C course? At our University, we have in the first semester a very difficult C Introductory Course, that consists of presenting a shortened version of the language specification: What are for/while loops, if clause, what is a pointer and so on.

But they never show how good C code in a more complicated application should look. What version control is, what Valgrind is (a gnu tool for detecting memory leaks) and so on.
For the many new (about 60%) to programming or C, the group projects are quite a knockout (about 40%).

Some motivated students and I decided to offer a "best practices" session before the first assignment is handed out and after the lecture has finished.
For the students to have a better chance of finishing this course successfully.

Our selected Chapters are these:

how to compile (clang and gcc and their flags and warnings)
valgrind
make
coding style

best practices -> how to allocate memory, typedefs, file operations
basic program flow, some simple patterns

git
pitfalls specific to this course and C in general
how to ask the right question (and in turn how to google their problems)
how to use the  manpage

Are there points missing? Is there something that we shouldn't do?
In short, how to improve the content. We are planning on 3 Sessions with around 3 hours each.

I think an important aspect to any best-practices list is the rationale behind it.  It is entirely too common for a programmer to, for example, insist that gotos and global variables are evil and then proceed to use exceptions and singletons to create the exact same problems that got those features proscribed in the first place.

So I suggest that when introducing a rule of thumb, you don't just give examples of code that follows the rule, but rather examples of the sort of awful code that led to the rule being created.  Let them understand why the rule exists both so they can avoid making similar mistakes and also recognize when the rule isn't applicable. (Of course, no examples will be as helpful as allowing them to write terrible code and then try to modify it, but you have limited time.)

A related recommendation that is somewhat tangential to the best practices lecture, but related to the question of how to help them complete the course successfully:
Don't assume that the more abstract explanations of topics are necessarily easier to understand than the ones that get into the gritty details.

I've had a number of students who were completely confused when we tried to explain pointers using diagrams of boxes and arrows, but as soon as I sketched out a table of memory (with addresses as indices), explained that a pointer is just an integer that is used to "index memory", and then walked through a block of code, updating the table as I went, they understood it almost immediately.  (We put the abstractions back in place when it was time to work with higher level data structures, after they understood the fundamentals.)


How to prevent organization/OS students from becoming premature optimizers? While I'm sure that the comp-sci 101 mistake of having a triple nested loop with two recursive calls is sure to be cured by a decent comp-org class, it can have the unintended side-effect of turning students, enlightened by this hidden knowledge of registers and memory management, become obsessive about unrolling loops in trivial ways and trying to out-O3 the compiler like it's ($CURRENT_YEAR - 40).

What is the prevention to this error of learning in the course of teaching the subject? I doubt that most students will ever be in a situation where there will be a difference caused by writing something like struct baz{char a; int z; char b;};.

I'm honestly not that I would address this problem at all within my own courses, but if it is to be faced, I suspect that the solution would be something like this:

Immerse students in their current layer.
Really teach the metaphor and thought-process of the layer that they are currently in, and only accept code that utilizes that model of thinking.
Warn students about the dangers of premature optimizing
Show students how to use a profiler in order to figure out what is actually slowing their code down.  Tell students to address their efforts here.


System to validate run time complexity requirements TL;DR: Do you know of a method/system that can determine the run time complexity of code automatically?

At our university we have a system in place that allows students to submit their code and get feedback on whether or not they satisfy the functional requirements of the exercise.
This is excellent and works well for many of our courses, especially the introductory courses.

We also use it for courses that teach more advanced algorithmic concepts, focusing on run time. We have exercises that ask them to implement for example dynamic programming solutions in $O(n^2)$ time.
Currently we use the automated tests to check for the functional requirements and have some tests with larger datasets and a time out to hopefully distinguish between $O(n^3)$ and $O(n^2)$ solutions.

Perhaps to nobody's surprise this system is not perfect, with some students optimising the wrong parts of their code to hand in an $O(n^3)$ (or worse) solution and get it through the tests. Thus for the graded assignments our TAs also check all of these by hand to make sure the solution is really $O(n^2)$ and they deduct some points if it is not.

My question is, do you know of systems or methods that can automatically check the run time complexity of code (in terms of big-O), rather than the actual run time (in seconds)?

In case this is relevant: the programming language used at our university is Java.

(NB: I've seen this question and appreciate the concerns about including this in grading. For introductory courses I would not do this. For the courses that focus on finding the most efficient algorithm to solve problems however it is one of the learning objectives :))

Buffy is provably correct (no risk needed!) that it is impossible to do it with automated code analysis, as this is an attempt to figure out when a program will finish (i.e. the halting problem.)

You can get a very good guess, however, by using a few (very) differently sized input data sets, run the program on each one multiple times, and observe the results on a graph.  This is fairly trivial for a human, and takes very little time.  It may be less trivial for an automated statistical analysis, but I will defer to other who know more about such things to decide whether that is possible or not.


What resources and data sets are available for teaching big data courses? I currently utilize Cloudera’s QuickStart VM and for Talend’s Big Data Sandbox as part of my big data classes. These touch on frameworks, storage / data access options, data integration, data quality, data governance, and search.

What resources do you use and would suggest for hands on big data labs? Perhaps something for Snowflake, AWS, or Azure to catch cloud aspects of big data? Or some compelling big data tutorials for an analytics tool? Are there curated big data sets especially appropriate for educational use?

I work for a Talend; but also teach big data classes at Washington University in St. Louis.

Related questions:

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

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

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

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

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

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

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


Simple Pointer Examples in C Thanks to feedback in this thread, I'm beginning to plan how to integrate a basic introduction to pointers into my unit on arrays. Here's a sample program I just wrote up:

#include <stdio.h>

int main(void)
{
    int number = 42;
    printf("Value of number: %d\n", number);
    printf("Address of number: %p\n", &number);

    int *pNumber = &number;
    printf("Value of number pointer: %p\n", pNumber);
    printf("Value at address of number pointer: %d\n", *pNumber);
}

I will probably add comments before actually presenting it and making it available to students. Seeing how the address of number and the value of pNumber always correspond will hopefully reinforce how pointers work. The first and last line will match as well. The idea is to show as clear and simple an example as possible.

My question comes in two parts:

Is this an appropriate example for introducing pointers?
Do you have suggestions for similar simple examples of basic pointer
usage?

I would teach the use of arrays and array indices first (with pictures of a long row of physical mailboxes, or school lockers, etc.)  Then later explain that all of a computer's and/or C program's (process) memory can be thought of as one big array with a pointer being a form of index (locker number) into that (virtual) memory array.

You can then draw a picture of how arrays of char (bytes) might be allocated in memory.  And then show why pointers might be necessary in order to tell a standard string function how to find (or modify) a substring in an arbitrary C string array.


CS-oriented Ice-Breaker Games I will have my new incoming CS freshmen (HS) for a week-long summer orientation in August. The kids don't know each other yet, so Ice Breakers are in order! Has anyone encountered fun, physical CS-themed games for helping kids to loosen up and get to know one another?

Criteria: the students are not required to come in with any background, though they will be learning some very basic programming concepts over the course of the week that we see them.  Ideal games would either directly expose kids (in a non-technical way) to CS concepts, or could be referenced later (days, weeks, months, or years) in lessons to help explain concepts down the line.

Answers where you have direct experience with the game (and can vouch that it is fun!) are doubly appreciated.

Get them to line up (preferably on a wooden gym bench), then get then ask them to get into alphabetical order. You can use this to help learn names, and to introduce sorting algorithms.

I could also recommend CS-unplugged, it is part of the computational thinking, so aimed at very young pupils (primary school < age 11years old), but can also be used with older students.


Realistic task for teaching bit operations I'm looking for a function or algorithm that requires extensive bit manipulation, but is not complicated in its nature and purpose, so that students remain focused on bit operations.
Now I use Win32 API GetVersion(): it returns system version components encoded in a 32-bit integer. Although deprecated, it's a comprehensive real-world example that requires masking, shifts, and bit testing. Students also learn to figure out needed operations from documentation.
However, I'd like to move away from MS-Windows. What an equivalent facility might be? It may even be an external library, if it's free and easy to plug in (we already use libcurl).
The language is C++. Students are 1st year, not pure CS (industrial automation).

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

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

The black pawns? pawn & !white

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

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

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

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


How to teach to write optimized code While reviewing someone's code I found many problems, such as writing lots of loops instead of a single loop.

For example let's take the case of basic square matrix multiplication.

Both matrices can be created in a single loop (with user input). Instead people write one loop for each matrix, so they are unaware of Loop Optimization.

Another problem is creating lots of variables.

They are very bad practices.

How to can I teach them the importance of code optimization?

you not going to like this answer, but Don't teach it!!

At least, don't teach it unless your teaching a 300-400 level course in college.

Most code optimization is very tiny benefit, especially since modern compilers are able to do many of the optimizations for you and it's entirely possible for someone to optimize wrongly an slow something down instead.

More importantly code optimization takes time and often leads to less readable code, which is bad.  It's very rare that any optimization other then algorithmic (Big O level) ones will ever be needed, and code readability is a huge and important factor of every program.  You don't want to teach students to sacrifice readable, maintainable, and testable code for theoretical optimizations that often will not have a noticeable impact on rate that the code runs.  Leave that to be learned in upper level coding courses only after they are able to write solid readable code.

The only type of optimization I would every worry about teaching is Big O level algorithmic optimizations, and even then I probably wouldn't worry too much about that until their in 200 level college courses.

For low level courses I would demonstrate the difference between quick sort and some naive sort, to show algorithms can matter, and not much else.  Maybe give a quick example of a nested loop being much slower then two non nested loops, but I would not be emphasizing writing code efficiently, only showing that efficiency concepts exist, it's up to later classes for students to understand and make efficiency decisions.

At 200 level courses I would start stressing how things could be optimized algorithmically to some degree.  You would likely be teaching more about different container types, linked lists vs arrays vs hash maps, so just explaining these algorithms in a way that touches on why one would use one over the other is good.  You will be teaching them how skilled programmers use tricks to gain efficiency benefits by demonstrating the common algorithms they cam up with, which is great.  However, the emphasis now is less about coming up with great algorithms themselves, and mostly knowing that algorithm decisions can matter and they should be picking the best collection/tool for the job based off of it's algorithmic efficiency.

At 200 level you can also start to point out particularly horrible Big O mistakes.  The most obvious example would be including a nested for loop that does not need to be nested.  Telling your students "try not to have multiple loops inside each other if you can avoid it, especially not if each of them can be large" is okay at this level.  Give an example of why nested loops can be absurdly slow and how you can avoid it is okay, often this can be tied in with picking the right tool for the job by showing how iterating over an array once with a precompute phase to put stuff in a hash map before a second iteration is faster then the nested loop, and look here is a demonstration of another reason to use a hash map.

at 300 level courses your ready for a course that focuses entirely on algorithms, this one course should explain Big O vs Big Omega etc, give means of measuring algorithmic complexity, and really hammer in that algorithms matter.  From this point on always bring up algorithmic complexity and ways to make better algorithms, their ready to adjust for this.  However, still be quick to point out when an optimization was needlessly complex.

Sometime around 300/400 level optimization considerations other then algorithmic can be tackled as well.  I would suggest tying this in with study of the physical limitations of a computer though.  When you study how memory actually works you can give an example of how, for example, ensuring you access data 'nearby' each other to avoid cache hits is useful.

At this level of class I suggest explaining how the computer works and how this affects optimization decisions.  Then give them an 'unoptimized' piece of code and tell them to optimize it.  Write some automated testing scripts that will run the same code 1000 times on a large sample size, compare wall clock before/after it's run, and figure out the average speed of the code, then tell them you want them to provide N boost to it's runtime.

I had one such project where I got something like a 25 x speed increase when doing math on a 3 dimensional cube where we had to consider the content of each 'touching' cube.  The biggest increase was changing the logic to minimize cache hits, but things like loop unrolling and replacing methods with macros also came into play, these was using a C compiler with all optimizations disabled.  It really helped to show how drastic optimization can be.

However, it's important to always stress readable code is most important and that premature optimization is bad, repeat constantly to only optimize proven slow points and to test your code to identify where the slowdowns occur before trying to optimize.

If your not teaching high level courses though, just don't do it.  It's likely to lead to worse code most of the time and just adds an extra thing for students to learn and get confused about.  Focus on their writing good maintainable code and only after they have mastered that should they worry about 'efficient' code.


How important is learning Binary for first-year college students? I teach my freshmen Binary because I'm old school I guess. I do want them to know how data is stored and that means Binary to me. How do others feel? Is it a must learn early or a nice to have if there is room?

I see no reason to teach binary in an introductory programming class. It is not generally needed (see exceptions below) when programming in high-level languages, which is usually what is taught to freshmen students. If you have extra time in your course, rather than introducing binary, why not introduce them to other areas of CS that freshmen don't usually see, such as human-computer interaction, algorithms, computing history, Moore's Law, assistive technology, internationalization, etc.

I teach binary when there's a need to: in Computer Architecture, which is a required (2nd- or 3rd-year) course in our undergraduate CS minor and major. It is absolutely necessary in that class, to understand how processors work, how caches work, and how numbers and Unicode characters are represented. I don't teach Computer Networks but could imagine its being taught there.

If a curriculum does not include Computer Architecture, students should still learn enough about binary numbers and floating point encoding so they know why floating-point arithmetic is inexact.

If/when you do teach binary, teach them how to count on their fingers in binary.

I give extra credit in Computer Architecture for counting up to 31 on one hand. Just be careful...

See also this cartoon.


What are the core concepts of discrete mathematics within CS? Is there an accepted core set of concepts that is discrete mathematics as it applies to the study of Computer Science? The math department in my school is thinking about creating a course, they asked for our input, and I wasn't sure what to point them to.

In the search for a "core set of concepts that is discrete mathematics as it applies to the study of Computer Science," I kept finding nebulous ideas, without concrete parameters. There seems to be a general consensus that there is the need for a firm foundation in discrete mathematics when studying CS. There is also a broad agreement that "graph theory, and other topics" is part of that foundation. Unfortunately the other topics portion of the requirements are seldom well specified, and seemingly never delineated with any specificity.

I recognize that the question is in a high school (USA ages ~ 15-18) context. Be that as it may I've settled on a source from the university context for a solid, definitive, and delineated set of "core discrete mathematics material" to set as a touchstone.

Williams College requires that students who select "Computer Science" as their major demonstrate a proficiency in discrete mathematics. This requirement is usually met with a "C", or better, grade in their MATH 200 course. In Spring 2017, the Computer Science department added an alternate method of satisfying the requirement: A "Discrete Mathematics Proficiency Exam."

Williams is classified as "most selective" by U.S. News & World Report, admitting less than 20% of the applicants each year. As such it is expected that they have set standards, in all areas, rather high. However, I prefer to avoid the dangers alluded to by Michelangelo (disputed): The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it. If I were to choose a target, aiming "high" has the advantage that I might reach the target. If I fail to reach the target, I will know how high I can go. If the aim is low, however, and I reach that target, I still will not know if I could have reached higher. Therefore, using the materials from Williams College as a guide for a high school course seems worthwhile.

All that being said, here is the "short list" of their subject areas, (taken from their Preparing for the exam web page.)

Sets, Relations, and Functions
Basic Logic
Proof Techniques
Basics of Counting
Discrete Probability
Measuring Algorithm Complexity
Graphs and Trees

There is, most assuredly, a lot of ground to cover there, and it does not look any "easier" with a full breakdown. The referenced web page (ibid.) lists a breakdown of the topics followed by the  learning outcomes. I think the learning outcomes likely to be more significant in answering the OP's instant question, and have reproduced them with their subjects below.

TL;DNR

The seven areas above have following learning outcomes listed in the cited materials:

  Sets, Relations, and Functions

  Learning Outcomes:

  Define, as well as explain with examples, the basic terminology of functions, relations, and sets.

  Perform the operations associated with sets, functions, and relations.
  Relate practical examples to the appropriate set, function, or relation model, and interpret the associated operations and terminology in context.

  Basic Logic

  Learning Outcomes:

  Convert logical statements from informal language to propositional (and quantified) logic expressions.

  Apply formal methods of symbolic propositional logic, such as calculating validity of formulae and computing normal forms.
  Use the rules of inference to construct proofs in propositional logic.

  Proof Techniques

  Learning Outcomes:

  Identify the proof technique used in a given proof.

  Outline the basic structure of each proof technique described in this unit.
  Apply each of the proof techniques correctly in the construction of a sound argument.
  Determine which type of proof is best for a given problem.
  Explain the parallel between ideas of mathematical induction to recursion and recursively defined sequences.
  Explain the relationship between weak and strong induction and give examples of the appropriate use of each.
  State the well-ordering principle and its relationship to mathematical induction.

  Basics of Counting

  Learning Outcomes:

  Apply counting arguments, including sum and product rules, inclusion-exclusion principle and arithmetic/geometric progressions.

  Apply the pigeonhole principle in the context of a formal proof.
  Compute permutations and combinations of a set, and interpret the meaning in the context of the particular application.
  Map real-world applications to appropriate counting formalisms, such as determining the number of ways to arrange people around a table, subject to constraints on the seating arrangement, or the number of ways to determine certain hands in cards (e.g., a full house).
  Solve a variety of basic recurrence relations.
  Analyze a problem to determine underlying recurrence relations.
  Perform computations involving modular arithmetic.

  Discrete Probability

  Learning Outcomes:

  Calculate probabilities of events for elementary problems such as games of chance.

  Differentiate between dependent and independent events.
  Make a probabilistic inference in a real-world problem using Bayes’ theorem to determine the probability of a hypothesis given evidence.

  Measuring Algorithm Complexity

  Learning Outcomes:

  Be able to meaningfully compare the asymptotic growths of pairs of functions.

  Graphs and Trees

  Learning Outcomes:

  Illustrate by example the basic terminology of graph theory, and some of the properties and special cases of each type of graph/tree.

  Be able to prove elementary results about graphs and trees, such as:
  In any graph, the sum of the degrees of the vertices equals twice the number of edges.
  In any tree, the number of edges is one less than the number of vertices.
  Model a variety of real-world problems in computer science using appropriate forms of graphs and trees, such as representing a network topology or the organization of a hierarchical file system.

Source: Discrete Mathematics Preparation from Williams College Computer Science Department


Is it better to lie to students or to be pedantic when teaching Intro CS? When teaching Intro CS in Java, I sometimes tell students things that are not entirely true, such as that, unlike abstract classes, interfaces cannot contain any code. (For those of you unfamiliar with Java, that was true until functional interfaces were added with Java 1.8 in 2014.)

I realize I could put an asterisk on the slide, or visibly cross my fingers, and let students know I'm not telling the full story, but, when I witness other instructors allude to irrelevant advanced material, I view them as pedantic and fear that students find the additional information distracting or confusing.

I don't mean to open a debate on the importance of functional interfaces in Java -- they're just an example. What I'd like to know is if it's considered better to gloss over details in an introductory class or to always speak the whole truth.

Lying is good. But advertise it when you lie. Make sure students make a note of it that you are lying.
Pedantic is bad. If you try to explain everything you will wind up explaining nothing. Let me take a simpler example. In java we have a special incantation
public static void main(String [] args)

We put it in every program. It distinguishes a program. But if you start your java course explaining every part of it you will (a) confuse the juices out of them and (b) never get to the point of writing a useful program. For the beginner, it is just an incantation like
Riddikulus; // used in defence against a Boggart.

The Java code is just a "charm" for the beginner. All you need to say is that it is a "hook" for the OS to find its way into your program. Explain it later after you've taken up some of its elements for other purposes.
Beginners need a simple but coherent view of their language and system. When you simplify, work hard to keep it consistent. But it doesn't need to be complete and certainly not exhaustive.
When you are giving an "overly" simplified view, say that explicitly. Have the students mark their notes with an asterisk (or the above charm) so that they know it isn't complete. If you are explicitly asked for "the rest of the story" you have to decide whether it will help to include it (after the commercial break, of course) or to defer it or to enlighten the students out of the class context (email, say), or give a reference for those who "will not be denied."
I used to start some discussions with "I'm about to lie to you, but it will be helpful if you accept my lie for a bit". Of course I had to remember to come back an fill in the blanks  later, but it might not be for a while. Complex, inter-dependent topics are like that.
tl;dr: Lie, but honestly and truthfully.
And, perhaps the most important caveat, don't lie in such a way that the student later needs to unlearn something. Lying is giving partial truths, or temporary world views, not sending students into mental blind alleys and backwaters. Withholding some facts may be necessary and valuable as is presenting an incomplete metaphor. UnLearning should never be part of learning.
I'll also note that infants learn to speak a native language without everything being explained to them before they begin. The deeper understanding comes to them only gradually and over time. We are actually conditioned by evolution to work this way.


Why and how is it efficient to process sorted arrays than unsorted arrays? It is well accepted that processing sorted arrays is easier and efficient. What would be the pedagogical approach to explain how and why it is more efficient to process sorted collections than unsorted collections.

First, it is not "well accepted" that processing sorted array is more efficient. It depends on what you do. If you spend your time inserting, for instance, then sorted arrays are not necessarily a good choice. You are better off inserting at the end (say if you have resizable arrays such as Vector<X> or ArrayList<X> in Java), and then sort afterwards (you'll pay $O(N*log(N))$ instead of $O(N²)$).

It is true that if you don't have insertions (or very few insertions with respect to searching or other operations for instance) then it is more efficient.
If you want to find an element in a sorted array, you can use binary search which is $O(log(N))$ while if your array is not sorted you have to scan the whole thing which is $O(N)$.

Likewise if you want to perform set operations on two sorted arrays (intersection, union, difference), then doing so on sorted Arrays is linear. If they are not sorted you will be either quadratic (naive algorithm) or have to use an auxiliary data structure (such as a hash table).

Sorted arrays have the same complexity for these operations than the more involved tree structures (AVL or red-black trees) and they have a very compact and simple representation. But you pay the price that insertion is more expensive, since it has to maintain the order of elements.


Good example of what isn't a system call? I'm teaching an Operating System course, and was looking for an example of something that isn't a system call.

As silly as it may sound, I wasn't able to carve a good example. Everything (accessible to second-year students) that came to my mind involved system call in some way, and looking around for examples didn't help.

So, I'm reaching you: Is there any good example of operation happening on a computer that does not involve system calls?

And wish a long life to that community that I just discovered, but intend to contribute to!

Edit: the example can come from any OS, and I know that pretty much every useful program requires some system call, that's why I'm asking!

The simple breakdown is:

Anything that performs input/output involes a series of system calls.
Anything that's purely computational doesn't involve system calls.

Both of these statements have exceptions (I/O through memory-mapped files or peripherals is I/O without syscalls, calling a hardware accelerator or allocating memory is syscalls without externally visible I/O) but they're a good approximation.

So here are some examples of operations that don't involve system calls:

Getting or changing the value of a variable.
Arithmetic operations on integers and floats.
Conditionals and loops whose body doesn't involve system calls.
Operations on strings such as searching, joining, splitting, etc.
Manipulations of data structures such as lists, arrays, matrices, trees, etc.
Memory management, as long as the program doesn't need to obtain more memory from the OS.
Printing to a buffered stream, if the buffer doesn't get flushed during this print call. Likewise, reading from a buffered stream, if enough bytes are available.

It would help to demonstrate by showing the system calls made by some programs, e.g. with strace on Linux, with dtruss on macOS or with Systrace under Windows. Compare a program that does a lot of I/O with one that does one big computation and prints the result.

The case of buffered I/O, suggested by ctrl+alt+delor, is an interesting one because the same library functions may or may not trigger a system call depending on the state of the system.

There is sometimes possible confusion between a library call and a system call. Unix programmers in particular tend to believe that what is documented in section 2 of the manual is system calls, but this is not true on a modern Unix systems. Every function callable from C is a C library function that's a wrapper (possibly very simple, possibly even a macro rather than a function) around a system call that usually, but not always, has the same name and takes more or less the same parameters. You can observe that on a modern Linux/x86_32 system, where many system calls have been upgraded from 32-bit arguments to 64-bit arguments, e.g. strace ls will show calls of getdents64 and fstat64 rather than getdents and fstat. Under the hood, system calls and library calls have a different calling convention. At the very least, a library call involes a jump/branch instruction while a system call involves a privilege change instruction. Depending on the system, the rules for placing arguments in registers may be different.

You can discuss how a program could make as few system calls as possible by starting from strace /bin/true. Most of its syscalls are due to dynamic linking, so write that one-line program, compile it statically and look at the remaining system calls. Reduce it even further with a more minimalistic libc such as dietlibc.

# Install dietlibc, e.g. apt-get install dietlibc-dev on Debian
$ cat a.c
int main(void) {return 0;}
$ diet gcc a.c
$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 82 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7fff98099fe0) = 0
_exit(0)                                = ?
+++ exited with 0 +++


How to share solutions in a way they won't get uploaded I teach a computer science course and I like to share sample solutions to assignments after the assignment is due.  I think it helps students learn to see a solution sheet with sample solutions and notes on common mistakes, immediately after the assignment is due.  However, I face all too much cheating: some students upload these solutions to websites like Course Hero, and then when I reuse those problems in a future semester, now it's all too easy and tempting for other students to search and find those solutions and copy from them.  I would prefer to avoid that situation.
Are there any technical solutions that would allow me to share solutions with students, but in a way that makes it more difficult for them to share the solutions with others?
Right now I share solutions as a PDF.  Unfortunately it's very easy to download that PDF and then upload it to a site like CourseHero.  Is there some better way to allow students to view solutions, while making it harder for students to upload them elsewhere?  I know I'm not going to make it impossible -- if nothing else, students can take a sequence of screenshots -- but if I make it tedious enough, then I suspect that would help.  I suspect many of the students who upload solutions are not doing it to be malicious, but because of dark patterns at sites like CourseHero that pressure them to upload something, so if I can make it more onerous to upload solutions, they might upload something else instead.
Does anyone know of any technology that might meet this need?

I'm not interested in answers that tell me to never reuse problems in a future semester.  I ask for your trust that I am aware of the pedagogical tradeoffs and have valid reasons to do so.  I am willing to elaborate if you feel you need to hear that, but I suspect it is a tangent.

I don't have real answers, and I suspect there are none.  I also reuse prompts, if only because good ones are almost absurdly hard to come up with, write-ups and supporting code take time, etc, etc, etc.
I've taken a series of steps to mitigate the cheating.  Some of these are peculiar to my own situation, and may not translate directly to another context, but they also illustrate the type of thinking I use when I consider this particular (and particularly intractable) problem.
The first is to not weigh labs heavily in the grading.  This sucks, because they are a huge portion of both the work and the learning in the class, but they are not trustworthy as high-stakes assessments if you do your assessment at the end by looking at the final result. (There is genuinely no getting around this fact.)
I explain this to my students, and encourage them, then, to use the labs as learning opportunities. The brunt of their grade comes from tests and quizzes. The labs help them to prepare.
Next I talk about plagiarism.  I require them to keep in comments links to stackoverflow, indications of where friends have helped them, and any other sources they used.  I point out that even very veteran software developers use stack overflow regularly, and I assure them that this sort of help is not cheating as long as it is cited.
Next, I make sure that my lab write-ups are extremely clear.  Cheating typically centers around nervousness more than laziness. When students feel like they are not quite sure how to be successful, but nevertheless fear the consequences of failure, cheating is a natural outcome.
Then I have in-class working sessions where I go around and observe how the students are doing, and help them get un-stuck.  This allows me to see regular progress, and helps the students to learn from the labs.
Finally, I grade some of the labs as code-review interviews, and award a harsh, current grade, and a second, more generous grade for once the required refactoring is complete.
I don't believe myself in thinking that this entirely nips the problem in the bud, but I have reason to believe that the outright copying is minimal in this setup.


What are the "intangibles" that distinguish one university's CS program from another? Both Carnegie Mellon University (CMU) and Yale are top schools. (I attended both; one as an undergraduate, one as a graduate student, neither as a CS major). Their curricula aren't all that different. Yet CMU's CS program is far more highly regarded than Yale's. (And I'm beginning to think that this view is not about the "program" but something else.)

One thing that I did notice, or feel, is that CMU's CS department seemed more "authentic." That is, their CS students really seemed to "bond" with the program. The attitude of Yale's typical CS student seemed to be more like that of "doing a job." Assuming, as I do, that the students are roughly the same caliber, what could be the differences in teaching that give one group of students more enthusiasm or passion than the other?

Between two highly regarded schools with not too different CS programs, what are the "intangible" factors of one over the other that would produce two crops of students that are very differently regarded by Silicon Valley?

Fair warning, I am not intimately familiar with the programs, and my answers are based in some stereotypes of the institutions and the CS programs.  However, given that my answer is based on student selection, institutional reputation may not be a bad way to think about it.

While Yale is, by any measure, a top-tier institution, CMU is (at least by reputation) possibly the top computer science program in the world, and at an institution that is otherwise ranked lower than Yale.  I would expect, then, that self-selection among students would play a huge part in this. The sort of student who would aim for CMU for CS would be doing it because the opportunities for CS at CMU particularly appeal to them.

By contrast, the sort of student who would aim for a CS degree at Yale would be the sort of student who is aiming at Yale first, and also wants to major in CS.


How can I set up and deliver a Computer Hardware Course for the first time? I'm in need of major help at my current job. I'm a HS teacher and I teach a private school - I just started in August, two days before school started and five days before the previous teacher left for a different school for another opportunity, and I'm the new computer science teacher. I have a masters in CS.

Two of my classes are going very well (CS 1 and CS 2), and I'm very much in my element teaching those classes. They're not perfect, but I have some awesome ideas for building them over the years. The classes are about coding, which I am very confident in.

I am having major trouble with my 3rd class - Computer Hardware and Software. The course description is based on the A+ technician curriculum. Not only is it my largest and rowdiest class, but I'm having severe problems coming up with lessons or curriculum.

I don't have an IT background. I was originally told months ago that I have to teach A+ because that was what is in the course description, and that I have to teach the concepts of the course. The problem is, I don't have an IT background, I have a CS background, and so I'm supposed to teach what is in A+.

I don't have A+ certification, I'm not a technician by trade, I don't know all the ins and outs of different motherboards, processors or input/output ports - I mean, I have an informal understanding of those things, but I am not sure how to make this stuff interesting for 10th graders who all are already students with ADHD and are very bored right now. I find myself not having fun lessons ever, and I even cried in the middle of class because I'm boring and I have no idea what I'm doing.

My administrator says I can't change the class during the school year - I've made it clear since the beginning of the year that this is not my expertise. What should I do? I bought 10 raspberry pis and I want to use those to teach physical computing, but even that is coding, and not A+ at all, and it's something I have to learn myself.

I'm the only computer science teacher here at my school, and so I don't think my colleagues or my administrator understand that 1) A+ is not really a college prep curriculum, nor is it computer science, 2) Parents care more that their students are learning important things that meeting whatever was in the course description. I don't mean to be rude, but I feel like no one is teaching A+ to college-prep students, they're teaching coding.

What should I do? Does anyone have experience teaching A+ to high school students?

Somebody is going to be spending some money.

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

Test Basics

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

The overview from CompTIA provides:

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

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

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

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

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

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

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

Instructor Prep

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

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

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

Lab Prep

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

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

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

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

Motivation

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

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

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

ADHD Considerations

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


Should unit testing be taught in introductory programming classes? I understand the advantages of test-driven development, but should unit testing be taught/used in CS1 (the introductory class) for computer science students learning?

I am aware of researchers saying that "YES" it can and should be taught, but in the "real world", is anyone using it in their CS1 classes? Do the students write the tests or are they provided with the assignments?

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

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

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

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

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

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

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

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

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


Are there any recommended tools for teaching syntax and grammar of programming languages? I would like to know if there are some tools to teach the following topics in a programming paradigms course:

Demonstration of lexical rules
Demonstration of grammar rules, such as tree parsers of Backus-Naur forms

I found that one can teach this topics by using Flex and Bison, but it requires some previous knowledge in C and C++ languages. In any case, are there some alternatives to these tools?

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

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

For example, you could create a language defined as:

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

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

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

G = (V, Σ, R, s)

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

A guided discussion could go something like:

Σ

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

...

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

{ℤ+, +, -}

V

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

...

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

Expression -> positive-integer Operator positive-integer

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

{ Expression, Operator }

R

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

Expression -> positive-integer Operator positive-integer

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

...

Operator -> +
Operator -> -

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

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

s

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

Next Steps

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

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


How to handle objections to the wording of test questions or answers? I try to include a wide range of difficulty in the questions on quizzes and tests, from very obvious to quite subtle. The more subtle questions might hinge on a distinction of singular vs plural or other 'wording' aspects, so that those who have the strongest grasp of the material can differentiate themselves. I usually get a good spread of numerical grades, so experience says that I am doing this correctly.

But students who missed an item based on subtleties often speak up when I review the quiz or test immediately after all the results are in. It would seem impolitic for me to say that I made that item difficult deliberately, but it is true. Instead I usually point back to the textbook or my lecture to say that I actually explained and even stressed the point. Sometimes I agree that wording was poor in a question and so I give everyone credit (essentially acting as if the question did not exist). This can vary from year to year.

In a workplace subtleties will be vital, so it is not a manufactured situation to include them in my teaching, and I only use subtle distinctions in tests where they exist in the material, and are worth emphasizing.

How do you handle situations where students push back on the wording of test questions or answers? How do you not simply say, "Because that way I have a more useful test"?

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

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

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

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

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

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


How many projects(within the same organisation) can one apply for in GSoC (google summer of code)? Not because one would want to take on two tasks, but so that if one project is  already filled/assigned,they could be assigned another one,instead of  being turned down from  the organization
I have seen answers about the number of organizations one can  apply to,but not the number of projects per organization
I am in my first year and completely new to GSoC (google summer of code) and have just about begun exploring..

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


My teacher said that java is pass-by-reference when the type is not a primitive I am an undergrad student. I am an experienced programmer. For reasons out of the scope of this question, I ended up in a class where basic things about C++ and Java are being taught (but I already know those).

I know very well the difference between "pass-by-value" and "pass-by-reference". I know very well that Java is "pass-by-value".

My teacher was talking about pointers and a bit later he showed an example of pass-by-reference in C++, comparing passing "by pointer", by value and by reference. So far so good.

But then he said "on the other hand, Java has a rule, primitive types are always passed by value, and non-primitive types are automatically passed by reference".

My question: I know that technically what he said is wrong. But I didn't say anything. No one else said anything, the other students appeared to "learn" that. I would like to have corrected him, but how could I have done so? Alternatively, is there a good education reason to teach this way, perhaps a "white lie" of some sort, to avoid overwhelming students with details?

I've encountered experienced C and C++ developers who are convinced that Java is pass-by-reference for objects. One example I've used is this one:

void changeInt(int x){
  x = 42;
}

void changeString(String x){
  x = "hello world";
}

void testChanges(){
  int i = 0;
  changeInt(i);
  System.out.println(i); // still 0

  String s = "test";
  changeString(s);
  System.out.println(s); //still test
}

The changeInt() function fails to change the value of the parameter, because it's pass-by-value. But then the changeString() function also fails to change the value of the parameter- because it's also pass-by-value.

I also really like Cup Size -- a story about variables and its follow-up Pass-by-Value Please to explain the difference between pass-by-value and pass-by-reference from a Java perspective.

Now, as for whether you actually bring this up to your teacher, I'm not sure. If I were you I'd probably just bite my tongue and move on with my life.


How can I design online tests and prevent cheating? As you may know, schools in many parts of the world will remain closed for a long time due to the coronavirus outbreak.

In Italy, the government has invited schools to provide remote teaching, and since many schools are subscribers of G Suite or Office 365, teachers are giving online lessons using web conferencing services (Google Hangouts Meet or Microsoft Teams).

Now, the main problem is with tests.

Regarding computer science, if we know that "it is spectacularly easy to cheat on computer science labs" (and in my tests students have to write code on paper), we can just imagine how simple is to cheat in an online test, whether it is an assignment to be submitted after several days, or a few minute quiz.

A different assignment for each student is not a solution, since lazy students could ask clever students to solve their assignment, so I think I am forced to abandon tests which require students to write their own code.

Maybe a better idea could be a quiz with automatically generated questions, like a code snippet and the request to determine the output for a given input, with different input values and variable names for each student.

Do you know any tool to create such questions? Or do you have any other suggestions?

I don't think there are any published tools to generate programming assignments, though there are articles that describe such tools (such as this one from a CUNY, or this one from Croatia, so one option is to try to contact those authors and find out whether they would share their results with you.)
I will state categorically that there is no way of guaranteeing that students will not cheat.  As the old saying goes, "locks are to keep honest people honest."  Putting road blocks in the way of cheating will help dissuade students from trying, both because it becomes more of a bother, and because it gives them a chance to remind themselves of the ethics involved.
The bit about ethics is important, actually, and it can be remarkably effective all on its own.  Dan Ariely did an excellent set of studies about this, which he summarized hilariously in this TED talk.  If you don't want to watch that, then you can read this blurb from his blog, though the talk is well worth the time and much more interesting.

"We used an honor code in an experiment at MIT in 2007. We asked a few hundred undergraduates to do some simple math problems but didn’t give them enough time to finish. We then asked them to score their own tests and tell us how well they had done, with payment of $1 for each question they reported getting right. The students were asked to shred their papers afterward—but our shredder didn’t really work, so we could see how they had done. Many cheated. We had a second group of students follow the same procedure but only after they first signed the honor code. Signing the honor code before the test eliminated cheating altogether.
The effectiveness of such a code doesn’t stem from signing it, though. It comes from being reminded about moral issues. If your students eventually stop thinking about the ethics code as they sign it, it will lose its power. If they keep reading and reflecting on the code, its effectiveness might increase.
I ask my own students to write their own version of an ethics code—not because I’m especially interested in their interpretations but because it helps to ensure thought."
Dan Ariely

So, one way of working around the COVID-19 problem is to combine both ethical thinking and a few roadblocks to help gently dissuade cheating:

Remind students about ethics up front, at the top of your exam. (I make them copy out, by hand, an honor statement.  On a computerized exam, I would provide an image of the statement and make them type it.)
Schedule the exam in advance.  Give the exam at a specific time, and a narrow window (say, 10 minutes) to begin the exam.
There is no need to make different exercises for each student.  Make 3 programming problems, and assign each student to different problems using a rule.  This decreases the chances that they will have a friend in the class with the same problem.
Require that the exam be finished within a reasonable time from the start time.

It's not foolproof.  They could, for instance, have their parent sitting next to them, telling them the answers.  But you can't do anything about such a scheme.  What you can do is set up roadblocks and set the stage for ethical action on the part of your students.  If Ariely's studies are any guide, you should get the large majority of students to submit honest work this way, and that is probably the best you can hope for.


How to document the developed work using an agile methodology? In the final report of their internship, the students of our school must have one chapter where they "document" the developed work. When using the “waterfall” methodology, they usually have one sub-section for each stage:

requirements
detailed design
implementation
tests
...

What if an agile methodology like XP or SCRUM is used? Every year we have the same problem, as some teachers say it should be done one way, while others say the exact opposite.

Any ideas?

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

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

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


Is it possible to study too many things in parallel? Unfortunately I did not study well at school, I was not interested in many things, and I did not understand that things.

But I have matured, interests have become more. I am now 20 years old. Now I have to correct the mistakes of the past.
I am now studying, writing and earning money with JavaScript. But I want to study mathematics to understand more complicated things in computer science and learn other languages (English, Russian, Japanese).

And is it possible to study all these things (to study, write on modern frameworks, learn math from the beginning, and learn languages (not programming)) in parallel? For example, doing own work for 4 hours, after that to study mathematics for 3 hours and after that to learn languages 2 hours.

Will not I have a mess in my head?
And how to learn things correctly so that there is no mess in my head?

Actually, what you want to do is commendable. And no, at the scale of things you talk about, I don't think you are likely to get yourself confused. In fact, you may have the opportunity to learn different things in an integrated way. In some ways the educational system, which puts different topics in different boxes, isn't optimal and everyone needs some experience in integrating what they know into a personal whole.

I once learned quite a bit of French by reading Math papers from French mathematicians, though I was already pretty good at math, but you could, for example, read CS papers in Russian. Knowing something of the underlying ideas before you start lets you focus on how they are expressed in Russian, rather than Japanese or English.

You already seem to be aware that you will need discipline and to set aside time for your studies. That works for nearly everyone. If you are studying several things then you can also switch to something else at a point at which you either get stuck on some idea, or get tired of the current topic. Often letting your mind work on something else is a good way to let your unconscious work out details that you might miss when working in a concentrated way.

You should also be aware that you are now (age 20) at the height of your mental (as well as physical) powers. It is never too late to start, but you are starting at a good point. Onward.


Teaching "CS integer" vs. "math integer" The concept of an integer data type is not equivalent to the math concept of the set of integers. For example, in many programming languages the expressions 3. and $2^{10^{10000}}$ are math integers but (for different reasons) are not an integer data type. This potentially creates confusion for students in the age range of 8-16 years old who may be learning both the math and CS concepts of integer at once. What are effective ways to have students experience the distinct concepts so they reinforce each other rather than create confusion?

This might be an interesting way to do it, but here goes.

Give your students a blank sheet of paper. Have them write out "3". Then have them write out $2^{10^{1000}}$. Most will probably stare at you blankly. A few clever/sassy ones will just write out the exponential notation. Tell them that just as they write out numbers a little differently depending on size, the computer stores numbers a little differently depending on type.

If a number has a decimal point, it treats it differently from a number like 1 or 2, and it treats that differently from a really large number and it treats all of these differently from something like a string. This is the whole reason that you have to convert between types when you ask for a number as input() in python and then get a TypeError when you try to add it - instead you must add float(input()) or int(input()). It's the computer's way of making life easier for itself, just like we make lives easier for ourselves using exponential notation.

Also, by now hopefully they've realized that the world of math doesn't directly translate to some of its uses. Math is a very abstract thing, though it describes many things remarkably well. Pure math is very different from most math they've seen, and I think they understand the difference, for the same reason they understand the difference between x = x**2 and $x = x^2$. It's a different context, so it has a different meaning.


How to communicate expectations around "rabbit holes"? Without guidance, students will sometimes spend a large amount of time on a computer science assignment in a portion of the assignment that does not engage CS skills and knowledge. An example is a student who spends a lot of time creating costumes using the drawing tools in Scratch. The problem can include code, however, such as a student who has established expertise in simple conditionals but continues to build out an adventure game using repeated application of the same pattern without gaining any conceptual ground.

What practices do teachers use to successfully retain the student engagement driving a student to exert ongoing effort but redirect their effort to realize greater gains in learning skills and knowledge intended by the teacher?

There is another sort of rabbit hole, one that your best students can fall in to. I once had a situation in which students were programming with a certain library that provided a simulation - a virtual world. They had certain exercises designed to teach specific thought processes; think recursion, or design patterns, but it could be lots of things. Some of the best students figured out that they could get the right answer, not by programming within the simulation, but by re-programming the library itself to make the exercise trivial. They got the right answer by rewiring the foundation. But the intent was to help them rewire their brains.

It is hard to condemn such students, of course. They were very clever. They learned something. But the worry is that what they learned helped them avoid learning something else that may be more important in the long run.

In this case the solution was that I tightened up the simulator (which made it better/more secure), but I also needed to assure that they did in fact learn the lesson of the day. It isn't that they did anything wrong, or learned the wrong thing, just that they may have failed to learn something important.

The same situation would apply if a student, asked to write a program with some hard bits, modified the compiler to make those bits easy. Good that they teach themselves something about compilers, but bad if the hard bits held some important insights that programming around them left them in the dark about.

I sometimes have to tell a few (usually good) students that the purpose of programming exercises isn't to produce a program, but to produce learning. Usually, if I needed the program I could write a pretty good one myself.


Should I have written tests on basic programming skills? When making more complex programs, it is natural that one needs to run the program to see whether things work and fixing bugs. However, if one makes a lot of mistakes in basic programming, e.g. writing = instead of ==, this will slow down coding a lot, so it needs to be avoided as much as possible.

A possible solution to make students learn the basic syntax very well is to have a written test where students need to make small programs that only use basic syntax. Therefore, students need to learn to do these things right the first time, and also know the basic syntax very well.

Will this be effective? Is there a better way?

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

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

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

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


Curriculum for a primary school learner My niece is 11 this year and has shown a surprisingly deep interest in programming. She will spend hours on Khan Academy, using their javascript/processingjs environment. This is educational, but it's not a toy or a visual/drag-and-drop interface; it's raw javascript, with a bit of help from the compiler (in the form of a cartoon character that says things like "are you missing a semi-colon?").
Since I'm the programmer in the family, I've been working with my niece to develop her interest, and I'm unsure how to go about it further. She wants to develop video games or animations, so she'll look at programs that other people have written, but these are generally big and hard to follow. What she can do on her own is find individual lines of code that she can understand, like a call to fill(color) and she'll change the color, or rect(x,y,width,height) and change the parameters to change where the rectangle is drawn.
When I work with her, she'll ask for features, and I'll implement them and explain, and she seems to follow the explanation, but she can't generate the code herself, or understand how to decompose a complex task into pieces small enough that she can implement them, and then assemble the pieces into what she wants to build
I'm wondering if there's a curriculum or toolkit out there that would guide a child--slowly--through the skills. AFAICT, the Khan academy system isn't really that kind of thing, more like an environment and some tutorials, and access to other people's code, but not a linear course to follow.
I'm thinking of something like Python Like You Mean It, but for kids, and ideally oriented towards graphical output--something that the child could follow along in a linear way, to provide structure to her studies.
Or would that run the risk of killing a budding interest, and should I just let her play and wait and see where it goes?

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


Software to produce an interactive presentation? I'm tasked with leading a couple information sessions (totaling 4 hours) to teach non-programmers how to get started in Python. The audience is software testers employed in a technology department. I believe this would be pointless if it were a purely passive presentation of information, so I'd like to be able to include questions they can submit answers to while going through the presentation as well as interactive python shells to try to write snippets of code themselves. Ideally, I'd be able to view the answers and code submitted by each participant to be able to judge how well things are going and if there are any common misconceptions I need to clear up.

I've seen this kind of approach on instructional websites like Udacity. Does anyone know if similar software has been produced for public use?

Here are two ideas that might meet your needs:

Codingbat allows you to create a teacher account and your own problem sets.  You have to put in test values for all of your functions, but you can see the results that your students produce.
A worksheet.  "Now that we've covered that idea, go ahead and see what you can do with number 4 on your sheet."

Since you're just trying to make your lesson interactive, a low-tech approach might be your best approach.  Providing a work-along worksheet allows you to focus your time and energy on other parts of the lesson when you prepare.

Best of luck!