Is there a Java library for testing command line applications? JUnit seems to work well for unit tests, but I'm not interested in unit tests, I want to test and entire command line application as a black box.
I have created a text-based adventure game project for my students and I am trying to build an auto-grader. I do not have any web infrastructure and I would prefer to just creating a local application to test students' submissions. I also would like it to be easy enough to students to use to check their work (JUnit doesn't seem to be easily usable outside of an IDE).
I am looking to create a program that will attempt to compile a students code and run the game through all the possible paths. I could just build something like this from scratch, but I feel like there should already be some kind of framework to make handling test cases and printing results easy. I haven't found anything outside of web-based services, which isn't what I'm looking for.
Is there any library to help with this, or am I better off just making my own grader from scratch?

There is expect. It is designed to test interactive command-line systems. For non-interactive programs it is easier.
expect is not java, but as pointed out in the comments. The language is irrelevant, as the testing is done from the outside.


When does excessive collaboration become plagiarism? I was reading the abstract for this research paper: Yan, L., McKeown, N., Piech, C.: Using programming assignment work patterns to understand excessive collaboration in large CS classes, in SIGCSE 2018, Baltimore, USA, 2018

  As computer science classes grow, instructor workload also increases:
  teachers must simultaneously teach material, provide assignment
  feedback, and monitor student progress. At scale, it is hard to know
  which students need extra help, and some students can resort to
  excessive collaboration, using online resources or relying heavily on
  peer code, to complete their assignment. In this paper, we present
  TMOSS, a tool that analyzes the intermediate steps a student takes to
  complete a programming assignment. We find that students who exhibit
  excessive collaboration typically deviate from the standard work
  pattern, use fewer class tutoring resources than their peers, and
  perform worse on assessments. Our goal is to identify students at-risk
  of plagiarizing, so we can intervene and provide additional class
  resources to help them succeed.

So, my question is: where should the line between excessive collaboration and plagiarism be drawn?

I'm presenting this as an answer to preserve it. It isn't a direct response to the question, I know.

Let me draw out a conclusion from @BenI.'s answer.

The plagiarism "problem" in education seems to flow from a (IMO) misguided notion that all student intellectual growth must flow from that individual only without any collaboration whatever. I used to believe that myself, especially when teaching math, but less so in CS.

Certainly work in isolation can lead to A-Ha moments that indicate growth, but can also lead to deep frustration and abandonment. But collaborative work while it may lessen the former somewhat certainly tends to eliminate the latter. Many years ago, when I was a math student, most academic papers were by individuals. That is much less so now, and in CS, collaborative work is the norm.

Try to teach and organize your course so that plagiarism isn't an issue. Encourage peer work, peer teaching, peer evaluation, and all the rest. Find a way to evaluate individuals without requiring that their work be done in isolation. It better matches the work-a-day world that many of them will enter eventually. It reduces headaches, guilt, punishment. It encourages learning, sharing, and growth. Be a shepherd, not a judge.

How you do it is a question of course organization and project selection. Permitting collaboration also allows you to utilize larger, more challenging, projects than you might be comfortable with otherwise. You can impose rules in programming courses, of course, requiring role changes while pair-programming (driver <-> navigator) for example. You can sometimes choose teams or pairs yourself, and sometimes let them choose. For larger teams you can even use sandlot-baseball team choosing, which I've found to work. (You choose captains, the captains alternately choose additional members until everyone is on a team).

Don't just permit them to work together. Try to find a way to require them to do it. It is harder for off-site assignments, but not always impossible, especially if your institution provides some sort of common workspace for students.

The cited research seems to be about improving teaching, not about detecting plagiarism. No student should be accused of plagiarism based on statistical measures only. The paper seems to correctly make that point.


Real life examples of 0-indexing It can be perplexing for students to begin counting at 0 when they enter a CS class. I made it a point over and over to talk about "Day 0" and "Week 0" in the opening days and weeks just to build familiarity with the idea. Even so, I sought when explaining this idea to ground it in some real-life/non-CS example where we as humans use 0-indexing naturally and possibly without knowing it.

Question: where can we find 0-indexing outside of CS and grounded in everyday human experience?

I'll share the one example I can think of below (Q&A style), but I'd love to hear more, potentially better, examples.

[Note: This question relates to another I just posed.]

You can get at this concept very intuitively in strings before you ever get to arrays.  Take a string like "hello world" and ask them a subtle-sounding point: does the string begin here: "*hello world", or here: "h*ello world".  They'll certainly be able to identify the correct answer.

Then ask, "how far from the start of the string do we have to go to get to the 'h'?  Answer in a number of characters. Do we have to move 5 characters away? 3? 1?"  Again, they should be able to identify 0.

Now, it's time for the big reveal.  (My description here is in Java)

"When I want to get at that first character, h, I do it with myString.charAt(0).  Given what we just discussed, why do you think I would use 0, and not 1?"

At this point, they will naturally move to the idea that it is at the beginning, and that we have moved no steps from the beginning.

"Excellent.  This is an example of an index value.  And, in Java, when we do index values, we don't count from '1', we actually count the DISTANCE from the start.  So, if we want the first character, we move no distance.  And how far do we move to get the 3rd character? ..."

When you later get to arrays, you can remind them of the concept, and just say that it is being used again here.


Should I teach that 1 kB = 1024 bytes or 1000 bytes? Which conversion should I teach to my undergrad students? That 1 kB is 1024 bytes (binary) as everyone learned back in the nineties or the recent industry-led "friendly" conversion that says that 1 kB is in fact 1000 bytes (decimal)?

My immediate feeling goes toward the binary conversion, but when IEC says otherwise and major OSs decide for the decimal conversion (Mac OS X ≥ 10.6 and Ubuntu ≥ 10.10 now use the SI prefixes exclusively to refer to powers of 1000) I'm not so sure anymore.

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

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

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

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

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


How can we best inform potential students of the nature of CS? Recent questions deal with the problem of too many applicants to CS programs, both in High School and University. Yes, this is a problem when only a smaller number can be accommodated for reasons of resource availability. One of the easier issues to deal with is whether the student's past performance indicates potential success, though even this is hard. If the student hasn't studied Computer Science in the past, what courses are predictors? But this question is focused elsewhere.

Some students, in periods of high demand, choose a field simply because of its popularity at the time. While they may have the aptitude and background for it, their interest may be shallow or even misinformed. It would be good to help such students make better choices about their futures by informing them early of the nature of the field and how their future would likely play out if they stay in the field. The goal is to reduce the number of drop-outs: students who start a program, but leave it before completion. This potentially wastes both the student's time and resources as well as wasting institutional resources. It also risks denying other students an entrance slot that they might have had.

In particular, such students may not know all of the things that CS professionals do on a daily basis. What are the interesting things? What are the boring things? What are the risks? What are the rewards? What frustrations? What will they ultimately need to do to become successful, in either the commercial or academic worlds.

What resources can be brought to bear to assure that, possibly naive, students get a good look at the profession so as to better decide whether they want to enter?

Google provides a lot of information for "What is Computer Science?" This includes the summaries given by a lot of colleges. However, most of it stresses only the positive things and so gives a somewhat incomplete picture.

In the early 1960's as a teenager, I visited a local computer center. They had what was likely an IBM 650 with drum memory. I got to see what folks did back then and recall that I wasn't very impressed. I studied math. But CS wasn't an option then. But something more was needed in my case to generate interest.

For the record, I'm interested in drawing an accurate picture of work in the field, not horror stories or overly optimistic projections.

If the main issue is that the not-so-great side of programming (to pick one area as an example) is not disclosed, then tell people point-blank, in an admission conversation or while describing programming to groups:

  Programming is one of the most frustrating and difficult things that
  humans have ever devised to do.

I say that to all my students right out, usually the first day. I also tell them about the big egg-shaped rock I used to wave threateningly at the (glass CRT) screen when I got particularly frustrated. And I tell them about the time I had to go back to the bookstore to buy a different book about the intricacies of writing DOS interrupt routines for networking with IPX over Novell: the first book had a missing line in a code example.

It certainly is true that one can succeed with poor background and preparation. I hated math classes, and they probably would have helped me become better faster at programming (my first chosen career that I attended college to get to). There is no substitute for being really interested in something, interested enough to defy your parents and change your major in college, interested enough to press on through many difficulties, come what may. "Being carried along is not enough."

Loving it even when you don't really know what it is will work, I do not know what else will. As it says about qualifications in the book At the Feet of the Master:

  Love, if it is strong enough in a man, will force him to acquire all
  of the other qualifications, and all the rest without it would never be
  sufficient.

We are supposed to do what we love. Freud said that the keys to a meaningful life are Work and Love. Really, they are one.


Homework Policy for Advanced/Honors Students Perusing Twitter just now, I saw this tweet from the @CSTeachingTips account, and it got me thinking about the general topic of homework as it applies to our discipline:

  Downsize homework because, like a job, students should be able to do
  the work during business hours.

I personally struggled a lot with what and how much homework to assign my AP students this past year. I wanted it to be effective and not just "homework-for-homework's-sake."

I found students worked more effectively on coding when I was in the room and they could ask for help. If they hit a brick wall at home, they were stuck until a) they got to class the next day or b) they received an email from me (presuming they took the time to send one and I got it in time to reply in a timely manner).

On the other hand, the content required in an AP class, especially CS50 AP, seems to necessitate some work be done at home. There's a lot to cover, and class minutes are at a premium, so if homework can reinforce the day's work and/or give a head start for the next day, it's worth it. Yet, as with the tweet's sentiment, I want to honor the lives of students outside of just my classroom.

For my question, I'm thinking particularly of honors-level HS students (either AP CSP or AP CS A - I think this would apply roughly equally to both).

What homework assignments do you and your students find beneficial? What type/amount of work done at home is most effective for increasing student learning?

My students are already slammed with homework, so when possible, I try not to add to their misery.  I have done some formal polling of my students several years back, so I have used real data to balance my own approach.  Of course, as of this writing, I cannot find those numbers any more, so I will be working from rough memory here:

I mentally aim for 50% of the kids to be able to finish labs during provided lab time. In reality, it is usually closer to 15-20% of the kids who are able to finish the labs during the provided lab periods, but there remains a large portion are able to complete their work in <3 hours of outside work (something like 60%).  Only the remaining 20-25% had substantial work from the labs.  While I offer help outside of class, I have not found a reasonable way to prevent this problem; kids who are slow at labs will always take more time than I can provide.

If I am teaching a brand-new course with a brand-new curriculum, all bets are off, as I have very little sense of how long the activities will take.

However, I once found a Williams College professor's labs posted online, and she added a short question to the end of every lab to the effect of, "How long did this portion of the lab take you?  This answer will have no bearing on your grade, it is only used to help me adjust student workloads in future years."


How to learn to program compiled languages efficiently when coming from an interpreted language? I have experience with Python and now am learning C++, I am finding the lack of an interpreter or a repl to be a serious hinderance when learning the language, as well as the ability to type help(func) in the interpreter when I get stuck.

What changes to the development environment, or to my approach to learning, can I make to increase my speed of learning?

(Is there a typical development flow that compiled language programmers use that make them efficient?)

How do they create fast feedback loops between code edits and results?

Your question deserves a long discussion, but I will try to narrow it down to few points.

First, remember that you are dealing not just with a "compiled language" such as Java or C# (that could be much easier targets for you), you are dealing with C++ that was designed with backward compatibility with C as a killer feature, and C was created in late 70s. It means that C++ indeed implements numerous design decisions that look archaic/obsolete/strange for a modern learner. Say, the whole system of header files is a hacky substitute for a proper package management. Thus it would be good for you to study carefully major language features and understand the true reason why they exist. In many cases you'll find newer and better alternatives to old tools (such as std::vector objects vs. arrays)

Second, use a good IDE. For instance, if you place a cursor under printf() (or any other library function) in MS Visual Studio and hit F1, it will jump to the extensive online manual, so this is not an issue. Also you will get autocomplete features similar to those available for Python (e.g., type a variable name, then a dot, and see a list of member functions).

Third, think of a compiler as of a subsitute for REPL (and there are true REPL environments for C++, such as the one available at repl.it). When you type a Python program, you don't know anything about its correctness until you run it. In C++ you can catch many errors just by compiling. So by the time of the first run you will already eliminate all syntax errors and many other errors related to type mismatching. I was learning Python after C++, and for me a source of constant annoyance was to make sure that every single line of code is executed before I could even hope it is correct.

Thus your typical session will look like "type some lines -> compile -> type some lines -> compile -> run"). Since you are asking about "fast feedback loops", I can tell that really good C++ programmers invest considerable effort in the type system used in their code. They don't use int everywhere even if they can. They use incompatible types for incompatible entities, declare member functions as const if they shouldn't modify objects, and add static_assert statements where possible, and avoid type casting. In other words, they make the compiler do the job. In the best case, if such code compiles, it works correctly. So the real feedback loop is concentrated on the stage of compilation.

In any case, remember that C++ is a complex hardware-oriented language with long history (just look at the sheer size of Stroustup's definitive guide), so approach it with patience. Mastering it takes time, indeed, be persistent and don't expect fast results.


What hardware can I use when teaching Compiler Language and Assembly Code This year course includes creating a compiler of course using Syntax Analyzer and Lexical Analyzer, Semantics and of course through all this generate Assembly Code

But also the teaching program includes using at least a little piece of hardware to pass assembly code to it.

Does anyone know a programmable hardware that we can use just for education purposes?

We will pass assembly code to the hardware.

The 32-bit subsets of ARM assembly language are fairly clean, orthogonal and RISC-like, as well as being a reasonably nice target for a simple compiler.

Inexpensive Raspberry Pi's run 32-bit ARM code, as well as natively supporting a complete compiler development tool set (lex, yak, bison, et.al.)

Almost every student is likely to possess a mobile phone that will also run ARM machine code, and both Apple and Google provide free development tools that allow coding portions of a mobile app (iOS or Android) in ARM assembly language.

The 6502 and 8051 ISAs were not designed for modern compiler output, even though otherwise suitable for teaching hand-coded assembly language and running it on inexpensive (vintage or microcontroller) hardware.


Explaining pointers to highschoolers How would you explain pointers and their use to high school students with some prior knowledge in programming, mainly in Python, but very limited knowledge of C?

Note that this isn't a duplicate of Simple Pointer Examples in C, because here I'm asking for an explanation of how they work, not an example of them working.

A prerequisite to understanding pointers is a basic understanding of memory. At least on the broadest level, students need to know that when they declare a variable in their programs, that variable is stored somewhere, so they can use it, access it, update it, etc. Where that variable is stored also has some address, so it can be located (specific addressing techniques need not be introduced yet). The specifics of heap v. stack, memory size (int v. long long), and other such concepts are not necessary to understand what a pointer is (but they certainly would help).

All this background established, here is the easy way to think of pointers:

  A pointer is a variable that contains an address of a variable.

Simple enough on the surface. That sentence comes from Chapter 5 of K&R (The C Programming Language by Kernighan and Ritchie). This chapter has a great explanation of pointers and arrays, and I would highly recommend it for an understanding of pointers, at least in the context of C. One key point for C is the following:

  Since C passes arguments to functions by value, there is no direct way
  for the called function to alter a variable in the calling function.
  ... Pointer arguments enable a function to access and change objects
  in the function that called it.

Now, to get into the details of pointer arithmetic, passing by reference, syntactic sugar vis-a-vis arrays, pointers do become more complicated. However, always keep in mind the simple definition that gets at their essence: pointers store addresses for other locations in memory.


Explaining access levels and visibility in OOP While teaching OOP in a high school CS major (in java), it is important (and part of the curriculum in any case) to explain "what is the meaning of this public and private?" (A question voiced by many students).
The usual explanation is a technical one:

Something public is accessible from anywhere.
Something private is, well, private.
protected ??
default access (when no other access modifier is given).

As for protected, the students know about inheritance but the explanation of "it can be accessed by things down the inheritance tree" doesn't really get the idea through. Examples only show it so far and only works for a number of students.
So this got me thinking: How can access levels be explained in an intuitive way to high school students?
Note: I'm not only asking about protected, that is my main problem when explaining access levels.
Clarification
I am talking about access modifiers for objects and methods, not classes:
public class Example extends JFrame{ //the public in this line is not what I'm asking about.
    private int x; //this is the kind of private asked about
    protected void paintComponents(Graphics g){ //and this is also the kind being asked about.

Here's an analogy that I've used for several years, and that students seem to understand. It doesn't focus on the rules, but why we have public and private and protected.

"Most of you know that I live down at the beach. If you find yourself riding past my house, and it's hot outside, you might come to my front door, knock and ask if you could have a soda. I don't live in a gated community, so anyone can come to my front door and knock. My front door is public. However, you can't open the front door, walk right in to my kitchen, open the refrigerator door, and help yourself to a soda! My refrigerator door is not public.

My children and grandchildren, however, who live next door, think nothing of walking into the house and getting anything they like out of the refrigerator. In our house, the refrigerator is protected; my family can directly access it, but the general public cannot.

Not everything in our family is protected, though. My kids know that going upstairs, finding my Visa card, and charging a new book at Amazon, isn't permitted. My Visa card, and the contents of my wallet, are private. No one else can access them directly; they have to make a request."


Teaching the humble for loop So, in C-style languages, the for loop has a funny little syntax:
for (int i = 0; i < 100; i++) {
    // do something
}

If we order these sections in a natural, intuitive fashion, we would get something like:
for (1; 2; 3) {
    4
}

... which is how students seem to feel like things should be ordered.  But, of course, the real execution order is 1, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3...
What tricks have you developed for helping students make sense of for loops at the very start?

Show then how the loop can be unfolded into a while loop:
int i = 0 // Step 1
while (i< 100) { // Step 2
    // Do something
    i++ // Step 3
}

Explain that the order is derived from that unfolding.
You could start out by only teaching while loops, forcing them to make these while loops with iterators, then showing that for loops are a condensed of those while loops with incrementing variables.


How to teach C++ language to beginners of (BSCS) students who have no any idea about it? Some students come to CS field but they have no idea about any programming language. Either they will have the background of engineering or medical. But still they want to make CS their field. What technique should be applied on them to take start, clear their initial concepts and make ready them how to code any program?

While I would suggest a different language for beginners, I'll take it as given here that the students need to learn C++ and not just programming for general use.

In that case, teach them Modern C++. That means C++ versions 14 and 17 and don't bother with anything earlier. To do this find a good book that focuses on those versions (or later if you are reading this in the future) and has been developed by someone who has good knowledge of pedagogy as well as the language. There are a couple of books available on Amazon that meet this criteria.

Note that you give up nothing by starting with the current version. The book will still cover the low level details that were inherited from C and that are still useful. You won't spend time trying to learn the things that have become obsolete for modern software development.

But, the important point is that a modern language comes with a set of idioms that enable its proper use. A language is not just a collection of features that you combine arbitrarily. It was designed with a vision.

So, once you get beyond trivial programs, you want to learn the current idiomatic usage of the language (whatever it is) along with the lower level details. In particular, you don't want to spend time on the idiomatic usage of an earlier version of the language once they have become obsolete.

I will also note that programming in a language requires the programmer to adopt some mental model. If a language is well designed, then it is possible to program completely within that model without worrying about how that model is implemented in some lower level model. That is to say, the model will be both consistent and complete. So, a book with good pedagogy will emphasize how you use that model to create useful artifacts.

The advantage of Modern C++ is that many of the pitfalls of earlier versions (and especially those of C) have been removed through the use of standard libraries. Lots of the kinds of errors that seem invariably to creep into commercial software don't occur at all (and so fewer viruses,...) if the programmer understands the libraries and the proper idiomatic use.

There is no need to take an historical approach to computing, starting with machine level programming and working UP to some higher level. That was my approach, actually, since I grew up with that history and have been programming for over 45 years. I didn't then use the languages that I use today since they didn't exist, not because it was better, in some way, for me to use primitive languages first.

Note that if a language does not provide a complete and consistent abstraction model for programming (if it isn't Turing Complete) then you would have to try to understand its features in terms of some lower level implementation mode. Otherwise you can learn the language directly and understand how the parts fit together idiomatically to write any program using a single mental model.

If you, as an individual want to learn everything bottom up, then go ahead. But if you are a teacher, I suggest that you don't impose that way of learning on your students. It is inefficient and unnecessary.

Once the students learn to program at a given (complete and consistent) level of abstraction they can then learn about how things are built or use them to build higher level abstractions.

If I had a choice of first teaching language today, it would probably be either Haskell (functional) or Scala (Object oriented). Both of these offer complete and consistent mental (abstraction) models as well as rich libraries. The teaching method would be to teach the idiomatic usage, not just the features. There are others that would serve equally well. The mental model needs to be taught along with the language. That is a pedagogical issue.

However for someone with less background in language principles and in programming pedagogy, I'd probably rather recommend Python or Java, just because of the wealth of teaching materials available, combined with a rational abstraction model. Creating good teaching materials in any language is hard work.

I'll also note here that many people have the experience that the second language they learn is the hardest, especially if it is either quite similar or quite different. That is due to the fact that your first language teaches you (you believe) how to program, so, the new language feels awkward and one tries to apply the idioms of the old language to the new one. It won't work. Even languages as close as Java and Ruby have different idioms.


What are effective approaches for teaching dynamic programming? Dynamic programming is a subject that's notoriously difficult to learn and to teach. It's one thing to educate oneself, say by reading the appropriate chapters in Kleinberg & Tardos or CLRS, and working through a sufficient number of example problems. It's another matter to learn or teach this material in a classroom setting at the high school, undergraduate, or graduate level. Intrinsic to the subject is the skill of identifying the type of problem structure that's amenable to the dynamic programming approach.

In light of this, what are effective approaches for teaching dynamic programming?

I think it's really about breaking down the concepts into smaller pieces. First a student needs to understand recursion well, then they can understand memoization and dynamic programming. It's hard to just jump into  e.g. the knapsack problem without first having worked through simpler problems. After one gets practice with the basic concepts, dynamic programming isn't inherently so difficult. Here's a basic way one can break it down:

Recursion

As an alternative to loops
Binary search
Divide and conquer
Backtracking

Memoization

Backtracking can be inefficient. Why not cache the results as you go through them?
Simple problems, such as reaching a specific sum with certain coins.
Can then consider harder problems, where a 2D array is required.

Dynamic programming (DP)

Consider the coin sum problem again. How would one be solve it manually for the numbers 1 - 10? Can this "build-up" solution be put into code?
Solving more advanced problems with dynamic programming instead of recursion/memoization.
Identifying problems for DP approaches - Partially this comes with experience of solving a few different problems. But there's a standard pattern one can recognize - if a recursive solution can be used to get a solution very inefficiently (by repeatedly searching through the same subproblems), then memoization and DP can be used to make it more efficient.

(If you're interested, I also created a free tutorial on Recursion that breaks it down as above with programming challenges.)


How should educators ensure their curriculum remains relevant over time? I'm sure we can agree that there are some parts of theoretical CS that are unlikely to change - topics such as computation theory (Turing machines, automata) will be useful and applicable for many years to come, [or at least until quantum computing becomes hugely pervasive]! I think a strong theoretical base is extremely important and I greatly enjoyed the modules I took at university which covered this sort of theory.

Most courses do include a practical aspect, though. One of my frustrations as a student who started at university with experince in professional software engineering in industry, was that a lot of the more practical content was incredibly outdated, not in line with industry best practices or just downright irrelevant.

As a concrete example, I took a web development module in 2015 which focussed on PHP 4, taught us to write code riddled with XSS, CSRF and SQLi vulnerabilities and didn't place any emphasis on architecture design. Some parts of the course were useful (such as the primer on how HTTP works at a protocol level) but it was obvious the same slide deck had been reused year after year and I came away feeling like I'd wasted my time. Some of these details seem to be out of the lecturer's hands and determined by the department, but the end result is still the same. I do realise web is perhaps one of the worst areas for this, but it's equally applicable when e.g. introducing Java and not covering the "new" generics support, or the more functional features in Java 8.

What can educators do to try and prevent this from becoming too big an issue? I think trying to keep up with each new shiny JavaScript framework that becomes momentarily popular is unrealistic and useful for neither student nor educator - but there must be some middle ground. Should these sort of modules be entirely theoretical to avoid this problem, or perhaps collaboration with industry could be sought out to explain how things really work in practice?

As a wise man once said, "We are preparing students to solve problems that don't exist / using technologies that haven't been invented."

I agree with alephzero in the sense that you can't avoid this issue.  Every sign is that technologies will keep changing rapidly, at least for the foreseeable future.

This is why we must always keep our instruction oriented towards concepts, not languages.  The syntaxes for arrays and lists will differ in different languages, but the trade-offs between the two remain the same.

One easy way to keep the emphasis on the conceptual is to utilize more than one language.  Over the first 3 years of our major, all students work in Python, Java, C, 6502 Assembly, and Scheme.  Additional languages are used for electives, depending on the nature of the course content.  By providing a more varied exposure, students can easily come to differentiate the underlying concepts from the syntaxes of the languages they are learning.


Publication outlets for research by undergraduates? In mathematics, we have lots of undergraduate research journals. In CS, you can publish by either conference proceedings or journal papers. Are there peer-reviewed conferences or journals aimed at research by undergraduate students? I am already aware of MCURCSM (but it didn't happen last year, and might not in 2019 either). Thanks!

I am not aware of any journals for undergraduate research journals in computer science. Note that anyone can submit to the journals and conferences, there can be student only papers.

ACM does have a student research competition at two levels, one for undergraduates and one for graduate students in computer science. Those are held at many conferences.

ACM SRC Web page


Book recommendations for rigorous CS books I am a mathematician but I would like to learn basics of computer science. I have seen many books that are fine but has some mistakes. For example, Introduction to algorithms even says that one should use $f(n)\in O(g(n))$ but still uses the notation $f(n)= O(g(n))$.

Is there university level computer science books that are suitable for person who wants to study computer science on very rigorous books, or that are aimed to mathematician?

The Art of Computer Programming in four volumes by Knuth is an obvious choice.

The first chapter of the first volume is a pretty solid course in discrete mathematics all by itself. If you can do all of the problems in that chapter you can earn a PhD in CS. (Some of the problems remain unsolved, I think - at least they were when the book was first published.)

Knuth is a Mathematician turned Computer Scientist and gives the mathematician's view of the field about as well as anyone can. You can depend on the accuracy of the book as the author has induced the community to drive out all inaccuracies using bounties.


What do I do if my computing teacher does not teach the subject properly? I'm a student in the UK, and I have a computer science lesson every two weeks. Most people would think computer science is my favourite subject, as I started coding from a very young age, but the computing teacher cannot teach it properly.

Firstly, she teaches things like copyright and made me spent a lesson researching a lawsuit between Ed Sheeran and Matt Cardle. She hasn't taught us a single programming language except a few lessons on small basic once, which there is obviously no need for, and she could have taught a modern language like python or JavaScript. We spend a month or so making magazine covers in Adobie's photoshop. We were recently doing “Should the internet be a human right?”, which isn't remotely useful. I have shown her the wikipedia page on computer science, and she says stuff like “Wikipedia is not credible” and “I know the syllabus better than you”.

Secondly, we had a test recently, and I answered all the questions correctly (to the best of my knowledge, and checked after), yet she marked many questions wrong, for example, one question was “Why may someone not be able to access the sites on the internet (Give 3 reasons)”, and 2 of mine were “Legal Restrictions (eg, article 13)” and “ISP may be blocking/slowing down the website (Due to the removal of net neutrality)”, and she marked both answers wrong. She also gives incorrect answers marks.

She also teaches things which are incorrect, like “This spam email is a spam email because it recommends using Firefox, which is an insecure browser”, and when I say it is not, she says it is because she doesn't like using it.

Is there anything I can do about this?

All of that is in the key-stage 3 syllabus (it is not all programming). However it may be that the teacher is over focused on one bit.
What is in the new computing syllabus
The new computing syllabus (post ICT), consists of three parts: Computer science, IT, and digital literacy. The timetabling people often make up name, so not wise to get to hung up about it.
You can download the syllabuses, here are some resources:

https://www.computingatschool.org.uk/data/uploads/ComputingCurric.pdf
https://www.computingatschool.org.uk/data/uploads/cas_secondary.pdf
https://www.computingatschool.org.uk/data/quick_start_secondary/progression_path.pdf

Where does copyright fit in
Within digital literacy there is a small section on, aspects of the law and ethics: copyright, patent, trademark, computer misuse, privacy, plagiarism sharing is caring, free software, etc; internet safety; evaluating resources (e.g. Wikipedia articles).
Copyright is a small part of the syllabus. Here is where copyright is mentioned (indirectly):
“They need to be aware of their legal and ethical responsibilities” — page 15 of https://www.computingatschool.org.uk/data/uploads/cas_secondary.pdf and “Explains and justifies how the use of technology impacts on society, from the perspective of social, economical, political, legal, ethical and moral issues” — last column grey section of https://www.computingatschool.org.uk/data/quick_start_secondary/progression_path.pdf
What to do next
Check to see if you teacher is only teaching part of the syllabus, then consider helping by sharing some of the resources below.
There are also a lot of teaching resources, here are a few.

https://csunplugged.org/en/
https://helloworld.raspberrypi.org/


How do I construct a basic lesson on computational complexity and undecidability? Essential Understanding 4.2 of the AP CS Principles curriculum is as follows: "Algorithms can solve many, but not all, computational problems." Among the topics I am expected to cover in the context of this standard are algorithms that run in a reasonable time v. those that don't, the difference between solvable and unsolvable problems, the use of a heuristic, and the existence of undecidable problems.

My plan is to cover the 0/1 knapsack problem, the heuristic of a greedy algorithm, and the halting problem. This is a relatively small part of the course and is assessed by only a couple of multiple-choice questions on the AP Exam, so I don't need more than one lesson (or two) of material.

That said, I am afraid any one-day lesson will be inevitably reductive as these are complex topics. Moreover, the students are new to programming and computer science in general, so I need to balance abstract with theory with concrete, relevant examples.

What lesson ideas, examples, and/or analogies do well to serve the teaching of this standard?

The hard parts of this are hard for everyone, of course: P = NP (or not). But the others aren't too difficult to get across in a short period of time, especially if the students have something of a math background.

You can easily construct problems that grow exponentially and whose programs for solution must also grow at that rate. Drawing a completely connected graph for example and adding vertices.. Listing all of the permutations of n distinct elements, for example.

The halting problem is great, of course, and you can often use a graphic to illustrate the problems: a machine that takes machines as one input and tapes as another.

But you can also convince students that most problems don't have solutions as there are only a countable number of computer programs given any finite character set. But the number of problems is uncountable. The fact that we know of only a few unsolvable problems is similar to the fact that we know only a few non-algebraic numbers, though most (again uncountably many) real numbers are not algebraic while only countably many are algebraic.

But laying out the broad outlines (feasible, non-feasible, non-computational) lets you say a few words about what we don't yet know and why CS, like math, isn't a fixed body of knowledge, but a field ripe for research.

You can even go a bit farther and talk about the issue that for some problems a solution is hard to find, but easy to check, which is fundamental to encryption. It is hard to find factors, but easy to check that they are factors once found. This gives you a way to talk about nondeterministic algorithms of which "repeatedly guess and check" is one variety.

One final idea that can be fun. Assuming you have already covered sorting to some extent, you can have the class, or small groups within the class, brainstorm the most inefficient sorting algorithm they can think of. But it needs to be an algorithm, not just randomness. But "Mix the values and check if sorted. Repeat until done." is actually an algorithm if your mixer is truly random. That is, it is guaranteed to sort.

If your students know some calculus, you can mention Newton's Method for finding zeros of a function. While it seldom gives you the exact value it is a process (pseudo algorithm) for guessing and then improving the guess in the next iteration. I say "pseudo algorithm" since it isn't guaranteed to terminate or to find an exact answer. But it is an improvement on pure "guess and check"

A resource on Non Computability and its relation to self reference and recursion is this paper by Owen Astrachan of Duke


Ways to do live polling (aka ConcepTests) during class Has anyone tried live polling during (in-person or remote synchronous) class? I was planning to use Poll Everywhere, but they don't allow for long questions containing code. There's a new service called ItemPool that does allow this, but is missing advanced features like LMS integration, PowerPoint/Keynote/Google Slides integration, etc. Wondering if anyone has experience or advice. Here's a sample question:
What is the value of y after executing the following code:
x = 37
y = x + 2
x = 20

a. 39
b. 22
c. 35
d. 20

Edit:
Thanks for the great ideas!
I've realized my wish list (LMS integration, code formatting, autograding and export, support for mobile devices so I can reuse once we're back in person, free) is unreasonably long.
I may give up on tracking participation for a grade - this will allow me to simply post the question on a slide, and collect simple A/B/C/D responses any number of ways: Webex polls, Poll Everywhere (free account), ItemPool (which has code formatting), etc.
If the questions live in my slides rather than hardcoded into a specific platform, it should be less work to switch platforms in the future. And I'll have greater control over the look so I can include formatted code, equations, etc.

My students are all on a Discord server with me, so when it comes time for polling, I hijack the reaction system in Discord to get it done.
One nice feature is that it does syntax highlighting for any language that you specify, and you can also install mathjax on your server if you'd like to be able to represent mathematical functions.  Here's a question I polled recently.  The question itself is quite a lot of fun, and is from Java Puzzlers by Bloch and Gafter:
**What will this Java code output?**

```java
public static void main(String[] args){
   final String pig = "length: 10";
   final String dog = "length: " + pig.length();
   System.out.println("Animals are equal: " + pig == dog);
}
```

React with:
:one: `Animals are equal: true`
:two: `Animals are equal: false`
:three: `false`
:four: The code will fail on an exception

This outputs in Discord as:

Students then react with one, two, three, or four.1
It doesn't allow reactions to be hidden, so if this is an important feature to you, then I would look elsewhere.
I've also found it useful for getting a sense of where my students are in an activity when they go to breakout rooms to work in pairs or trios:

This is very informal polling, but you can see how useful such information can be during virtual instruction.
1 - The answer is 3.  Surprised?


Exercises for teaching GUI / Windows interaction basics It is now very easy to plop together some visual User Interface controls on to a form and hook them to events. In Microsoft Windows, there are a staggering number of properties and events available for controlling all aspects of a GUI. While simple apps can be created in moments, more complex ones involving enabling / disabling sets of controls, etc., can be fraught with unexpected complexity and paradox.

What are some good initial projects for working with just the UI aspects of a design? Ignore all the details of what the events will actually do, and get the user interaction working, to do some nontrivial things? We are currently using as our textbook "C# Programming" by Doyle, and the Windows GUI section is chapters 9 and 10. The examples in chapter 9 had some poor practices (while loop inside a button click event handler?) which might be improved on, perhaps with the more detailed information in chapter 10, which covers input controls such as textboxes, radio buttons, checkboxes and listboxes.

One example I created was of a simple method for students to "clock in and out" of the classroom sessions (as part of workplace readiness training). It looks bone-simple: a little box with their Windows Domain Name, two radio buttons for IN and OUT actions, and a few read-only textboxes that display accumulated time for the day and week. (It connects to a database on a server). I wanted the interface to behave "a little strangely":

Neither radio button would be checked when the program starts
Attempting to clock IN outside of time bounds would show OUT
A database access failure shows NO radio buttons checked
The app becomes 'topmost' at the start and end of each time period
It stops being topmost when the user interacts with it

This takes some interesting code and unusual settings at design time, yet it creates an ideal interface to allow the desired functionality and nothing undesirable. It could not be simpler. What other examples of Windowing interface situations would make for concise, understandable and broadly applicable exercises? How can the students learn the pitfalls of event-driven interfaces without having to master them entirely? In particular, what does not make sense in an event-driven scenario?

The last time I took a session on UI, that was when I was teaching these students who had finished a course on C sharp (dot net) and now wanted to build simple UI so they can turn their just learned programming skills into visibly usable software.

Since they were on dot net, I advised them to start by building a calculator using WPF. When I say calculator, it was a simple calculator. Build the number pad, and then implement just the addition and subtraction. While many of them were proficient in programming, they found themselves baffled...connecting the UI with code that would otherwise work just fine on the console. As they got the hang of things, I asked them to add more and more UI elements, until they had a full fledged scientific calculator with a fairly complicated UI.

My advice to those who are new to UI is to allow the UI to evolve, and make sure that your backend development skills are up to the mark.


To plan or not to plan that is the question We are often asked to plan: We are asked to make lesson plans; When I was a programmer sometimes I was asked to create a plan; We are told to ask our students to plan their projects.

However there is often a problem with this:

As a programmer,
I could not plan everything upfront. There is a lot of discovery in the development process. If we knew what we were doing then it was because we had done it before. If we had done it before, then it was a bug that we were doing it again (we should be reusing).
As a student,
I have been in a class room where a teacher has told students to plan / design a project, and that then after that they would be taught how to program it. This often does not go well, as students can not plan for something that they have no experience of.
Teachers seem to think that this is the “Correct way to do it”.

Another approach is test driven development: Ask what next, Write simplest test that will fail, Write simplest code that will make test pass, re-factor if needed, repeat. This works most of the time. However, there are times when it does not. For example, the other day I was making an adding machine out of lego (my own design). Part of the build was tinkering and experimenting, but for part I stopped and wrote a plan. It was easier to plan on paper than as I went along, as mistakes could be fixed more easily (it is hard to fix an error in the middle of a lego model, you have to take it apart).

I seem to have an intuitive feel for planning (just enough, and just in time). However this is probably not a good explanation to tell others.

When students are doing project work,
When is planning and high-level design a good idea? When is it not? How do you tell the difference? And how do you teach this to the students?

I work with pupils years 10-11 (age 14-16), and 12-13 (age 16-18).

As you suggest, it is a subtle question. Twenty-five years ago, the answer was simple: Plan. But too many software projects crashed and burned because of over-planning and sticking to the plan after it was obvious to all that it was the wrong plan. More recently, the initial failure of the signup system for the Affordable Care Act was likely caused by this same failure of thinking.

Plan if you can, but be flexible enough to deviate from the plan when needed.

That sounds like good advice, but it can, itself, be the root of too many problems. If you have a complete plan you are likely to be willing to expend resources at the beginning that will only recoup their investment if it proves to be the correct plan but will be wasted (sunk cost) if the plan proves to be incorrect.

So, with a complete plan you can build the thing at lowest cost if the plan was correct. But you wind up with a failed project otherwise. Not only have you spent money on the incorrect plan, you have expended time and your competition may have moved ahead with a better solution. You are both late and poor.

When you can't plan, build on a tight feedback loop.

That is the key message of Agile development. All of the practices of, for example, Extreme Programming and Scrum flow from that message. The implication is that you don't expend resources on speculative assumptions about where the project will go. It does mean that (a) you sometimes can't take advantage of economies of scale and scheduling but (b) you don't get caught with sunk cost that you get no benefit from. In today's development environment (rapid change) this is usually a better assumption to make.

My advice to educators is to learn everything they can about Agile Development, whether you decide to adopt it or not. The ideas are interesting in themselves and can prove transformative if not viewed too narrowly as just a set of practices.

And, of course, read the Mythical Man Month. Its message is valid yet, though it was written for the BUFD (Big Up Front Design) era.

Note that agility goes beyond software development. The principles of agility (see the Agile Manifesto) can be reapplied in different ways to vastly different things.


Best Way to Explain Distinction Between Void vs. Return Functions in JavaScript I am familiar with the concept of void and return methods in Java, and am teaching a course in JavaScript, programming Sphero robots. I think I have the gist of how to explain these concets, but am slightly concerned since I can't find any good examples of NON- return (void) functions used in the JavaScript. It seems that the keyword 'void' is only used to indicate an expression without a return value. The problem is, I need to differentiate between void and return methods/functions since you cannot use an Async function with a return function.

Is this concept of void and return methods in Java analogous to JavaScript as well, or is there a better keyword that I can use to explain the different kinds of functions?

Another thing I would like to explain, is, what if you are calling a function, but you don't know what was coded to create it? Is there a hard and fast rule or way to tell if something is void or return?

A function to perform a procedure often has a void return type. For example:

function foo(a, b, s)
{
    // tell sphero s to go one direction a, another b
}

You are executing a procedure as a side effect and are not returning a computed value.


When teaching Web Development, should server or client side come first? I teach full stack web development because the purpose of the course is to give an overview of how a complete website is created, from SQL for database management to HTML/CSS/JS for front-end to ruby on rails as a backend. Would it be better to teach the front-end (HTML/CSS/JS) first or the back-end (Rails/SQL)?

My instincts would suggest front end because the students can type something and immediately see results which can be much more engaging, but teaching JS as the first "real" programming language also bothers me because of the many confusing and missing language features.

Starting with frontend does not necessarily mean starting with JS. You could first do HTML and CSS, which is engaging, as you mention. Then proceed to Ruby for the backend (whether Ruby is suitable as a first programming language is another debate), i.e. generating static pages dynamically.

JavaScript could come at the end of the course. This is also how things went historically, more or less. I would say this order makes the reasons for JavaScript (faster and smoother interaction, a.o.) stand out better.


How does one create a balanced AI curriculum in light of the popularity of Deep Learning? During the past decade, interest in machine learning has exploded, especially due to the many and growing successes of deep learning approaches using convolutional and other neural networks.

To those familiar with a modern artificial intelligence curriculum, say embodied by Russel & Norvig, ML may be safely regarded as a proper subset of AI. Yet due to the increasing popular attention to ML, more and more we bear witness to the conflation of AI and ML; even some computer scientists use AI and ML interchangeably.

As CS educators who teach AI courses, how do you develop a balanced curriculum that incorporates ML, yet pays attention to crucial problems like commonsense reasoning and inference, which don't share the spotlight with ML and have so far, in fact, proven resistant to ML approaches, including deep learning?

I suppose the design of the curriculum revolves around the goal.

If the objective is to prepare students to enter the field as researchers, then the balance needs to favor the research that's active (and probably employable.) Where that fits into the AI picture as a whole is helpful. What limitations it has, and the missing pieces it doesn't solve are important to recognize, but have less weight than the targeted areas.

If the objective is to provide an overview, or survey, of the AI field, then deep learning and machine learning are only promising avenues to solve part of the puzzle. A balance in this case should include the history as well. Including the previous "promising avenues" that didn't deliver all they were supposed to deliver. Temper enthusiasm with reason and perspective.

Showing how the lesser-known areas are important, as well as their resistance to current approaches can help too. Even if the students will enter ML, a big-picture view will help them know where they're going.


How can I prepare CS majors for non-programming jobs? I teach at a 4-year liberal arts college near Silicon Valley. Our stronger grads are able to get programming jobs straight out of college. In addition to preparing them well academically, I've worked as a software engineer and, while in industry, interviewed software engineering candidates, so I can coach students on interview skills.

Not every CS major is a strong programmer, at least at that stage of their life. What other good jobs can I suggest to students who aren't great at or don't enjoy programming, and how can I prepare them for these jobs? FWIW, many of our students have strong writing and interpersonal skills.

Sci/Tech journalism
There's a common complaint that people in science journalism, who may have journalism or English academic backgrounds, are okay at writing but vastly underinformed about the computers (or physics, or chemistry, or other subject matter) they're writing about. I've seen it firsthand, and while there are of course exceptions, the complaint is justified in many cases. Your students would have a big advantage in this field because of their technical backgrounds, especially since you mention writing and interpersonal skills. Some basic journalism and psychology coursework might be handy, in my opinion.

Tech writing
Also in the writing category, there's the field known simply as technical writing. Technical writers often deal with creating documentation or manuals but may work on any specialized, um, writing that is technical. In my experience, these people often have either English backgrounds, with most of the rest having technical backgrounds, and whichever one you have, you're perceived as not having enough of the other. There's no running around and interviewing strangers as there is with journalism, so brushing up on writing skills on paper is the first thing I'd recommend here.

Requirements engineering
Adjacent to that is requirements engineering. Reqs engineers are on technical teams and work with programmers but don't do any coding themselves. They think bigger-picture about what the needs of systems will be, communicating with customers and developers and other relevant people (I suppose I should say "stakeholders" but that feels so business jargon) to figure out what a project should do, what it reasonably can do, and how it should do those things (and also, what it shouldn't do).

I haven't often seen requirements discussed at the undergrad level, but they're also not full-on graduate programs. Not that I think you're looking to recommend grad school here anyways. If finding and taking the one graduate requirements course isn't an option, I'm not sure what I could recommend to prepare for this one. Having a CS background will be a huge advantage, and I would almost say necessity, for such a position, though.

Evangelism
An answer that may be a bit more specific to your students specifically, based on your description of your school and your other activity on this site: evangelism. You don't need to be sitting in front of a computer writing code to care about the pipeline problem. The main issue with this answer is that there don't seem to be many places where you can get paid to work on this. Organizations that deal with diversity issues tend to be non-profits that lean heavily on volunteers.


Allowing students to work cooperatively on a computer, and retain access to their work I like pupils to work in pairs, as they learn quicker this way, and need teacher help less often.

However, there are problems, when working together on a computer:

Free loaders. For this, I give them two roles: Driver and Navigator. The Driver controls the computer, the Navigator does most of the thinking, and tells the Driver what to do. They then switch role often. I manage this by walking around.
Access to previous work, when the partner is not present. Because pupils have to log in, and use a single account. There is a problem if the account holder is not present (ill), or if I want to re-pair students.

Has any one any experience with this 2nd point, and do you have any solutions?

I am mostly looking for non-technical solutions. I will add a technical solution.

Edit: I am not only asking about programming. There may be other work on the computer.

Actually, in true pair-programming no one works (or at least modifies any code) unless the partner is present. This is an important rule as I've seen really bad things happen when one member of a pair (or team) thinks he/she "gets it" and doesn't. I've had to spend half a day backing out "improvements" that were really misunderstandings by the perpetrator. People are not, however, forbidden to think about the project when alone - which would be foolish. To ease the offline thinking, pairs can be encouraged to simply email the existing code to both members so they have a basis for their deliberations. Printing it is even better, as it can be marked up on the bus, etc.

To solve the other issues, you could create meta-accounts for the pairs in which pair members know the credentials and change them when pairs are reassigned. Using personal accounts for group work is probably a mistake.

One way to manage exchange of ideas and peer-teaching in such a situation is to let pairs work for a while, swapping roles as appropriate, and then mixing up the pairs. The navigators at that moment move to a new station and the driver stays with the one they are "driving". The navigator continues to navigate, coming up to speed for a bit.

However, a caveat, and a suggestion for your overall process. I consider it poor practice to swap roles by the clock. They should switch at natural points. The classic one is that the driver drives until he/she gets stuck and the navigator, who has been really navigating and not just observing, knows how to proceed. Rather than make a suggestion about how to proceed, the navigator just takes the keyboard and continues. This may not be sufficiently often in the classroom as some students will (foolishly) try to dominate and others (equally foolishly) may try to ride along for "free". So...

Another way to encourage frequent switching is to combine pair programming with a strict pre-test rule: No code without a failing test. Switching then goes like this. One partner writes a failing test for the code and the other takes over long enough to (a) make that test pass and (b) write another failing test. Then they switch again and continue. This has been called "heartbeat" switching. It also encourages the navigator at the moment to stay engaged.

The navigator is NOT an observer. Don't let students think that it is easier than driving. It has an important "strategic view" purpose that complements the "tactical view" of the current driver. With no need to think at the detail level, the navigator keeps the direction of travel in mind. Both participate equally, though differently. Make sure students understand that. The job of the navigator is definitely NOT to get coffee for the driver, nor even to do background research. Both should do those things together.

For paired/group work that does not involve just programming you should seek to assure that the members of a group don't just "divide up the work" between them, but actually work cooperatively on it for all phases. Students think that division is a great idea until they reach the point of trying to integrate possibly inconsistent separate work. On Agile teams, pairs work together, but the team's pairs work on different things. The daily Stand Up Meeting is the way for all of the pairs to assure that they all work toward the common purpose. So, you might institute a practice of daily face to face meetings in each pair/team so that if they work separately they do so only on small and easily integrated things rather than big chunks that don't necessarily fit together.

Additionally, in a course that uses pair and group work extensively it is a good idea to use peer evaluation. In addition to the suggestions at the link you can use index cards creatively to capture the individual evaluations and create a matrix form in which to record them. I'm assuming that you change teams/pairs, so that students get to work with a variety of partners. It is really only necessary to record the exceptional evaluations (good and bad). The matrix lets you see not only who is consistently given good or bad evaluations, but also lets you see who gives consistently good or bad peer evals.


Teach smart pointers to beginners with no knowlege of OOP or templates I have to teach an Intro to Programming class of students with some exposure to proccedural programming, arrays and loops etc. However, they have not taken any course in oop and templates. It is a requirement of the course to teach pointers. I felt teaching raw pointers only will be incomplete; it is appropriate to provide the students a fuller, mordern C++ Intro wrt pointers. This implies teaching smart pointers.
How do you explain the syntax of smart ptrs to these students without having to teach them first about classes, constructors & destructors dynamic memory and templates?

I hate giving advice like this, but my honest advice here would be not to do so.  Or, at least, don't do it without consulting with your colleagues first.
Students (and your fellow teachers in future courses) depend on you getting through the required material in the course.  If you find that you have extra time at the end of the semester, then by all means, go back and try to take a stab at smart pointers.  But I wouldn't endanger your odds of getting to the end of the material that students will be expected to know in future coursework.  That could create far larger problems for the students going forward.


Fun way to teach algorithms I will teach algorithms for 4 days for some students. It will be their first course in computer science before learning coding with Java.

My fear is to bore them as I was bored at the university :(

Is there a fun way to teach algorithms ?

A loaf of bread, a knife, a jar of peanut butter and a jar of jelly.  Write an algorithm to build a PB&J.  Have one of the kids follow the literal direction written by a different kid.  This project have been a favorite starter for algorithms for 30 years.


Transition from Java to Python I am preparing to teach students python, in addition to java.

Usually, I test a proof of concept (POC) of my teaching with a handful of students, so as to know if my lesson plans are good (I teach the lesson to 4-6 students of varying skill and then I ask them for feedback). This time, the students were introduced to Python, after they were taught Java (They were taught OOP and basic I\O).

For the POC lesson in python, the feedback I received showed the difficulty in understanding the difference between Python and Java. Python felt so different (and rightly so) to the students, and they couldn't quite understand how it works, when compared to java. They know java has the runtime environment which runs compiled code, but they don't know how python runs the code they write. This difference I'm referring to. That isn't the only difference they had difficulty with.

So, in an attempt to make the introductory lesson in python to the rest of the students, I am trying to explain those differences beforehand.

How can make the transition\introduction from java to python more smooth?

TL;DR Use the Python module dis to show students Python's bytecode alongside Java's bytecode. Avoid the "compiled v. interpreted" rabbit hole to start (because it may lead to more confusion than clarity) and instead show students what's actually happening underneath the hood.

Begin by defining "bytecode" in the context of Python. Here is the Python 3 documentation:

  Python source code is compiled into bytecode, the internal
  representation of a Python program in the CPython interpreter. The
  bytecode is also cached in .pyc files so that executing the same file
  is faster the second time (recompilation from source to bytecode can
  be avoided). This “intermediate language” is said to run on a virtual
  machine that executes the machine code corresponding to each bytecode. [emphasies added]
  Do note that bytecodes are not expected to work between different
  Python virtual machines, nor to be stable between Python releases.

That might sound to students not too dissimilar from their experience with Java and its use of a virtual machine. Also, take a close look at the documentation for the dis module.

Let's consider this very short Python program test.py:

print("Hello, CSEducators.SE!")

If I run the command python -m dis test.py, I see the following Python bytecode:

  1           0 LOAD_NAME                0 (print)
              3 LOAD_CONST               0 ('Hello, CSEducators.SE!')
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE

Now, let's write Test.java:

public class Test {
    public static void main(String args[]) {
        System.out.println("Hello, CSEducators.SE!");
    }
}

I run javac Test.java then javap -v Test.class. Here's a small part of what I see:

  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String Hello, CSEducators.SE!
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 3: 0
        line 4: 8

This is only a small part of it; the full output leaves a lot to explore. Nonetheless, at this point, students will see fewer differences than similarities (hopefully).

Additionally, consider this SO question: "Compiled vs. Interpreted Languages". It's not quite so black-and-white, and forcing it into a pure dichotomy may do more harm than good.

Let it be a bit messy. That's what learning is all about.


In what branch of science does technology belong? The question may be found in the following link. I have been asked in the comments to provide my question on this Stack Exchange site.

Is there a word for mathematics/physics/data-analytics/…?

Actually, technology per se isn't science. But then, neither is mathematics. Technology is normally about the creation of things. Science is about using a certain methodology for trying to discern the truth about the world and natural processes. If you define natural processes broadly, including human processes, then social science is also science.

But mathematics is about using logical process to explore the implications of basic assumptions (axioms).

But both science and mathematics are about ideas, whereas technology is about things.

Technology, as in iPhones and respirators and all, is about the creation of useful things. That is basically why you can patent inventions, but you can only copyright scientific papers.

Some sorts of technology, say vaccines, depend on science to assure safety and efficacy. And some sorts of technology depend on mathematics, such as computers and bitcoin.

Computer Science has elements of both science and technology. But one normally gets a PhD in CS for discoveries on the scientific side, even if the science is an exploration of something created on the technological side. CS actually has elements of mathematics as well, such as in algorithm analysis and computability theory.


Computer Science in the Waldorf curriculum How should computer science, software engineering or ICT be integrated into the Waldorf curriculum?

Steiner-Waldorf education derives from the anthroposophical philosophy of Rudolf Steiner, and places lots of emphasis on Music, Art and Craft. Students study a "Main lesson" in the morning, followed by specialist lessons (though the exact pattern varies from school to school). The issue of "age-appropriate learning" is very important.

The "Yellow Book" of the Waldorf curriculum mentions computing, but it is short and seems not to have been updated since the 1980s.  Anthroposophical theorists have a distrustful relationship with TVs, Computers and other devices with screens, which makes teaching computing difficult.

Have any Waldorf teachers taught computing in their schools? How did you do it?

I'd particularly like to know at what age should children start learning, and how should they progress in computing in the Waldorf context. and did you teach computing in the main lesson or later in the day?

Waldorf / Steiner and Technology Use

Waldorf schools aren't against the use of technology in education, they take the stance that introducing technology too early is harmful to natural educational development in students.

This quote about Waldorf schools in the UK (where they're also referred to as "Steiner" schools, since Rudolf Steiner pioneered the movement) sums up the rationale:

  The hugely sensible approach taken by Rudolf Steiner schools is that computers only become useful in the teen years once children have mastered fundamental, time-honoured ways of discovering information and learning, such as practical experiments and books. 1

If you're afraid that this is backwards-thinking in the information age, it is perhaps telling that some of the biggest proponents of Waldorf schools are parents 2 and tech executives 3 who live and work in Silicon Valley.

Digital Literacy Curricula in Waldorf / Steiner Schools

Digital Literacy is a common term used to describe the use of technology in education, though this isn't a Waldorf construct. (It's championed by everyone from Harvard 4 to the Public Library Association 5).

However, in Waldorf Schools, digital literacy is typically applied in a more "holistic" way (another tenant of Waldorf education).

The approach taken by the San Francisco Waldorf School 6 is a good representation of these principles (though not all schools follow this same breakdown):

Early Education

  Young children learn through imitation, imagination, movement, play. Teachers tell beautiful stories with complex vocabulary and sentence structure. Children are unencumbered by the passive consumption of fixed media images, which scientific research confirms are difficult to process and can hinder learning.

Grade School

  Media-free classrooms are places of human connection and experiential, creative lessons. Middle schoolers are introduced to digital literacy, exploring questions of online behavior, information resources, and social citizenship. Families agree upon class community guidelines for the introduction of technology.

High School

  Students use technological tools for learning and creation, and teachers cultivate critical thinking through discussion-based seminars and inquiry-based exploration. There is a media center, rotating laptop carts, and cloud-based resources. Phones are turned off to create a space for learning and social connection.

So, if you want to follow true Waldorf pedagogy, technology should be introduced in the secondary/high-school years, and done so in a way that is "holistic", though some variations do exist.


Teaching students how to construct regular expressions (and other "translation" style problems) I'm currently helping teach a unit about languages as a part of a discrete math course -- we're currently focusing on regular expressions, NFAs, DFAs, CFGs, grammars, and the like.

One of the skills we'd like students to be able to acquire is the ability to translate English into equivalent regular expressions -- e.g. translate phrases like "match all strings containing an even number of the character 'a'" or "match all binary strings that do not contain the string '1001'".

Some students seem to easily pick up the "knack" of performing these sorts of translations, but many more of them seem to struggle.

Unfortunately, I'm not sure how to best help these students. Constructing regular expressions isn't usually something I find particularly difficult, so I've been finding it difficult to "get into the mindset" of the students who find writing regular expressions to be less obvious.

I've spent some time introspecting and trying to pick apart what strategies I subconsciously tend to use when faced with a new problem, but that's mostly yielded a list of ad-hoc strategies rather then anything fundamental.

Something I feel I should note is that I don't think unfamiliarity with syntax is likely to be the culprit. We're starting by studying specifically regular expressions (not regex) and have restricted ourselves to using a very minimal toolset: union, concatenation, the Kleene star, and epsilons -- so, no backreferences, no captures, nothing like that.

Rather, it seems what students find most difficult is the inherent act of interpreting and translating an English sentence and formalizing it into some logical form.

I've seen this same sort difficulty of manifest appear in other scenarios: for example, earlier this quarter, we asked students to translate English into propositional or predicate logic: I also found it difficult to teach students how to do this in any kind of systematic way. As another example, in other courses, I've observed many students find it challenging to translate English into SQL queries (and here I have some more sympathy, since I also find constructing certain kinds of SQL queries to be challenging).

The best I've been able to do so far is just have students do a bunch of practice/walk through a bunch of examples, but that doesn't strike me as being a particularly efficient strategy (though I don't dispute that practice is essential).

This brings me to the core of my question: How can I more effectively help students master the meta-skill of "translation"/"formalization"? I'd welcome both answers focusing on strategies for helping students more effectively construct regular expressions as well as answers focusing on helping students acquire this meta-skill in a more general sense. Answers that can give me more nuanced insight what sorts of things students find difficult about these types of problems would also be welcome.

Note: somebody asked a similar question to this one about helping students who are familiar with Java learn regex. However, that question seems to focus more on how to best teach the nuts and bolts of regex-the-language; my question is more about how to teach the meta-skill of "translation/formalization".

This is the stuff of math teachers' nightmares. The problems here, from my experience teaching about grammars1, are two-fold:

You said that syntax is probably not the culprit here. Students may be able to follow a grammar that has been presented to them, but may not be able to generate an appropriate grammar for a given series of test cases.
Students may not be able to generate appropriate test cases from the word problem itself.

The good news is that, by breaking it down into these two steps instead of one, you can actually help to isolate the problem that your students are having.

If you see your students frequently (as I do), here's a fix-up strategy that you can do in about 30 minutes of class time over three days.  Create a worksheet with a series of word problems, and ask the students, as homework, to generate test cases for these hypothetical machines.  They are not to create the grammars themselves, only create a series of test cases that should be accepted or not accepted.  Emphasize that redundancy is not a goal; you want a minimal set of test cases that could guarantee that some grammar is entirely correct.

The next day, spend about 15 minutes going over two of the problems, round-robin style, at the board.  Ask a student to write a test case for the first problem. Turn to the second student, and ask them to write another test on the board that could potentially uncover new ground.  On to the third student, fourth student, etc., until you are satisfied that you have a good testing set.  Ask if anyone else has any important tests remaining.

Do the same for the second problem, and then discuss the importance (in general) of creating good test sets upon encountering a word problem.  Point out that they will receive word problems on their assessment at the end of the unit, and you expect them to be able to figure out a good set of test cases with which to design a grammar at that time.

Their homework for that second day is to fix up their tests (if they need more work), and to create the appropriate grammars.  I suspect that when you get this homework back on day 3, you'll have much stronger results.

1 - I am using "grammar" as a stand in for "grammars, regexes, FSAs, or whatever type of expression/machine you are trying to get them to create at some particular moment."


JavaScript to teach Theoretical Computer Science We have been considering moving JavaScript into our core curriculum for vocational-readiness reasons.  However, our core CS curriculum focuses on concepts that won't become out of date.

There are certain languages that are pure, or close to pure, and lend themselves to teaching certain concepts.  Java (or Eiffel) for Object Oriented Programming makes sense.  Scheme, OCaml, SML, or especially Haskell is similar for functional programming.  Many other languages can, of course, be used for these concepts!  But sometimes the language itself brings advantages to bear when learning fundamental concepts.

We have wide discretion about what goes into our curriculum, but we are a little unsure about what core programming or theoretical CS concepts would be natural to teach using JavaScript.  We are considering functional programming, but that feels a bit Frankensteinian.  Would concurrency be a great fit?  Event-based programming? Is there something else that we are missing entirely?

Maybe a bit of an orthogonal answer, but let me try to refocus your thinking. I don't think that teaching a lot of languages, especially if they are similar to one another in some way is a big advantage for students. Giving them experience with different paradigms (ways of thinking) on the other hand is a big advantage. While I prefer Java (for its libraries), Ruby is actually a more pure OO language as, is, of course, Smalltalk and its successors. Scheme or Haskell can be used for FP, of course, and one has actual syntax.

Javascript, on the other hand is another OO language. It is different from the usual candidates, however, since it is prototype, rather than class, based. But that is a detail that an experienced OO programmer can become familiar with outside of any course.

But, many universities have a Language Principles course in the curriculum in which students study the fundamental ideas of languages without necessarily building a compiler for any of them. An older book covering this is by Ravi Sethi. You need to be careful that you focus on "principles of" and not "examples of" languages, however. But it is a good place to take a meta level view of languages and paradigms.

But if you want to have students learn a new language, especially one for which they also grok the basic paradigm, a project course is a good way to do it. Students build something significant in a new language. If you design the project you could also require aspects that they haven't seen much of before, such as concurrency.

But I would recommend against forcing the use of a language in a way that isn't natural to its design. While Java now has functional elements, I wouldn't use it to teach about FP as a paradigm. Frankenstein built a monster, of course. No need to repeat it.


What 'procedural' habits to break when teaching 'functional' programming? I have a class undergraduate students (2nd and 3rd year) who have had at least two terms of college/university level programming courses using a procedural programming language (typically C++), and often a term or two in other languages, also procedural. They have usually, though not a requirement, taken programming in high school, which was also based on one or another of the procedural languages. In the other computer classes they might have taken, or be taking concurrently, they have a procedural language as a secondary exposure. For example, the web design classes use JavaScript and PHP extensively. Bottom line is that these students are well versed (indoctrinated) in the imperative paradigm.

Now I have to teach them functional programming, and help them to adjust to a new way of thinking about the problems and solutions. In other words, I want them to be able to write a Scheme program, not a C++ program translated into Scheme.

So then, the question here is this: in the switch from procedural to functional programming, what are the critical "habits" to change in the students' minds so that they are able to grasp the functional paradigm enough to get them programming in the new language rather than writing old programs in the new style?

I undertook this study myself about a year ago. I started working through the Programming Languages MOOCs on Coursera (Part A Part B Part C), which are based on a UW course of the same name.

I didn't really know what I was getting into, but it sounded interesting. Before I knew it, I was learning a radically different approach to programming first with SML and now with Racket (Ruby is up next).

Here are some of the key ideas that were a major departure from my having programmed in C and Python:

Avoid mutation. Over and over again the professor emphasizes why mutation is a bad thing (or at least potentially problematic). From the world of C where I learned about declaring and updating variables almost immediately, this forced me to think differently about the information my programs contained and processed.
Don't call them variables. As a continuation of the above, they aren't variables (because after all they shouldn't vary because they don't mutate); rather, call them "value bindings." Moreover, these value bindings exist in an environment. This latter idea is essential (and has only recently sunk in) for understanding function closures.
Think recursively. Of the 3+ assignments I've completed for Part A and Part B, thinking recursively has been an essential component for creating elegant, efficient solutions. Indeed, in some cases it's been the only way to solve a problem thanks to the goal of avoiding mutation. This is not to say that recursion doesn't exist in other languages (because it obviously does), but it's been a more fundamental element to the design of solutions using functional programming languages.

Those are my big three; I'm sure there are more. Obviously understanding anonymous functions, higher-order functions, first-class functions, and all that comes with them (e.g. currying) is what functional programming entails. However, this content wasn't a "rewiring of old habits" in the same way that the above points were.

For what it's worth, I appreciate what C has taught me about what happens on a lower level, but I think studying a functional language qua an approach to programming has made me an overall better programmer.


Multi-client to server connection demonstration I am trying to think of a way to demonstrate how a multi-client server works, from the aspect of the broadcast messages sent from the server in response to a message from one of the clients.

I thought of making a small demonstration with cups and strings, having 4 to 5 cups on strings which are all connected to a main hub, rather than to each other. The hub is simply a closed box with holes where the other end of each line goes to, and a cup sized hole at the top.

When students speak into the cup, all the students hear what was said, because it was a broadcast from the main hub.

While this example sounds cool, I am not sure if it covers all1 sides of a multi-client server. What differences between a multi-client and the cup-string-hub example should I point out? (e.g. one of the differences I found is protocols, which the example doesn't exactly convey). I am talking about back-end differences, and not front-end ones.

1There are many things to cover, but I'm referring to the basics, as this is a first lesson in the subject of multi-client servers. They have tackled single client servers, so it's not an intro lesson.

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

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

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

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

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


A lab activity for the Y-Combinator We are about to study the y-combinator as a culmination of lambda calculus, and I would like a shortish lab activity that is related to this idea.  We are currently working in Scheme, though I don't consider that to be important at this stage.  What I want (and what I lack) is something interesting that students can do with the concept of a lambda expression that takes itself and then acts recursively.

One site that I find helpful for basic examples of coding task written in a multitude of programming languages is RosettaCode. While it is not always a win when going there, I still keep it high on the list of sites to check when looking for teaching examples or code that demonstrates something.

In this case the combination of the programming language Scheme, an example simple enough to use in a classroom and the Lambda Calculus Y-combinator are satisfied by this example:

  Define the stateless Y combinator and use it to compute factorials and
  Fibonacci numbers from other stateless functions or lambda
  expressions.

(define Y
  (lambda (h)
    ((lambda (x) (x x))
     (lambda (g)
       (h (lambda args (apply (g g) args)))))))

;; head-recursive factorial
(define fac
  (Y
    (lambda (f)
      (lambda (x)
        (if (< x 2)
            1
            (* x (f (- x 1))))))))

;; tail-recursive factorial
(define (fac2 n)
  (letrec ((tail-fac
             (Y (lambda (f)
                  (lambda (n acc)
                    (if (zero? n)
                        acc
                        (f (- n 1) (* n acc))))))))
    (tail-fac n 1)))

(define fib
  (Y
    (lambda (f)
      (lambda (x)
        (if (< x 2)
            x
            (+ (f (- x 1)) (f (- x 2))))))))

(display (fac 6))
(newline)

(display (fib 6))
(newline)

output

720
8

Bonus answer:

When others want to learn more about Lambda Calculus the first reference I always give is "An Introduction to Functional Programming Through lambda Calculus"

Note: While the link is nice if you really do use the book often then please purchase the book.


How can I prepare for DASCA Data Science certification if I am in UG? I am currently in third year of my Computer Science UG degree. I wanted to know what are the best certifications for a data scientist.
Found that Data Science Council of America (DASCA) is the most comprehensive one requiring 5+ years of experience in research and analytics. Also there is the SAS program and dozen more.
I wanted to know:

Which are the best certifications?
How can I prepare for DASCA?
Which other certifications should I do meanwhile preparing for DASCA?

I'm going to rephrase your question a bit:
"Is it worth preparing for the DASCA Data Science certification, and if not, what should I do instead?"
I teach data science and counsel with a lot of students looking for jobs, as well as employers looking for people to hire. I've also worked as a data science consultant for a few years.
I have never heard of this certification. I've talked to a few other data scientists that I know, and they also haven't heard of this certification.
In the world of data science, there are largely two credentials that count:

A degree in something from a major university. These days, that something can be:

data science
computer science
software engineering
statistics
in some cases, a degree specific to the problem domain you're interested in. (Economics or foreign policy are common examples)

Actual data science experience. This can be real-world experience, such as an undergraduate research project, a senior project / capstone class that you design yourself, personal projects that you document, Kaggle competition results, etc...

The employers I've talked to in my capacity as a teacher and as a consultant typically don't give much stock to certificates on their own.
They've found that people who focus on certificates either have too little real project experience (e.g. they know how to solve a couple of specific, clearly defined problems), lack the ability to do data pre-processing (which is the what data scientists spend the vast majority of their time doing), or lack experience working with a team.
There are of course exceptions to this, but by and large, you'll have a much better time if you focus on getting real project experience.
What to do instead
Unless there's a very compelling reason for you to get this particular certification, (you love collecting certificates for fun, someone is paying you for it, or there's a particular job you want that lists this certificate as an explicit requirement), here's what I would recommend you do instead:

Finish your UG degree, making sure that you take steps necessary to have as many meaningful data science projects as you can, preferably ones where you work with a team of people. Use the resources of your UG program to help you network with people in the industries you're interested in, find a good internship, visit career fairs, etc...

Look for personal projects you can do that will show you have explored different aspects of data science, especially data preprocessing. This can be things you just decide to do on your own, UCI datasets you explore for fun, Kaggle competitions or explorations, etc... Treat these like real research / business problems.

Make sure you document these results somewhere public, such as GitHub or Kaggle via Jupyter notebooks, or in some other way that makes it easy for you to share them with potential employers. This should go beyond just "here's my regression result", but a discussion of the choices you made, how they impacted the results, and caveats about your conclusions. This Jupyter notebook on Kaggle is a great example of what I'm talking about.