Is there a better way to validate student learning? I'm a student in an undergraduate Computer Science program with several years of experience before coming to university. As I began working through the coursework here, a large problem stuck out to me.

At my university, students are thoroughly prohibited from collaborating in any way on assignments, except for certain ones with permission. This includes even to the point of hosting review sessions where students talk through the intricacies of the best way to complete a project, without sharing any code. This is understandable. Instructors I've spoken to explain that it's important to verify student learning by forcing students to work individually. Unfortunately, this goes against everything I've been taught about how to learn.

I was fortunate enough to be mentored in programming by more experienced software engineers before I came to university, so I attribute all of my learning to being able to work in teams and ask questions of my peers/collegues. Here, that learning style isn't just discouraged, but actively punished. The instructors have a valid point however: it's important to ensure students are capable of working on their own when called to do so.

As Computer Science Educators, what techniques have you used to ensure students understand the material while continuing to allow extensive collaboration during practical programming assignments?

I may not be an educator myself (yet) but I have a passion for improving how people learn. I hope this question fits here.

You seem to already realize that this is a subtle question. When I taught Mathematics early in my career, I also forbade students to work together. Later on, teaching Computer Science, I found myself at the opposite pole. I normally forced students to work together on nearly every task. In some ways I changed, but it was more that the subjects are different. So, I learned to (try at least to) match the student activities to the kind of thing they needed to learn and understand.

In some courses personal insight is essential and hard-gained. Much of math is like that. The student needs to grok the ideas deeply so that they can be integrated into a whole so that the frontier of knowledge can be pushed forward. If students work together in such courses, it is inevitable that one of them will have the key insight first. A-Ha. From that point the collaborators are really just watching someone else work and will be denied the experience of overcoming the block themselves. Since those blocks are frequent in math, overcoming them is an important skill in its own right. Some CS topics also have this same nature, but most do not.

As you note, most work in industry is done in teams and team members share insights with one another. In fact, Pair Programming is specifically designed to force insight sharing. But as you also note, you sometimes need to work alone and so you need the skill to do that. But Pair Programming also fosters this skill as the Driver and Navigator roles swap frequently. One way to bring a newbie up to speed is to have him/her pair with a veteran. The experienced programmer could probably build everything alone but surprisingly often benefits from the fresh insight of the new hire. Since team-work is a learned skill, I think the university should help the students learn it.

In graduate education, things may be a bit different, but again, it depends on the course. More work is likely to be individual at this level as it is more likely to be insight-rich. Certainly by the dissertation level the student needs a lot of experience working through their own tasks. But even here, discussions between dissertation-level students working on different problems can be valuable in seeing how some things can be approached.

I worry mostly that forbidding collaboration in the classroom raises the stress/tension level in students. I hope there aren't many who see this as a good thing. Students have enough stress anyway and I think we faculty should work to reduce, not increase, it.

The faculty that forbids collaboration of any kind is probably a bit naive about what really happens outside their line of sight. Students no longer live in monastic cells. They meet. They talk. It seems better, in my view, to recognize this and to guide it.

One top US college at which I taught has an honor code in which students can collaborate on projects without limit as long as they share no code. Students can ask others for clarifications and advice. Students formally sign this code as a condition of acceptance to the program and it is kept on file. There are a few violations, of course, and the college treats them as a really big deal, with expulsion as a possible punishment. It isn't automatic, however, and review committees are permitted to show mercy as appropriate.

I've taught important courses in which the first task is to break up the students in to teams of 4-5. All of their work, with one exception, was done in collaboration and we (there were two professors) provided collaboration tools so that the students could easily meet in virtual space as needed. The one exception was an individual project that was done (take-home) over the period of one week. This project might have been related to the overall team project, or not, but it had a similar "flavor" in any case. The teams were encouraged to bring their less experienced members up to speed prior to this task and the teams took pride in the success of their members. Many of the "newbies" struggled with this, but a few had really dramatic improvements.

In other courses in which most work was collaborative and most of the grading depended on group project work, there were one or two fairly low pressure exams that counted for a small part of the grade. In total it was about enough to raise/lower the marks by one level, A <-> B, say. But one full level change would be extraordinary unless the student simply skipped the exam. Collaborative exam prep was neither encouraged nor discouraged. I assume that the best students were more likely to collaborate in prep than others, but have no data.

One advantage of collaborative project work in the classroom is that students can work on larger projects than would otherwise be feasible. Time becomes less of a constraint. Seeing large projects with many parts is a good thing, even if you primarily work on only one part of it.

One of the issues that some faculty have with collaboration is that it can be difficult to determine who the chief contributors are so as to provide appropriate rewards (and sanctions, of course). This needs to be planned for. There is a concept (and Pedagogical Patterns) about Peer Evaluation that are worth exploring. It is quite easy to do and can be structured so that it is a positive experience for students. Students can be encouraged to reward their best and most helpful team mates. I once also learned that a particular student who appeared to be disengaged in the class was actually the chief contributor to a team and that I'd likely misjudged him.

Please don't weaponize these comments against your faculty. It won't do you much good to be seen as a contrarian.


Do you use any teaching assistant tool in your CS1 lab classes? In the scope of my PhD work, I am developing a teaching assistant tool. These tools are used in the context of lab classes to gather "snapshots" from the student's code using one plug-in in the IDE of their choice (in my case, Eclipse and all JetBrains IDEs). The code snapshots are analyzed/processed, and several metrics may be used to determine the performance of the student as well as if s/he is doing plagiarism, and many other things.

Is anyone using a similar tool (e.g. Retina, TestMyCode, ...)? If the answer is YES, how is it working for you? If the answer is NO, why not?

It seems that they are quite familiar in Academia, but not so much in the “real world”.

When I was a TA, we used tools to automatically:

Collect submissions and run them against set of predefined test cases
Give instant feedback to students on how they did based on the test cases they passed/failed
Give feedback on the quality of their code
Generate plagiarism reports

For plagiarism, we used MOSS. For everything else, we developed a tool called AutoGradr.


Principles of Compiler Design v/s Compilers: Principles, Techniques and Tools by Aho, Ullman Now for a student who is trying to master the subject of "Compiler Design" which book should he/she follow (written by Aho, Ullman)?

1) Principles of Compiler Design By Aho Ullman (1977)

I find that the used copies of these text is still available online. Is it so that this particular edition inspite of being old is in great demand.

2) Compilers: Principles, Techniques and Tools (2nd edition) by Aho, Ullman, Sethi (2006)

I would like to know which one would be more suitable for a novice student having knowledge of only automata theory. Which book has a more lucid language? Which one is more preferable for a student performing self-study. I wanted to ask this question because in this answer it is said that older editions of few texts are sometimes better. So it is always better to have a good guidance before diving into a subject learning.

EDIT:
Here the question asks whether "the two volume books are more advanced or complete than the dragon book.Is the dragon book supposed to replace the two-volume books? Are the two-volume books outdated or still very relevant?" The book which is being referred to as "two volume book" is different from the book marked as (1) in my question.
Now I am asking specifically which one among the two books which are referred by me are more easy to read? Which has a more lucid language.In this answer here they say that the automata book by Ullman in the newer editions have changed the elegance of the actual text. Many important portions have been removed and at portions it lacks clarity. Now my question is which among the two books are better or are they equivalent? I had difficulty in following the second edition of the automata book so I felt like asking it here, such that before I begin, I am guided properly.
To learn the basics an old book does not matter, because foundations should remain the same, but I want to read those foundations in an elegant manner, without being puzzled by unclear or in-depth explanation of the same.(which at times happen if a new co-author is introduced)

Although it is not quite what you are asking, I deprecated these two books when teaching compiler design as many otherwise capable students are finding them tough going. I started to focus on more practical based books. Its a matter of top-down versus bottom-up approaches to the material (not the parsing).
I now prefer Grune:
"Modern Compiler Design", Grune, van Reeuwijk, Bal, Jacobs, Langendoen, Published by Springer 2012. ISBN 978-1461446989
But choosing books to recommend to students is a very personal thing and others may have other choices.

I learned from the 1971 classic "Compiler Construction for Digital Computers" by Gries, but not something you can use on a modern course!


Workflow for Code Submission Next year will be my first year teaching AP CS A. While I've spent a lot of time preparing by choosing textbooks, picking an IDE, and writing the syllabus, I'm not yet settled on my workflow for how to push out assignment instructions/starter code and how to collect work back.

I registered for GitHub Classroom with an education account, but I haven't yet had a chance to explore its resources and would like to hear from those who have used it. I can easily collect files via our LMS or Google Classroom. I just have doubts that that method is the most efficient for either me or my students. Also, this past year, CS50 took care of the distribution code, so I didn't have to worry about that. Now I do need to consider how I can get files to students efficiently if needed.

What workflow do you follow for the submission of student work, particularly in the context of Java files? Do you provide students with starter code? If so, how?

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

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

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

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

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


Why isn't Functional Programming Taught First? We've recently gone through the process of selecting an intern from a local university to join our team for the summer.  We are using F# and almost exclusively using functional programming techniques on our team, and finding a candidate with any exposure to functional programming proved to be impossible.  This isn't that surprising, given that even several senior members of the team with Master's degrees didn't have much exposure to functional programming before joining our team.  However, I've been wondering why so few undergraduate programs teach functional programming concepts.

Having attended a university that taught C/C++/Java for 90% of my undergraduate classes, I found it strange when first learning Haskell that the language was never used in any of my classes, especially considering how much easier and more obvious it makes the implementation of fundamental data structures like trees and lists.  When building enterprise-scale systems, avoiding things like state mutation becomes critical.  So why aren't functional languages taught first, and functional programming techniques taught as a "use this approach first, when possible" with imperative techniques and things like explicit memory management and use of mutable state taught as "only use this when absolutely necessary for performance reasons"?

I would think, with the increasing move towards multi-core processors, and the growing relevance of distributed systems, that teaching functional programming from the beginning would be the best way to prepare students for successful careers in the industry.  Is there a reason that universities avoid teaching Haskell or other functional languages first (or at least including them as a major part of the undergraduate curriculum) and teaching imperative programming as a supplementary skillset?

The why isn't necessarily related to the relative quality or benefit of the various approaches to the first courses. But some of the comments given to the question capture part of the reasons.

First, FP isn't precisely mainstream in industry. Most programming in the real world is now is done in Dijkstra-derived languages, not McCarthy-derived ones. This may change, of course, as the world starts to recognize the benefits of FP as it previously did for OOP. As the questioner mentioned FP has advantages in some important areas. But most curricula take a look at who is hiring entry level folks and what they want to see in the person's background.

Another reason is that most of the faculty is much more knowledgeable about those mainstream things than others. If the faculty went through a long program in which almost everything is built in Dijkstra-derived languages that is what they are more likely to teach beginners. OTOH, faculty (including some folks here) who went to, just to pick a name, MIT, are more likely to start in FP, but may still be constrained by the first reason.

Most faculty still think of FP as an advanced topic and so Let and Lambda tend to come late in the curriculum, after the students have seasoning. As you suggest this is not necessary, and may not be desirable, but there is a lot of inertia.

There is always some mental disruption when a student is asked to change paradigms, since a paradigm is built on a consistent mental model that is also relatively closed, not needing outside explanations. Paradigm shift is, in general, difficult, even for experts. The HS or undergraduate curriculum is short in time so most faculty are resistant, at least a bit, to require uproar in the middle of the two or four years. Much better, it is normally thought, to treat one paradigm as the main-line and any others as nice but inessential to the main goal.

If you have a lot of chickens, you get a lot of eggs. OTOH, if you have a lot of eggs, you get a lot of chickens. Pigs, not so much.

However, if you are going to teach any given paradigm, you need to do it well. You need to make students completely comfortable in that paradigm so that when presented with a new problem they aren't confused about how to begin or what should be the next step. Languages/paradigms should fit like a comfortable pair of shoes. I'm not certain that current OOP education is as good as it could be, actually, but that is due to my own background. If we suddenly adopted FP widely, you might well think the same thing about the then state of the art concerning FP. Change happens, but it is slow and is resisted.

Students need two things at least. They need to be able to solve problems so that they can be successful in academia and/or the world of employment. But they also need to be able to think and be flexible so that they are able to move with the times as necessary. So we tend to teach one paradigm completely (for the first goal), but allow them exposure to others (for the second). Mostly it works.

I'll also note that learning new languages is actually harder than it is often represented to be. If two languages are within one paradigm and have similar concepts then it may seem to be merely a question of new syntax applied to old ideas. Java and Python have similar ideas but quite different syntax. But learning the syntax of Python as an experienced Java programmer won't make you pythonic. But changing paradigms is much, much harder, even when the syntax is nearly the same. I'll note that C++ was derived from Dijkstra's ideas primarily (via Simula), whereas Java's core concepts come from Alan Kay. If you don't understand that then you can wind up programming badly in both languages.


How to teach Stack Overflow more efficiently? As evidenced by the numerous poorly asked questions by students on Stack Overflow, it is clear that many students have difficulty understanding how to ask questions there.

Even as teachers, we often seem to have difficulty asking questions on Stack Overflow and other Stack Exchange sites.

There have been flawed attempts with teachers assigning "ask a question and up vote another student's answer" which conflict the "vote on good material, not the user" (along with often asking really awful questions that get down voted and deleted).  Those questions tend to invoke the ire of the Stack Overflow employees and diamond mods and leave everyone involved with a sour taste in their mouth.

As students get out into the industry, they may find that having a good understanding of how to search and ask questions on Stack Overflow to be a valuable tool.  So, how do we teach how to use Stack Overflow?

Neglecting teaching how to use Stack Overflow in today's world is as bad as not teaching a student how to use a debugger and relying on the industry to teach the basics of software engineering and the tools available and expected to be used with a modicum of proficiency.

The lack of ability to teach Stack Overflow is also symptomatic of an inability to ask questions generally. Really, we need to teach students to ask the right questions, on Stack Overflow and elsewhere. How can I teach students to ask good questions, on and off Stack Overflow?

I don't think the core issue is that some students are bad at using Stack Overflow -- I view that more as a symptom of a deeper root problem. When somebody doesn't seem to be able to productively ask questions on Stack Overflow, I think that one or more of the following core issues are at play:

They don't really understand what it means to self-learn and independently research. After all, suddenly switching to independent work can be jarring after being hand-held through learning for the past N years.
They're not efficient communicators. Perhaps they care only about coding but not writing so ignored some of their teachers? Perhaps they were taught only to write essays or short answers where the main goal is to meet some word limit?
They're not familiar with online etiquette and norms.  In particular, when you ask for help in person, it's often ok to ask small questions or ask for general help when stuck. However, that kind of thing is often considered disrespectful, not just on Stack Overflow but many other technical forums -- you're expected to "front-load" your question so you don't waste people's time.
They're unwilling or too impatient to read. After all, Stack Overflow's help center defines exactly what's ok or not. (A perhaps more charitable interpretation is that not all students have fully tuned their ability to tell what must be carefully read vs what can be ignored.)
They're ineffective debuggers and so can't figure out a way to distill their issue into a specific question, even if they wanted to.
They don't know how to gracefully accept criticism and feedback when they inevitably do make a misstep.

So, given all this, I think trying to directly teach students to use Stack Overflow is probably a waste of time. There are deeper issues you need to tackle first. I would instead recommend doing some mixture of the below:

Incorporate more independent work into your curriculum (partly to make them less reliant on getting help from teachers and partly so they're more likely to run into questions worth asking).
Explicitly make good technical writing one of the goals of your class. Assign lab reports or writeups and grade students based on how effectively they've balanced completeness, concision, and clarity. (Perhaps this can be coordinated across different departments? Science classes often require lab reports, English/writing classes are a thing...). You could also tie this in with academia: make them write research papers.
Have your own discussion board where you answer questions. This way, students get some practice writing questions in a friendlier and more tolerant environment -- if somebody asks a poor question, you can prompt them for details to make the question a better one. As time progresses, get more strict: flat-out refuse to answer duplicate questions and the like.
Teach students a variety of debugging strategies. Show them how to use a debugger (and walk through several examples). Explain how to do printf debugging in a principled way. Teach them binary debugging. When they ask for help, teach them problem-solving strategies instead of directly helping them with their problem (where applicable). Teach them how to pin down and verify preconditions/postconditions/invariants. Teach them how to write (good) tests.
Make your students used to receiving feedback. Don't just grade their code based on correctness or whatever: grade on style, conduct code reviews... That said, your students are probably already used to being critiqued after spending N years in school, so perhaps there's nothing extra that needs to be done here...

(Unfortunately, I don't really know how you can rewire people so they'll actually read things. As I understand it, that's an unsolved problem in the general case.)

I realize these answers are sort of a cop-out -- you were asking how to teach people to effectively use Stack Overflow, and my answer was basically "don't use Stack Overflow". But in the long term, I do think it'll be for the best. The hope is that once they've graduated, they'll have learned the meta-skills needed to effectively and professionally communicate not just on Stack Overflow, but in other technical forums or at their workplace.


What are good sample programs for learning to use a debugger? One skill I teach students in Java 1 is how to use a debugger, specifically:

single-stepping through code
using breakpoints
viewing the values of variables
going up and down the call stack

I have been unable to come up with good programs for them to use when learning to use the debugger. Specifically, I would like to provide them with a program with a bug that they're unlikely to find just by looking at the code but can find with a debugger.

A few Java specific examples come to mind:

Using % with a negative number - I recently came across this and had to remember how Java treats modulus v. remainder (cf. this thread)
Listing switch statements without the proper break; at the end of each case - maybe something that can be seen right away, but stepping through each line would be good to visualize this process
Integer division is also a classic - using the conventional Celcius-to-Fahrenheit (or vice versa) conversion program with the formula broken down over several lines would force them to see line by line what is happening when you evaluate 9/5 or 5/9
Operations with increment/decrement operators in prefix and/or postfix position throughout a program - I like this one a lot because of how variables may change without that change always being seen

I'll edit and add ideas as more occur to me.


Scope and Sequence for Raspberry Pi Course I am in the process of developing a new course focused entirely on Raspberry Pi. The goal is to make it a summer-school elective equivalent to one semester (i.e. one class meeting over the summer == one week of class during the school year). The course is in its beginning stages, but my goal is to essentially make a "textbook" out of Raspberry Pi. The course is to make it project-based and hands-on and to work my way from the ground up assuming no prior knowledge of programming.

Here is my current course outline:

Unit 0: Computational Thinking with Scratch
Unit 1: Programming as Art with Processing and Sonic Pi
Unit 2: Programming in Python
Unit 3: Hacking Minecraft with Python
Unit 4: Learning the Command Line
Unit 5: Intro to OOP with Greenfoot and BlueJ

I am confident in starting with Scratch, Processing, and Sonic Pi and concluding with OOP. However, I am unsure of the order of Units 2-4.

Does it make more sense to introduce the Linux command line (and the shell/scripting in general) before Python or after Python?

I would teach the command line first. Both units 2 and 3 require use of python, which I wouldn't teach before the command line because it is normally run from the command line. I'd also teach the command line earlier because I find that it makes students more comfortable knowing it. It could also be useful because you could teach some command line utilities to connect to the pi and that we prepare the students to learn about networking further.

Generally, teaching shell scripting opens many doors into computer science that I'm sure a few of your students will happily explore. Once you know the command line you can learn how to write command line utilities, explore networking,  process management, and so much more. I think it'd be more effective to get this vital information to students earlier rather than later.


Concern over plagiarism in designing online course Background
I am currently working with a university to design an online Machine Learning and Cloud Computing course. We are closely following Hands-On Machine Learning by Geron. The author of this book has created many useful Jupyter Notebooks with examples that follow the text.
I have been creating new Jupyter notebooks by supplementing his example Jupyter notebooks with paragraphs and bullet points excerpted directly from the text. The plan is to make instructional videos that work through the notebooks.
Question
Could any of this be construed as plagiarism? Obviously, I'm not suggesting to the students that I am the author of the notebooks. I am completely transparent that the notebooks are based off Geron's textbook and supplementary materials.
Is this ok? What's the best way to be transparent if it is okay to proceed down this path?

So, as a matter of fine distinction, what you are doing cannot be plagiarism if it is credited.  It could still be theft, and it could still be unethical, but plagiarism is passing someone else's work off as your own.
If you are having the students purchase the textbook, I would reach out directly to the author and explain what you are doing.  Since he will be compensated by the textbook purchases, he may well agree to allow it, which would eliminate the ethical issue.
Even if you are not having students purchase the book, some authors are simply generous enough in spirit that they would nevertheless agree to such an arrangement.
The ethical alternative is to come up with your own exercises and explanatory texts.  These can closely follow the spirit and outline of the author's text if you think he has a great approach, and you can point students towards his book as an excellent and highly recommended source.  (You would still have to credit the author to the degree that his contributions and organization of the material is a resource for you, but if you do not use his text or exercises, then that would be all you would have to do.


What are competitive programming problems that require a tree data structure to solve them? I want to practice my problem-solving skills that involve the usage of a tree data structure (e.g. Binary Search Tree, Heap, Fenwick Tree, etc.)

The problem should make me search for the right tree data structure and apply it in solving the problem, but not manipulate the tree itself. Hence, problems like the lowest common ancestor, inorder traversal, etc. do not count.

One nice problem that I know is as follows:

N pixels in a row are originally coloured as white:
WWWWWWWWWWWWWWW // N=15 in this case

We now keep recolouring all pixels between position i and position j
with a different colour c for T times:

T = 1: WWWBBBBBWWWWWWW // i = 4, j = 8, c = B
T = 2: WWWBBGGGGWWWWWW // i = 6, j = 9, c = G
T = 3: YYYBBGGGGWWWWWW // i = 1, j = 3, c = Y
T = 4: YBBBBBGGGWWWWWW // i = 2, j = 5, c = B
...

At the end, you are asked to print the colour of each pixel.

Since N and T can be large, one requires a tree data structure to efficiently update the colour pattern of the pixels.

Can anyone suggest good programming problems of this nature?

How about Huffman encodings?

  Given a text that uses an alphabet of $n$ unique characters, how can we uniquely encode the alphabet so that the text uses the smallest amount of bits?

More formally for Huffman encodings (as formulated by Tardos & Kleinberg in their book Algorithm Design):

  Given an alphabet and a set of frequencies for letters, we would like to produce a prefix code that is as efficient as possible - namely, a prefix code that minimises the average number of bits per letters $ABL(\gamma) = \sum\limits_{x\in S} f_x|\gamma(x)|$. We will call such a prefix code optimal.

This has an $O(n \log n)$ solution.


When a student submits a work that is a copy from a colleague, should you also punish the student that made the work? The question kind of says it all. Imagine that for an assignment you receive two or more similar submissions (e.g. programs). What will you do? Annul all the works? What if you know for certain who was the original author?

Probably this is already in your schools’ code of conduct. In my school it is not and I sometimes don’t really now what to do.

This would depend on context, in my opinion. Given you know the identity of both the original author and the plagiarist, consider:

Did the original author facilitate the plagiarism, or was the code plagiarised without the original author's knowledge? Can you tell?

Clearly, if the original author was the victim of someone peeking over their shoulder, or just blatantly copying code files, then they should not be punished. But if they gave help to others despite being told that this is inappropriate, then they are equally guilty of misconduct.

It's easy for me to write this, but in practice determining whether the plagiarism was with or without consent is more difficult. I would be inclined to give the benefit of the doubt if there is any chance that one party did not intentionaly cheat.
Is there any record of the students cheating previously? If so, that might be a guide.

I would be keen to avoid punishing someone who might not have done anything wrong, but some others might not give the benefit of the doubt. It's certainly not easy to tell what exactly has gone on when two very similar works are handed in, but if you can rule out any copying without the author's awareness with certainty, then you must assume that the author facilitated cheating.

If you haven't made clear what the difference is between helping and cheating, then you can't really punish anyone fairly—if you don't clearly lay out your expectations, then you can't enforce strict rules.


Enjoyable and\or fun way to explain cmake As a pilot project (which was delayed by an incredible amount, seeing as it's starting 8 weeks after it was meant to), my school grouped together a few kids (high school, they know basic OOP and work in Java) and we teach them a bit about C and working in C.

We use CLion, which in turn uses CMake to organize header files. Naturally, the more inquisitive students asked what cmake does. (Like a plant, because it is in the curriculum anyway).

So, I was trying to think of ways to explain what cmake does, in an analogy. Because CMake can get exponentially more complicated as one adds modules, I am focusing on analogies that simplify this, and hopefully present in an enjoyable way (such as a demonstration or student participation).

The idea is to explain how CMake can be useful for arranging header files.

So my question is what analogies can I use, which preferably include student participation?

cmake, allows you to define variables, these variables can be filled with strings.
These strings can be tools or files.
Additonally it allows for conditional compiling, setting version numbers and library injection.
I would have a look at: https://cmake.org/cmake-tutorial/

Now on how to explain:
Cmake utilizes a script language to make building projects much easier. It has a feature set that does specific things. Like requiring specific versions of files.
How to make it "fun" I dont know. But you could split your class in groups that each  have to create a header cmake replacement script, with a specific variable name. And a program that does anything they like, but has to use the defines. For example DEBUG
Then each group has to create a list of substitutions, and they share the substitutions. While executing the diffrent substitutions, they have to determine why something breaks or works although it shouldnt. This can be used to examplify, how the header operations work, and also how wrong or malicous usage can wreak havoc in their project.


Looking for good Master Theorem examples I'm teaching an Algorithms class (junior/senior level), and we've just proved the validity of the Master Theorem. I'd like some good questions on it, both for homeworks and for exam questions. Problem is, most questions I've seen online seem to just give the constants (e.g. a=2, b=2, c=1, now solve for the Θ class), which isn't very intellectually challenging.
So what are some real-world recursive algorithms whose running times can be analyzed with the Master Theorem? I have a very limited list already:

Merge sort (possibly quick sort too, but that's a little problematic)
Binary search
Traversing a balanced binary tree
Ternary search (finding the max of a unimodal function)

Anything else?

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


Easy on-boarding for grad students to lead outreach? I've been volunteering at a local Girls Who Code club at a U.S. high school. Other volunteers are female grad students in computing. I've been struck by the fact that even though the volunteers are women in computing, that doesn't mean that we won't scare the high school girls away from computing with bad teaching practices.

The other volunteers tend to:

Lecture a lot
Type code or plug in wires for the student instead of letting them do it
Talk about expensive electronics as if everyone owns them
Assume a very fast pace of instruction

Do you know of any resources I can pass on to these volunteers to help them become better teachers and volunteers?

I'm thinking of making my own, but I'd love to save some work :)

The situation you seem to have is that you have students (your volunteers) suddenly thrust into the role of teachers without any preparation other than what they can emulate from their own teachers. Teaching is a skill that can be learned but only through reflection and practice and that takes a lot of time. And you don't have that time now. I would guess that most of your volunteers are (a) used to be lectured to, and (b) have a learning style consistent with that.

However, as I've said in response to other questions here, the students aren't at all like their teachers. Every student is different and your learning style is not the same as that of your students. Good teachers learn this, mostly through experience, and learn to accommodate students with a variety of learning styles.

My advice, then, would be to try to have the volunteers give up a "teaching role" so that they don't get trapped in the emulation game. Instead, have them work with small groups of students in a responsive way, answering questions only rather than giving out information. Have the volunteers act more like mentors than teachers. In other words, divide the students into groups with one or two volunteers for each group. Each volunteer is just a resource for the group, not its leader.

One thing they can do, of course, is give something of their own backgrounds and what led them to tech. They can talk about what they find hard in learning and how they work to overcome that. They can talk honestly about the obstacles they faced (and that women in general face) and how those can be at least partially overcome. Counterbalancing the obstacles, the volunteers can also talk about what they love most about geekiness and what cool things they have built or helped build.

Mentoring relationships can be fostered and it would be good if you can find some way for those to continue after your volunteer gigs end.

But if they think of themselves as teachers they will just emulate the teaching they have been exposed to and that may not lead to the best outcomes.

If your volunteers know something about Agile Software Development process, especially Extreme Programming, you can do something like the following. Have each volunteer act as a combination Customer and Coach to a team of students. These are two quite different roles (two "hats"). As a customer, the volunteer breaks down a project into stories and feeds them to the team over a set of iterations. The Customer also handles acceptance of the work between iterations. As a Coach, the volunteer keeps the students on track, observes the periodic (daily) meetings and makes sure tests are written. If every team works on the same project, then you might be able to have one (or maybe two) volunteers act as Customer for all the teams, and the others serve just as coach (and mentor, of course), one for each team. The volunteers, by the way, will learn something if they also compare notes periodically and have their own debriefing sessions.


How do you teach Big O to high schoolers with varying degrees of math exposure? My second semester programming curriculum includes a searching and sorting unit and mentions Big O notation, giving the notation for each search and sort we implement.  It does not show the derivations but does show how you can deduce some Big Os by looking at the structure of the code.

The course that I am teaching is called Programming II.  Programming II is the basic concepts of programming I (variables, decisions, loops, arrays, functions) again in a different language (C# as opposed to VB.NET), plus object-oriented principles, multi-D arrays, file I/O, searching and sorting, collections, interfaces, and some other minor language features of C#.

My district allows very limited prerequisite specification, meaning the only prerequisite for Programming II is Programming I.  (Programming I has no prerequisites.)  This means I have a widely varying level of mathematics exposure/competency for the students who come into the second semester course.  I struggle with how much or how little to say or share about Big O notation.  I want my students to have exposure because I know they will see it later in their CS careers, but I don't want to scare them away with "math".  And I have to account for their differing math skills.

Have you taught Big O to high schoolers?  What methods did you use?  How do you deal with their differing levels of math?  Is it a good idea to teach them derivations?  On tests, do you require them to do derivations or have them parrot back Big Os for various algorithms?

One good overall educational strategy is to teach the same thing to students repeatedly, using a Spiral approach, in which each turn of the spiral teaches at a deeper level. Don't expect the students to completely get much of anything at the first mention of it, but reinforce the ideas and deepen the knowledge. You can do this for many things in one course, but you can also do it over a student's career.

As you say, it is a mathematical concept and students may not yet have the tools needed to completely get it, but you can start, and you can give them enough insight so that when Big O comes up later, say in their undergraduate education, they have some prior basis for understanding it more deeply.

However, it is important that you don't oversimplify the topic or to give them false information, leading them to misconceptions that require un-learning later. So, first, be honest: the topic is mathematical, it is a bit deep, we can only scratch the surface a bit.

For young students without a solid algebra background and little exposure to calculus, it might be good to start with a graphing calculator so that students can see what happens to common functions as the independent variable increases. Graphing $log(x)$, $x$, $x^2$, $2^x$ etc is a start. Graphing $1000x + x^2$ can give them the idea that the high order term dominates the growth. If they can see it, you don't need to depend on their knowledge from elsewhere.

Next, you can show them a few algorithms and look at the actual run times, noting that you are only giving them an idea. One of my favorite "tricks" is to ask students who have seen a few sort algorithms, to come up with the most inefficient sort algorithm they can think of. With a good randomizer even repeatedly randomizing an array and then checking to see if it is sorted is an algorithm by the law of large numbers. If they know about permutations they can even calculate the maximum number of iterations needed to sort. If they are not likely to know that from other places, then computing permutations can be an earlier programming exercise.

The problem with teaching the first cycle of a deep knowledge of Big O is that it is easy to give the wrong impression about a lot of things depending on the words and examples you use. If you say that, for example, bubble sort is $O(n^2)$ you are correct, but it may have little meaning. It doesn't mean, however that the "running time" of bubble sort is $n^2$, but (if $n^2$ is the best bound) that it is "proportional to $n^2$ for large values of n." It is easy to forget to say those extra words: "proportional", "large...". It is also easy to forget that Big O is about upper bounds, only. So technically, Bubble Sort is also $O(2^n)$, but it would probably not be wise to stress that in the first cycle of learning outside a mathematics class.

Also, the examples matter. Bubble sort (if unoptimized) always runs in quadratic time and you can see that from the algorithm. It depends only on the size of the data set. But insertion sort is different. The normal program has two nested loops, just like bubble sort, but if the original dataset is already nearly sorted (by some measure of "nearly") then it actually runs in near linear time - or even linear time, for some examples. But it is still a quadratic algorithm, since its worst case behavior is quadratic. So, "worst case" is another important word to keep emphasizing.

You also need to mention, but probably not stress, is that efficiency need not be determined by the size of the data set necessarily. Factoring large numbers is an example. There is only one number to factor, but it is harder to do for larger numbers since (for brute force, anyway), the difficulty is determined by the number of possible solutions, which is itself large (but can be estimated).

A third complication is that it isn't always time complexity that is needed. Space complexity is also often important. How much "scratch" space does an algorithm need for datasets of different sizes (or datasets of different complexity, or ...). A recent (early 2018) experiment(pdf) in Artificial Intelligence, pitted two different AIs against one another. One of them "learned" that it could "win" the competition by forcing the other to use more and more memory space, resulting in a crash of the other.

Another idea to get across is that if the numbers (data set size for example) are small, then using a highly efficient algorithm may be worse than one theoretically more "inefficient". Big O is about asymptotic behavior, of course and the more efficient algorithm may be more complex and actually be worse on small data sets as well as being, perhaps, more likely to be buggy. Some quick sorters, for example, revert to a quadratic algorithm once the split gets the datasets small enough. I once built a product that had an exponential algorithm embedded in it. That worked, since the likelihood of a large dataset was vanishingly small. Integer Programming is actually done by real programs in the real world in spite of the complexity of the problem itself.

Finally you need to note that Big O is about algorithms. That is related to the complexity of problems, but isn't exactly the same thing. There are a lot of array sorting algorithms and they have different exponential behavior. But the problem itself has an inherent complexity. For sorting int or long values (the built in data types) in a computer, the complexity is actually linear (Radix Sort). You need some sort of a BigNum data type before you reach $O(n*log(n))$, since the number of possible values in int is bounded. And for large numbers of arbitrarily large values, you start to run into space problems for most purposes.

Let me note, for completeness, prompted by a "conversation" in comments here with user RiaD, that any algorithm that is $O(n^2)$, such as Bubble Sort, is also $O(n^3)$ and $O(n^4)$ and $O(2^n)$, since all of those other functions dominate $g(n) = n^2$. One normally gives a "good" estimate, but the "worse" estimates for growth apply by default.

tl;dr: Say what's true. It is a complex, mathematical topic. Examples are good. Deep understanding can come later. Completeness isn't essential in the first cycle of understanding. Take that into account when testing.


How to advise change in a curriculum as a new teacher Due to the Corona crisis I was forced in to a temporary career switch. Currently I am working as a sort of "supervisor" for students in a controlled environment where they do projects provide from companies. So they get some practical work experience while not directly working at a company (Seeing most companies don't accept interns due to the corona crisis).
My issue however is that the students (in my opinion) are nowhere near the level they are supposed to be. They are in their second year of college(software engineering), yet barely have complete understanding of the basics. This is partially due to classes falling out due to the Corona crisis, but also in my eyes because their program is slow paced and wrongly focused (Nearly the entire year is dedicated towards HTML/CSS, they barely touched PHP/JavaScript/Databases and had nothing in terms of documentation).
This forces me to spend more time doing lectures and teaching them what they were supposed to learn then actually doing my so called "supervisor" duties of managing the projects. To help them increase their level of knowledge I started making my own little assignments for them to practice with and referring online tutorials to them but, I can not force them to do them so a large chunk just ignores it.
Seeing I am doing a good-job I will also be doing extra groups as of February and will be giving actual lectures besides my supervisor role.
This is my first "teaching" job and I am wondering how I can advise the school to make changes in their curriculum without sounding like a know it all/arrogant. Seeing the students have shown to me that with the right structure they are more then able to grasp the material but the schools pace and prioritization of the materials is to slow/focused on the wrong things. As a result the students literally telling me that they don't see the "urgency" of doing their work seeing the got way to much time to do it and it's boring due to the ease of it.

You might not like this answer, but I would be cautious. There could be many reasons why their curriculum is laid out in the way that is.
They might be dealing with students of more varied abilities at the start than you think. They might have later coursework that depends upon mastery of the current coursework. They might only have it in place for historical reasons.  This current curriculum may well be in place because of certain problems with another approach that they took in the past.  Or, they may feel that the mission of their program is somewhat different than you think it is.  (This last is almost a given, actually.)
Therefore, the first order of business is, at least for a while, to do more listening than speaking.
Now, as for what you can do: at least in the US, many institutions that teach to the ages you mention have periodic curriculum reviews. Sometimes these committees can even involve outside representatives from industry.  You could express your interest in serving on such a committee if your institution engages in this practice.
Beyond that, you can certainly share your observations.  Most people (though certainly not all) would be willing to engage in such a discussion with someone who is not pushy or overly-opinionated.  And, in such a conversation, you may well find that there is openness to change!  What I would stress, however, is that you should also remain open to the idea that things are in place for reasons that you simply don't know, and they might not ultimately choose to change the structure.


Encourage students to learn and use advanced design I mentor an FRC (FIRST Robotics Competition) team, and they program in java.

The team members who work programming the robot are using an extension1 library which they themselves write.

The library that they write doesn't exactly follow good design concepts. for example, instead of having an interface for describing the functionality of a moving subsystem (a robotic forklift, for instance), they have a class that extends a subsystem, and it contains that functionality.

This is one example, and there are quite a few other examples. I say this to explain that they have quite a bit of code already written, and it would be difficult to make it more abstract and write it with a higher level of design.

So my question is how can I approach the subject, and encourage the students to want to learn and use higher levels of abstractions?

By "approach", I mean bring up the matter, without making it sound as though I think they have to do it, or that their code "won't ever be good unless they do it".

The students can learn it (i.e. they are able and capable of learning those concepts). This question isn't about how to teach it, but rather how to encourage the students to want to learn and apply those concepts

A clarification: I am not their teacher, I am a mentor. I do not teach them, but rather I help them learn (it's informal)

Proper design and abstraction makes code, especially libraries, easier to maintain and easier to use, and also prevents some types of bugs and errors.
That is one of the main points of design patterns, as well as a "side-effect" of following SOLID principles.

1Without going into too much details, I'll say that there is a supplied library for programming the robot, and the team is writing an extension of that library.

The most fundamental shift in my programing came from my attitude about details.
When I was young I wanted to pull every detail out of everything I touched, pin in down in front of me in one source file and beat it into submission. I could stand in one place and know everything.
After decades of programming my attitude is: the less I know the better. Dealing with a detail? Feh, I let other things deal with that. I already have plenty of stuff to think about right here thank you. I don't need more clutter.
I have shifted from a procedural mind set to a more abstract one.
That sounds fancy but all it means is that no mater where I am in the code, I want to think about only one problem, in only one way, from only one perspective.  Any detail that distracts from that is getting tucked away somewhere. I work very hard to make it that easy because I'm that lazy.
There are many ways to try to teach this, problems that invite students to drown themselves in details if they aren't careful. But one guiding principle has helped me see when I'm doing it right.  It has many names but the one I'm most fond of is:
Tell. Don't ask.1,2,3,4,5
If I have to ask a question then I have to deal with the answer. Usually that's a detail. The only reason I ask is because I want to do something and I don't have enough information to do it. Why can't I just tell the thing I asked to just do my something? It knows the answer, so it knows what it needs already. I should be able to just tell it "do it now" and it should be able to go do it without making me think about it.
Adopt this attitude and working abstractly becomes very appealing. Without it, abstraction and polymorphism are very annoying because they're getting in the way of you knowing everything. Teach your students to love not knowing.
I don't know. I don't want to know.

How to motivate students to use this?
Don't.
Motivate them to explore it. Which is better is not a settled issue. What you should teach is what problems this style addresses. How to identify situations that create a greater need for it. How to identify situations where it's irrelevant.
I've been studying every programming principle and style I could find for decades now and not one of them is something I would advise someone to adopt without critically analyzing how and whether to apply it in any given situation.
What I do recommend is practicing with them. Until you've used one while solving a real problem all your doing is being a tourist. I've watched people end their career by waving a book around preaching principles without knowing how to solve a problem.
When interviewing prospects I'd rather hear:
"If you follow principle x it may help with this y issue."
than
"You should always follow principle x. It's good design. Professionals always follow good design."
Spare me from fanatics that follow rules without thinking.
Encourage them to learn every principle, pattern, and practice they can. Not because they should always use them, but because when they look at code that already uses them they should understand why the code looks the way it does.
The reality is true professionals spend most of their time wading through crap code trying to get what they need out of it while causing the smallest amount of fuss they can.
The really good ones will spot some tiny little improvement they might be able to get away with while they're here. These "boy scouts" leave the code a little better than they found it. Give me those over the crusaders that want a complete rewrite every time they look at a new code base.
Cultivate in them a skeptical "boy scout" attitude. Give them all the tools but teach them to use them sparingly, wisely, and carefully.


Advise on a class project Me and my friend are both in high school taking a “PLTW” Engineering class, where our goal is to design a solution to any problem and work on that solution over the course of the year. We’re reaching out to this forum in hopes to receive some advice on our startup

After careful consideration of different projects we could pursue, we came up with the idea of a platform that could provide comp. Sci. students with all the resources they would need to develop their careers. We would take on any willing instructors with backgrounds in coding that would be able to use the students as a means of developing their personal projects, while simultaneously teaching them how to code. Everyone benefits. We hope to expand this past just students, and take on more and more staff. The students would leave the program with experience in their field and proficiency of 1 or more languages.

The main goal of our platform is to provide a network for students and teachers to collaborate and work on projects while developing their skills as coders.

Where we are at
Right now we are in the planning phase. We need to reach out to different communities for not only advice but for reassurance that people would want to take part in this project with us.

What we need help with
If anyone has had experience with assembling people for a project, or just starting a project in general, we would really appreciate any advice you might have for us.

So our question is
How do we go about finding people that would be willing to invest in our idea? We would need teachers, students, and anyone else who is qualified and willing to work with us.

Buffy's answer is already spot-on, but here's another $0.02.

  We would take on any willing instructors with backgrounds in coding that would be able to use the students as a means of developing their personal projects, while simultaneously teaching them how to code. Everyone benefits.

I think you're vastly underestimating how much work it is to delegate tasks, to bundle those tasks up in a format that another person can approach, and to generally manage other people. It's also very difficult to deal with time management (or lack thereof), and to manage expectations (and decide what happens when expectations are not met).

You're asking instructors (who are already extremely busy) to work as program managers, for free, on projects staffed by people who are going to need a ton of hands-on help. There is a huge time cost here.

You've basically just described an internship, and generally both parties are paid for their time. If you aren't planning on paying the people involved, then I'm afraid you aren't going to see many volunteers.

Your heart sounds like it's in the right place though, so I'd recommend doing another round of brainstorming. The best advice I can give you is to start smaller.

For example, you might rethink your project to be something more like a way to connect students to open-source projects looking for help. This question has a bunch of resources you might want to check out.


Good, Motivating Examples for Algorithmic Complexity I was recently reading a really good article on this topic, and I realize that it could be a very good added value for students to understand better and appreciate (and eventually put in practice) all the theory that is behind Algorithm Complexity1. Certainly, not everyone will apply this in the future, since the most efficient way to solve a problem is not always required (although it should be). I think more people should be interested in this, since it has benefits in various ways.

To understand my question a little bit better, I want to give an example of my own personal experience.

  From the very first moment I learned about Trees and Binary Trees (a
  long time ago), I don't know why, I hate them. I never thought about
  them like a solution to the many problems I had to face and resolve.
  Some time ago, I was told to recreate from scratch the Shannon–Fano
  encoding as an exercise. I enjoyed that so much! And of course, for
  that encoding, everything is based on trees. It was at that point that
  I was more interested in trees, how they work and their functionality
  to solve real life problems.

So, in the same way the Shannon–Fano coding help me to understand better and made me want to go deeper in the tree's data structure theory, I'm asking for good motivating examples that might help others understand and want to learn more about Algorithm Complexity.

1 Just to clarify, when I say Algorithm Complexity, I'm talking about all the theory and techniques that are available to know how efficient an algorithm is, and to compare that information with other results, thus leading to the most efficient way to solve a problem.

I attack this problem with three "visits" over the course of two years with my students

At our first brush with Complexity, I don't spend a ton of time motivating the study of it.  I introduce the notations of $\Omega$, $\Theta$, and $O$ (as well as briefly touching upon $\omega$, $\theta$, and $o$).  I show the difference between linear and binary search, and then explore four sorting algorithms: bubble, selection, insertion, and bogosort.  (This is fairly early on in the curriculum, and we haven't dealt with recursion yet, so I skip out on quicksort and mergesort.)  The last one makes them laugh, and makes the material at least have a point: some algorithms are just worse than others.
Later in the year, we look at quicksort and mergesort.  At this point, again, we use this only as a chance to review the concepts and the notation.
Near the beginning of the second year, I talk about why algorithmic study matters.  Computers get insanely faster over time, right?  (See Richard's answer for some eyebrow-raising numbers).  Since our computers are getting faster, it only stands to reason that things that are slow to compute today will also just get faster.

"Au contraire!" I cry, "as our computers get faster, our algorithms are getting slower, you see!"  What do I mean by this outrageous claim?  As our computers get faster, our hard drives also get bigger.  By necessity, we perform calculations with larger and larger data sets.

So, let's use high-end rendering as an example.  In 1980, Apple came out with the Apple III computer, which shipped with a whopping 5 megabytes of diskspace.  It also used the 6502B processor.  It could perform about 0.43 million instructions per second (MIPS).  Today, hard drives come in at about 6 gigabytes, and 305 billion instructions per second.  My numbers don't have to be exact to make this work, though.

If we processed a complex graphic that took about .5% of our hard drive using a $O(n^3)$ algorithm in 1980, that would be about 2,500 bytes of data, and it would take us roughly 9.25 years to complete.  That's awful!!  But if we did that today, (roughly 30 megabytes and 305 billion computations per second), it would take us over 28 thousand years to complete.  We're trending the wrong way!  The problem is that, even at a relatively cheap function like $O(n^3)$, the growth due to data creep is just far faster than Moore's Law.  Faster computers can't deal with correspondingly bigger problems if the $O$ sucks.
Finally, a few weeks later, I talk in grand, futuristic terms about the Big Picture.  This is more to excite their curiosity than anything else. The three drivers of possibility with computers are, I argue, smaller transistors, better battery life, and better algorithms.  If you take a $O(n^3)$ algorithm and find a way to accomplish a similar task in $n^2$ time, that's a foundational enabler.  You don't become individually famous, but you change the world.  The Google Maps team didn't solve the Traveling Salesman problem, they developed algorithms that could get likely best answers without the guarantee.  The bottom line is that developing algorithms with better complexity literally enables us to do new things on practical timescales.  To paraphrase Heroes, change the algorithm, change the world.


how to motivate student that programming will give bright future to them? some students in my class are leaving CS because programming is difficult and think that it will not give them bright future. how to motivate that students, that their interest is develop in programming and they become satisfied for their future.

This might be a mistake, actually. Everyone is different. People like doing different things. Programming isn't for everyone, nor is the wider world of Computer Science as a whole. My daughter, for example, is perfectly happy as a Philosopher. My son is perfectly happy outside academia.

Convincing someone to do something (a kind of advertising) may do them harm in the long run. People spend millions of dollars convincing people to consume sugary drinks, to their detriment.

If you make the classes interesting, with interesting problems to solve, those who want to do it will stay. Wish the others well and focus on those who want to work at it. Some of us have found that group work (pair programming) is a motivator, introducing a social aspect to learning as well. On the other hand, it is possible to make learning programming as dull and demotivating as learning multiplication tables.

I'll note that many things are hard. Becoming an olympic athlete is hard. Some people are willing to put in the work to do it. For others, it isn't worth that effort.

Saying the "future is bright" is something you can't honestly predict. Many things could happen that make it less bright. The need for people specializing in CS might decline in future years as some processes become more regularized. This has been the history of the world, actually. One takes a chance on the future no matter what you do, so you might as well follow your own dreams, not those of someone else.


How do I teach ethics in hacking? I teach a course on hacking every other year.  It's a very difficult class, and it only attracts kids who are really enthusiastic about delving deep into the bowels of gdb, stackframes, format string vulnerabilities, buffer overflow attacks, and the like. 1

At the beginning, I give a short lecture talking about ethics.  The basic analogy that I draw is to a locksmith: a good locksmith can get into your car, and can get into your house. But an honest locksmith does not, because the lock that is in place communicates that he or she is not supposed to enter.  Thus, a good lock is there to keep out honest people.2

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

The question, then, is is this a sufficient message to impart?  If not, what more need be said?  Bear in mind that it is not actually a course in ethics per se.  I really can't spare more than about 15-20 minutes to impart the most important ideas, so I really want to make that short time count.

¹  The course largely emphasizes security holes from the 90's and the 00's. This isn't to prevent them from being able to work in modern system, but because you can study the attacks we focus on in relatively pure forms using virtual machines from that time, so we don't have to spend time working around more advanced security features. And learning about those attacks in any depth is already plenty hard!

² The lock may not be effective against, say, a determined burglar. But it helps people who generally wish to stay honest avoid temptation and conquer moments of ethical weakness.

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

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

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

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

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

From there, I had an ethical choice:

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

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

  if a security feature is designed to keep you out

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

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

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

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

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

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


How to encourage participation in the national olympiad in informatics? Currently, relatively few participate in the national olympiad in informatics (high school) of my country. This is partially because the first round takes a bit of time (up to 40 hours if one wants to reach a perfect score, but 10 hours should be sufficient for a passing score). I'd like to encourage participation in the national olympiad in informatics, because I think that several students are good enough to do well in the olympiad and I think they would like it.

How can I encourage participation?

Personally, assembling a team (or club etc.) of those students and teach them the relevant material would encourage most (if not all) of them to participate.

Also, finding a guide\mentor who can teach them would give the sense of, for lack of a better word, prestige.

Here, where I live, there's a national competition and it's very popular, due to the use of the aforementioned method.


Why teach C using scanf without talking about command line arguments? Most of the books I read give examples using printf and scanf. At some point the students know perfectly how to use these two functions but they don't know about stdin, stdout and argv.

To me and according to many programming principles (e.g. KISS) a program should not interrupt the execution for prompting the user. Instead, and this is a much clever approach, the developer should learn to use the power of pipes and use the options and the arguments.

I think this:

$ whatdaywas 1982 02 16
Monday

Is much better than:

$ whatdaywas
Enter a year: 1982
Enter a month: 2
Enter a day: 16
It was a Monday.

Is there any rationale behind this pedagogical approach?

I think that the rationale is so you don't have to introduce arrays and array notation on day 1. Typically, arrays enter into the picture at roughly the same time as loops, which would take place a few weeks or months later, depending on the pacing of your course.

That said, if you want to start with command line programs, it's not a huge problem to do so.  At the very, very beginning of programming, there are always a few magical incantations that students must type, but won't fully explore until later.  args[0] could easily be such an incantation.

As a side benefit to this approach, your students may have an easier time when they come to arrays, since they've already used them a bit.


Creating a complete application Good day,
I have learnt the basics of C++ and now know how to write simple console applications using codeblocks.
I would very much like to create a fully functional application like a calendar or notes app.
Can someone help me find resources such as tutorials or textbooks where I can be guided, step by step, to make an app (a very simple one would suffice)?

Writing a fully functional application, even if that application is 'trivial' quickly becomes complex and will need some good thinking on paper before starting your code. I would suggest learning a software development proces that starts with requirement analysis and takes you all the way to technical design from which you can start your code. The one I know is called ICONIX (for object oriented programming) described in "Use Case Driven Object Modeling with UML - Theory and Practice". The book uses a bookstore as an example application and is very hands-on. The application is developed using Java and the Spring framework. It is essentially a step-by-step guide to application development. Through object oriented analysis, you will create a detailed design in the form of a class diagram with attributes and methods allocation, and sequence diagrams for the most critical features. You will work through one use-case at a time and iteratively develop a fully functioning application.


Is there any value in teaching goto statement or flowcharts? I was recently reading a new, and mostly excellent, magazine Hello, World. There is an article on teaching goto. The author states that there is value in teaching goto, as it helps to translate flowcharts into code.

I have always considered goto to be harmful. It results in code that is buggy and hard to read. Not just because I read it in a 1960 paper “Go To Statement Considered Harmful“ — Edsger W. Dijkstra, but because it is self evident (once you have tried structured-programming).

I have always considered flow-charts the same way. They are just the pictorial form of unstructured code (The UML of assembly language).

So the question:

Does the author have a point? Is there some value in goto or flow-charts?

I accept that:

Flowcharts are visual, but there are visual structured representations that are better.
goto can/has-to be used in teaching assembly language/machine code.

One of many links to the paper “Go To Statement Considered Harmful”

I am the author of the article. The point is to simplify the model of computation, not to match flow charts.

This is for mixed-ability 12 year olds, and when I say mixed, I mean some still add single digit numbers using their fingers.

Flow charts work because you can easily jump to another point in the program. This is not software engineering. I want them to create software where they understand how it works.

Goto also more closely mirrors the processor: it's easier to describe how programs are translated. After all, there is no such thing as structured programming at machine code level.

Dijkstra's article is a polemic from a purist. There were dissenting views at the time, which gave a more nuanced picture. The Wikipedia page on the article has good links on this.

Most new programmers shun goto because they have been warned it is evil, bad, and wrong rather than a more considered opinion.

My GCSE students learn structured C++. I myself am a CS grad and was a professional programmer a number of years ago.


Java: The Complete Reference, which edition to follow Java is updating on a regular basis and it being so the corresponding text books to study Java also changes. Now I do not know why the edition "Java 2: The Complete Reference" by Herbert Schildt is so famous, in the sense that I find most educators having a copy of this particular edition and there are abundant used copies of the same available at cheap rates.
$\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad$
No doubt it is based on an older version of Java, but what is the special in this particular edition.
I am quite confused as to which edition to follow, as in many cases of other texts I have seen that older editions are at times better and clearer in the meaning and newer editions tend to go less lucid at times.
With the advancement of Java in this rapid rate, which edition to follow (edition 11 is the latest I hope) and how to be updated of the advancements (if I am suggested to follow the latest edition, it is going to get old within a couple of years).

The fundamental question is, whether your goal is to learn programming (in which case the language doesn't matter at all … theoretically at least) or to learn Java.
If you want to learn programming, the programming language and the version doesn't really matter. It only matters insofar as to understand the examples, and to understand the concepts behind the code, you need to understand the programming language. So, the code and the programming language should be as simple as possible … e.g. a language like Scheme or Smalltalk, or you already need to know the language.
If you want to learn Java, then you should use a recent book, because there has been a lot of stuff introduced that not only makes stuff easier to read and write, but that fundamentally changes the way Java programs are written.
Sun dropped the "2" from "Java 2" in 2004. That should give you an indication as to how old this book is. It covers Java 2 1.4, which was released in 2002.
You don't have to chase every version, every release, every edition, every new feature (especially with the new 6-month release cycle), but since 2002, there have been multiple new features in the Java language that fundamentally change how Java code is written:

Java 5 (2004):

Generics
Annotations
Autoboxing/Autounboxing
enums
Varargs
The enhanced for loop
[LIB] JSR166 Concurrency APIs

Java 7 (2011)

[LIB] Extended JSR166 Concurrency APIs
[LIB] NIO.2

Java 8 (2014)

Lambdas
default methods on interfaces
[LIB] The Stream API

Java 9 (2017)

modules
[LIB] Reactive Streams

Java 10 (2018)

Local variable type inference

Java 14 (2020)

switch expressions

[I bolded the ones I deem to be particularly disruptive. I marked some features as [LIB] which are library additions to the Java platform and not language features, but are nonetheless important. E.g. NIO.2 offers a whole new, much higher-level, much improved way of interacting with files. And Streams essentially mean that you will never have to iterate over a collection ever again.]
Value Types and sealed Types will bring another major shift in the near future (possibly as early as Java 15 (October 2020)). In particular, sealed Types will allow modeling Algebraic Sum Types in Java, which opens up a fundamentally different way of structuring programs.
Oracle has recently started to include so-called Previews as well, these are features that are shipped as part of an official release, so they reach a wide audience, but that are not guaranteed to be supported in future releases in that form. They may be changed or dropped completely. One of those features is records that currently ship as a preview in Java 14. While they aren't as disruptive as some of the others (Generics, lambdas, Value Types, sealed) as they are just syntactic sugar, they allow to drastically reduce the amount of code for simple data classes, and thus make it easier to see what is going on.
For example, this:
final class Point {
    private final int x;
    private final int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int x() {
        return x;
    }

    public int y() {
        return y;
    }

    @Override
    public boolean equals(Object that) {
        if (!(that instanceof Point)) {
            return false;
        }

        var other = (Point) that;
        return x() == other.x() && y() == other.y();
    }

    @Override
    public int hashCode() {
        return x() ^ y();
    }

    @Override
    public String toString() {
        return "Point[x=" + x + ", y=" + y + "]";
    }
}

Can be written in Java 14 as this:
record Point(int x, int y) { }


The theory of parsing, translation, and compiling, v.s. Compilers: Principles, Techniques, and Tools? Alfred V. Aho, Jeffrey D. Ullman have written

The theory of parsing, translation, and compiling. Volume 1 Parsing 1972 and Volume 2 Compiling 1973

Compilers: Principles, Techniques, and Tools 2ed 2006, i.e. the dragon book.

Are the two-volumn books more advanced or complete than the dragon book?
Is the dragon book supposed to replace the two-volumn books?
Are the two-volumn books outdated or still very relevant?
Thanks.

A lot has been done since 1973. But for an introduction, the earlier books should be fine.
For a more advanced treatment, choose a modern book, of course.
Another book that I like a lot is On Pascal Compilers by Brinch Hansen from 1985. While it is written in Pascal, it is one of the true pieces of CS Literature. It restricts itself to Recursive Descent parsing which is suitable for LL(1) languages. But my view of languages is that the should be LL(1) for readability, though compilers might use LR techniques for efficiency.
So, it depends on what you need. If you are a novice at this and haven't yet built any compilers an older book might actually be superior.


Suggested fliers for high school career fair? I will be tabling at a high school career fair and would like to have printed fliers about careers involving computer science. Does anyone know where I can find ones that are free (either to print or have sent to me)?

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

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


What are some real life applications of the knapsack problems class? Students are very happy when they see some real applications of the theory. Any suggestions for interesting examples of knapsack problems?

I'll probably try with this one, from an actual software I almost developed.

There's a factory that produces paints in various colours.
The factory has a single production line that can produce only one colour in a given moment. It's capacity is also limited, i.e. 1000 litres per day regardless of the colour produced.
Different colours have different production costs and are sold at different prices. I.e.: white is cheap to produce and is selling price is low. Gold is expensive to produce because metal sand has to be added in the paint to give it a shiny note. Gold is also sold at higher price. Red lies in between.
Different customer requires different amount of paint, i.e.: customer A asks for 1000 litres of white, customer B and customer C asks for 250 litres of gold each, customer D for 700 litres of red.

That given, the problem is to find the mix of production that maximise the profit.


How to give assignments that require heavy computational resources? For an undergraduate course in AI, there has been an assignment that uses deep learning on neural networks to do image classification.

However, many students complained about their (university provided) laptops were overheating when running their implementations and only a few were able to run enough training epochs to get meaningful results. (While those devices have a high-end CPU (for laptops, at least), the GPU is rather low-end).

I doubt that the problem was bad implementations, as even the better students had these problems.

All in all, just letting the students run their own implementation doesn't seem to have been a good idea. Are there better methods to give students the assignment of practically implementing a computationally intensive algorithm? How feasible would it be to provide cloud compute resources to the students so they can run their own implementations (I don't think we have a computing cluster available to students at my school)?

How to give assignments that require heavy computational resources?

Don't.

Most computionally intensive problems can be stripped down to something that's just as instructive but runnable on any normal computer. In particular, for inexact algorithms, you can generally trade off accuracy against computational cost, and often actually get still quite good results with only a fraction of the cost of a publication-level run.

I always like to emphasize that stuff like physics simulations (which is what I work on, and have also done assignments for students) or image classification should in principle, mathematically speaking, have infinite computational cost: an image is a function from continuous 2D space to colour space, i.e. the space of images is an infinite-dimensional $L_2([0,1]^2)$ Hilbert space. When doing numerics one quickly (IMO, often too quickly and without proper thought) restricts everything down to a finite-dimensional subspace thereof, but that's to some degree arbitrary – the subspace just needs to be big enough (and suitably constructed) to still represent the features that are important for the use case.

In an image-processing example, you should definitely check how much you can downsample the images that the students should work with and still get somewhat sensible results. If necessary, choose only a smaller set of images with clearer distinguishable features, that the algorithm can pick up quickly.

If the results aren't so great with a stripped-down accuracy, well, that's actually particularly instructive, because this kind of tradeoff is absolutely crucial in real-world applications too. You may have more processing power available in a research of commercial situation, but you'll also have much higher demands in terms of data amount and needed accuracy. So, discuss these points intensively, and make a presentation of how much better the students' results look when run by you in higher resolution on a solidly powered machine.


Textbooks: Yes, no, roll your own? I haven't used textbooks in my classes for a number of years. I find that generally it is hard to get students to read them unless you assign homework questions. And I'm not a fan of that method. What I have been doing is making my presentations available online. Students do review them but they are light on detail. Recently I have started writing my own books. They are short - about a third the length the typical textbook - and I am hopeful that they will actually be read.

What are others doing? Are you using standard textbooks or no textbook at all or do you write your own materials of some sort to share with students?

This is difficult to answer in general. I have personally used a lot of different solutions depending on the course. For low level courses it may make less difference, but maybe not. I still have many of the text books from fifty years ago that I considered important to my development, and have consulted them.

There are courses in which there are truly classic books: The Dragon Book for compilers, for example, which is dated but still valuable. It would seem a mistake to me to try to teach a class in Scheme without at least one of the two classic books. But there are other courses in which there simply are no textbooks, the material being too recent or in flux.

One reason for not using your own materials exclusively is that your students get to see a view other than your own. That seems to me to be a good thing in itself. Some of your students might use the exercises or worked examples in a textbook for review and exam preparation.

If you intend that your materials won't be valuable to them after they leave your course then informal materials are fine, in my view, but if you want them to have a resource that they can use later then make sure that it is one that will stand the test of time.

I also used extensive materials of my own, but mostly as a supplement to more formal materials. Like you, I seldom referred to the formal text, but it was available to them whenever I was not, including after the end of the course. Think about your student's future, not just their present.

It might be enough, in some courses, to provide an annotated bibliography including, especially, classic works. But if your students aspire to be professionals in the field (academics or not) then they should build up a library starting in their early years. I'm guessing that you have done that yourself, as I have.

There are, of course, situations in which the cost of modern textbooks can't be ignored. Providing low cost or free resources may be essential in these situations.


What intro CS coursework is most useful for life science students? My college requires students earning a bachelor's of science (BS) degree to take a CS course. Currently, they take the same course as CS majors: a typical Java 1 course. What would be a more useful course for students majoring in the life sciences (as almost all of our BS students are)? Some of the students hope to become doctors or veterinarians, others medical researchers.

I'll say upfront, I'm familiar with both life sciences and CS, but I've never applied one to the other.

In life sciences, computing is used for a lot of heavy processing. Stuff in genomics and molecular modeling, for example. It's not fast work. Efficiency, then, must be important for researchers to know about. The course you're designing should cover Big-O and and related topics in its discussion of algorithms.

That theory won't be much use if the researcher can't communicate with the computer. I'd say Java may not be the best language to use. The upside that's usually cited is that it's very common, and similar to other languages in industry, but these students aren't going to be professional programmers, so that doesn't really count for much here. With Java, you'll also be spending a lot of time teaching semantics about the language itself rather than CS principles; time you can't afford to waste if you get only a single course with these students. Alternatives: Python seems to be used more in science, and Ruby has a nice learning curve. Both are well-established languages with plenty of documentation and communities available online.

Doctors and vets who are frontline healthcare provider types rather than in-the-lab researcher types are more likely to be users of software than writers of it. Depending on specialty, they'll be dealing with assorted medical records suites and similar programs. They should understand principles of cybersecurity, including more technical things like how passwords really work (or, just as important, fail, e.g. lack of salting or e-mailing in plaintext) and what makes them important as well as less technical ones such as social engineering, which are often both easier and more effective.

(Thanks, xkcd 538.)

Doctors and researchers are already looking at images on computer screens a lot, and I don't think I'm predicting the future too much by saying that's only going to increase. Understanding how lossy compression works, or JPEG format tradeoffs, and why the "zoom in and clean that up" CSI magic from TV doesn't happen in real life could be useful.

Beyond all that, there are some fundamentals that everyone should know, life sciences or not. The basics of how a computer operates, so that it's not a mysterious magical process between pressing keys or tapping the screen and pixels lighting up. Some brief coverage of programming, algorithms and data structures. The fact that no matter how fast we make computers, there are some problems they can't solve, and we can prove that using math (even if you don't go through the proof itself).


What part does formal Ethics training play in your curriculum? What is your current practice of teaching ethics to students, both institutionally and individually?

Note that the teaching of ethical standards (not just lists of rules) has at least two elements: What to do, as well as what not to do to be ethical.

Are your students required to take any ethics courses? Are those courses tailored in any way to the concerns of the technorati? Do you bring up ethical consequences of the things you teach? Are you required to? What topics do you think are most important?

What can you recommend to others for giving students some ethical training?

Are students required to buy in to an ethical standard beyond the classroom?

Or do we simply depend on, and hope that, it happens somewhere.

It would be helpful to know which courses you teach that clearly require ethical behavior and how you go about teaching it. For example IoT (Internet of Things) development has clear implications about security and privacy. How do students learn this?

I hadn't really considered teaching this, but one could use the ACM Code of Ethics and Professional Conduct, and simply talk through the major points. I looked at the General Moral Imperatives section and it basically boils down to the usual ideas about "doing what you would want to happen" in a situation. If people do not realize that we are in a collective enterprise and that their actions affect everyone, then they need more basic education.

To answer your questions: There is some "soft skills" training here, but I am not involved in presenting it. As far as I know, it is not discussed otherwise and the students are not required to accept any set of principles. I guess we figure that they already have it. My co-instructor referred to ethics as "the things we used to assume everyone already knew." Where and how they used to learn it and who is failing in their responsibility, I do not know.

Gerald M. Weinberg writes about The Platinum Rule (do unto others as they would be done unto) and I can't see that much more needs to be said about ethics, beyond illustrating what could happen if that rule is not followed. It is no different from other fields that have codes of ethics and professionalism. (Except that we can easily influence the lives of millions of people, for good or ill.)

In this reference - Stanford panel debates: Does teaching ethics do any good? - they ask, "can something as personal as ethics be taught in a classroom?" I don't see ethics as personal, any more than physics or finance are. If you know what to do, you can safely assume that any other person who also knows will do the same thing. The only 'personal' factor would be ignorance.

It also says, "teaching students social psychology, rather than moral philosophy, is one of the most effective ways to make them more responsible social actors." I would agree. Finally, one participant said, "When I teach them how to write a philosophy paper, I definitely assume I know better than they do how to write a philosophy paper ... [but] I'm 100 percent certain I am not more virtuous than many of my students. Some of them live much more conscientiously than I do." I don't understand that either: why wouldn't more experience make one more virtuous? As the old saying goes, good judgement comes from experience and experience comes from bad judgment. Shouldn't this be true in all cases?