Test takings strategy tragedy Are students generally aware of test taking strategy or do I need to emphasize this? I have to ask because I often reuse tests and some years all the students breeze through with plenty of time, and other years it is challenging, and they might even run out of time. A test where they run out of time is essentially invalid and does not help me.

But, I think there is in those cases a failure to make the best use of the time! I tell them the point values of different items (1 pt for True / False, 4 for Multiple Choice, 5 for Fill-in words) and I say to look over the entire test at the start, to answer all the easy ones (for them) first, then go over it again to get slightly harder ones, then the hardest ones, and finally, review the answers before submitting the attempt. So, I do give them strategy.

But sometimes there is still this tragedy: someone runs out of time half-way through. My tests are almost always open book and notes (but no internet use). When I hear, right from the start, lots of page-flipping, I know it will not end well. Someone is starting at the first question (T/F is at the start, then Multi choice, then Fill-in), and giving equal attention to all of them. I think it is because, even though they know the strategy, they panic and just bear down.

To me, this is work-related learning, and we are giving workplace-relevant training, and so learning not to bear down is a good lesson.

Is there a better way to introduce and reiterate Test Taking Strategy, beyond what I have already done? How to quell their panic, when I hear the page-flipping? Too late?

Test taking is a skill that not every student has. It should be learnable with practice, but not everyone comes to the same level. This is independent of subject. Some people just freeze up, some spend too much time on inessentials, trying hard to "get it right." Some students just panic and nothing you say will alleviate that panic. Every exam is like their first ride on a zip-line or their first rappel down a sheer cliff.

Like anything else, all of your instruction about strategy will only reach some and everyone's response will be different.

However, There are two things you can do. First, my own preference is to avoid stressing tests in favor of projects for grading. Tests are useful for advising, provided that you do advise the students singly when the fall short. For grading, however, projects let students do their best work in a more measured mental state.

However, I found that open-book exams are far from optimal. The only exam I distinctly remember badly failing in College was an open-book test in Physics. The problem is that the student will study wrong before the exam and will come to depend on the book in the exam. That is why you heard the page flipping. The "facts" were in the book. I don't need them in my head.

Prior to any exam that "counts" you want students to review and practice with the material in a way that mimics what they are likely to see on the test. They can/should provide their own review materials, or you can provide them (not as effective). The nature of the problem is that test preparation for an open book test is insufficiently active. They don't do much to reinforce their own knowledge beyond, perhaps, knowing a bit about where they can find various things in the book.

Moreover, your test isn't likely to just ask them to transcribe the book's information, but to do something with knowledge learned. Open book tests actually discourage the actual learning part.

An alternative to open-book is to permit the student to bring one standard sized sheet of paper to the exam on which they may write anything they like prior to the exam. The paper should be signed by the student and handed in with the exam (largely to prevent student B from using a copy of student A's sheet). This forces them to be at least a bit active in their prep.

A second, possibly valid, use of open-book testing is the following. Assuming that the test period is about an hour, announce beforehand that for a five minute period starting at the 30 minute mark, students may consult their books and/or notes. The open-book segment needs to be short and it needs to be after students have had a chance to consider each question.

tl;dr: Consign open-book tests to the dust-bin of history.

Tests / Quizzes tend to be under 30% of the total points for a course segment (a few weeks). The rest is Lab projects that they have days to work on each one. My co-instructor has more 'performance' oriented questions on their tests, and I lean towards using the test questions provided by the textbook publisher (choosing selectively).

Recall of words and ideas is absolutely vital as a programmer, equal in importance only to being able to look things up quickly and accurately. And, that is pretty much the entirety of what I am trying to impart at this point. They will never remember everything in a single course segment, let alone the entire year. But they must end up with a tree of related ideas that prompt their memory, or they have learnt nothing at all. I admit to my ignorance in how to plant and nurture this tree.

It always mystifies me when we are looking at yet another way to use a Collection, and I say, "this is a Collection" (being careful to capitalize the word) and they look as though they have not heard of Collections relentlessly during the last 4 months in every conceivable circumstance. It's an ubiquitous concept. Get used to it.

Working under pressure is necessary. Someone will ask a question in a meeting (or a job interview) and something had better come to mind. I realize that people vary in that ability, and one of my former supervisors was not good at thinking that fast. But he got good at reformulating the question into his perception of the path to proceed, and saying, "I will get back to you right away on this." It worked. So, in fill-in questions, if the person has even a related word or concept, I give partial points. I am not an ogre.

Many times I have solved programming problems by recalling some tidbit I had read years ago, and then looking it up to get the details of how to apply it. So, open book is simply how life works, not some awful stumbling block that I am placing. But not panicking is something that every professional needs to learn. We cannot afford the results otherwise.


A beginner example of xor, that is functional (does not switch to procedural) I have been trying to think of an example of xor to connect with what students already know. I did some searches. But everything I found, seems to have unconsciously switched to procedural.

For example:
They say for and "the lights are on and my eyes are open".
But when they get to xor, they say "Choose this xor choose that". This is not a boolean predicate that evaluates to true or false. This is a selection.

So the question:
Can you provide an example of use of xor in a boolean statement, that is accessible to students, that are new to boolean?

I am not yet interested in all the beautiful things that can be done with xor. That is easy. At this stage I am trying to connect to what we say in English language.

I can't tell whether I've missed something in the other answers or comments, but the natural language equivalent of XOR is to ask "is there any difference?"

Used in a sentence which follows the broad format of those in the question, you'd be saying something like "the light is on differs-from the door is open", with the compound 'differs-from' element being the XOR operator.

Even in computer science, the XOR and XNOR operators typically go by other aliases, such as Not-Equal and Equal operators, respectively.

I am going to the local animal shelter. I will adopt a dog xor I will adopt a cat. (I only plan to adopt one pet.)


Why don't more universities teach revision control? In the answers to this question, it's suggested that one of the most common things that CS graduates still need to learn to be employable developers is revision control, and by inference that many CS graduates don't learn how to use it while at university.

This surprised me, because on my CS* course we started using revision control (git) on literally the first day of the course, and a lot of the work we did during our degrees would have been much more difficult without it.

Taking this claim at face value, if knowledge of revision control is both a) useful during the degree and b) desirable afterwards, why don't more universities teach students to use it?

I understand that this could be seen as primarily opinion based so, if possible, I'd be particularly interested to see actual reasons given by the institutions themselves or people who teach CS (particularly software engineering) courses.

*I should clarify that my course was in actuality a Computing degree (BEng) and so contained more practical components than others may do.

I suspect it's a combination of several factors:

Version control isn't that challenging to learn (assuming you know how to use the command line). It's something you can trivially understand by following a few tutorials online -- I'd argue the hardest part is actually finding the right tutorial (there are tons of garbage "how to use Git" tutorials out there, and surprisingly few good ones, for example).
Despite that, it can be hard to find time to fit in the command line and git. You'll probably need to spend at least 30 minutes talking about both things, and if you have a lot of material you need to cover, it can be hard to squeeze that in without compromising on something else.

In particular, it's worth noting that you can't necessarily just add in new material somewhere and shift everything over. You need to make sure your change maintains the overall tempo of the course, make sure no topic "overlaps" oddly over a  weekend or a holiday, need to make sure students are still being taught the material they need a sufficient amount of time before you make related HW due... If the original course was competently designed, it's probably a well-tuned engine where every minute matters, so adjusting it will require some degree of effort.
If your university didn't find time to squeeze in version control, you'll be told to learn it on at least day 1 of your first internship or job.

(And they'll probably do a better job of teaching it! It's hard to teach the value of things/give students the opportunity to practice things like branching, rebasing (if you're using git), using specific workflows, etc. in a university setting -- those sorts of more advanced operations are really only useful in larger teams working on a long-term project.)
You mentioned that your intro course covered git on day 1. I can see an instructor considering against that approach if they want to prioritize moving to programming as soon as possible to try and "hook" the students in with instant gratification. (If you're completing new to programming, I can imagine learning to use tools like version control would be relatively dull and sort of a bother -- you don't really get to see the payoff until you start tackling more complex projects later on.)

So basically, it's material that's difficult to fully cover (where the subset you can cover is easy to learn yet still takes up an awkward amount of time), and that the student is going inevitably run into and learn without any real difficulty anyways.

None of the issues I pointed out are insurmountable, of course, but if you toss in inertia into the mix, you can see why some schools would never get around to rejiggering their curriculum to fit version control in.

I personally think it's worth teaching version control anyways (I'll go even further, actually -- I think schools that don't teach version control in some capacity are doing their students a major disservice), but can't deny that it can sometimes be logistically challenging to work that material in.

The majority of 'Version Control' actually pre-dates the Titanic, and was developed as part of Drawing Office procedures. It is only very very recently that the newer distributed version control capabilities have been developed.

Back in the day, drawings were made with India ink on kaolin and linen sheets, and were effectively more valuable than the 'old masters' artworks. If they were damaged then the product could not be built, thus great pains were taken to protect the master from damage or modification. Drawings were 'traced', and from those trace's the blue-prints were made. One would have to request changes, which would be batched up, before a 'change order' was allowed.

In those days there was only one physical master. Protection was paramount. The problems were human and physical. It was an administrative exercise.

Now we have perfect replication and high volume storage. Thus now we often use verification hashes to check if our 'master' is the same as their 'master'. And we use Merkle trees to verify the history of the modifications - Is our master properly derived from their base design (e.g. Git).

So underneath there is a lot of CS theory at work, but it's still something of an administrative exercise. It all depends on whether one is educating someone to be an academic, or a practitioner (or developing the practice..).

It's still a bit of a human problem, it's just that anyone over 30 probably still thinks the old way.


Want to be good at programming (C++) and then start learning game development, where should I start? This semester in my university we learned C++ but I feel like I am not that much good at programming as much as I should be, and because I am also interested in game development so of course it will be helpful for me in future. So I decided to learn it completely and not like leaving in the middle but I don't know from where should I take a course that can be best for me.... I chose a course from Udmey website (https://bit.ly/2nW4ayE) but I am not sure that I should go with it or should I take another course?

After that my main goal is to learn game development, I have zero knowledge in it. But I think I should go with Unreal Engine for game development. I am solo for game development. I also find a course for learning Unreal Engine from Udemy. So should I do Unreal Engine or another engine?

And should I learn anything other before starting game development solo, while I learn programming I can have enough time for learning anything other that can be helpful for game development, would you suggest anything?

Please also tell me that is it a nice idea of learning C++ and then starting game development.

How do you eat an elephant? One bite at a time.

First, learn how to properly code in C++.  This can be done by reading "The C++ Programming Language 4th edition" by Bjarne Stroustrup (The creator of C++) and coding at the same time; that is, while you read the book.  The key word here is "properly", though.  The following is a very accurate quote about C++: "In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg."  Improper use of the "new" keyword in C++ can lead to big problems.
This one actually got me, since I had a Java background prior to learning C++.

Second, learn about game development.  This will involve learning about how to build physics engines and collision detection systems (using spatial data structures).  A little bit of knowledge on vector calculus can go a long way when developing a physics engine.  You will also need to learn computer graphics.  You can buy a book on OpenGL, which is a graphics library that you can use in C++.

C++ may be a bit difficult for a first exposure of programming. I suggest starting with a java course, which is traditionally used as an entry-level programming language. Additionally, you could sign up for a web dev class that includes HTML, CSS3, and JavaScript. HTML is simple to learn and can help you become familiar with the world of coding.


Thoughts on language for Intro to Data Science? Next term, I'm going to teach an introductory Data Science class for the first time. In the past, others have taught it in either R or Python. My first inclination was to teach it in R because the language is specifically for statistics (and not a general programming language like Python). However, I see a lot of promise in Python's Pandas library. I haven't used Pandas myself, but I have more than enough time that I could familiarize myself with it.

What are your thoughts on R vs Python vs a bit of both?

Ultimately, the Data Science curriculum exposes students to both. Which do you think is more appropriate to begin?

Course details:

Prereqs include CS1 (C++) and Statistics
Topics include the analytics life cycle, data integration and
modeling, relational databases and SQL, text processing and sentiment
analysis, and data visualization. Emphasis is placed on reproducible
research, code sharing, version control, and communicating results to
a non-technical audience.
First of two DS classes as part of a DS certificate (Minor is <
Certificate is < Major) with predominantly Comp Sci and Stats majors
enrolled
I am currently teaching the Advanced DS class (the follow-up course)
with a concentration on R, but that could potentially change in the
future as well. Sooner or later, if they complete the certificate, they will get experience in both R and Python. The question is which comes first.
I can choose the textbook, but will give strong preference to free,
online resources

The biggest strength of R when it comes to Data Analysis is in its data visualization. As you've mentioned it is a more or less dedicated tool for statistical analysis.

The thing with Python is that you can easily go a bit off course with the lectures because for Statistical Analysis you'll have to understand, install and work with different libraries/APIs for plotting (matplotlib/pandas/plotly) and processing your data (scipy/pandas again/numpy). These may take different approaches for installing and working with besides being tools on their own.

RStudio already sets up everything for you for the most part so you can just focus on implementation; if you happen to need something extra installing packages from CRAN is incredibly easy letting you do it from the script itself rather than opening a terminal with conda or pip or whatever.

My notes:

If your interest is teaching more Data Science, as a tool in itself, go with R. It will let you focus more on concepts which are general.
If you're interested in teaching General Programming as a tool for Data Science and maybe other things, go with Python.
If you like both ideas, I'd start with R and replicate results with Python later to show its integration with different tools. This way your students will see both approaches are feasible in the case they go out there and see it in the job market.

As for me, Python is the best thing for entering to Data Science. As you see, among Python is a very popular, mainstream general-purpose programming language, it also has an extensive range of purpose-built modules and community support. Many online services provide a Python API.


For a beginner, is it better to start with C or a higher level language? Some friends of mine, over the years, asked me suggestions on what to study for learning how to code. Most of them had no real final purpose, just wanted to be able to understand programming and be able to work with it if needed.

When the asker was a motivated person, I always answered to first learn C, then C++ and finally to pick up an high level language (like Python, R, MATLAB, Swift, JavaScript or whatever then would have been needed). This is the road I followed and I feel that having first learned a low level language (with pointers!) followed by its natural OOP extension, I have now a deeper control on how a generic programming language behave, and I can easily learn any programming language sharing the paradigms of C++.

On the other hand I suggested less motivated person to start with an high level language (Python, R or MATLAB), so to not let them be scared by the pitfalls of C.

Based on your experience, would you give the same suggestion I gave? I mean, do you agree that starting with C/C++ is beneficial for a deep understating of programming or do you think that is easier to start with a simple language and then deepen the knowledge with C/C++?

Based on your history and preferences, you have a particular view about what it means to be a programmer. I have somewhat the same history, but come to a different conclusion. Start with a high level language, probably either a good OOP language (Java, Python, Scala...) or a good functional language (Scheme, Racket, ...). Those two groups of languages cover much, though not all, of the "higher level thinking" in programming today.

Programming Languages are all about abstraction. Different languages offer different kinds of abstractions and different levels of abstraction. However, once you choose a language, the programs that you build within that language are usually (always?) about creating even higher level abstractions than those in the base language. We try to write programs "in the language of the problem we are solving" and choose names (abstractions) accordingly. That is why we don't name our variables v1, v2, etc and our functions f1, f2, etc in our programs. Our variables are things like size and done and function names are like compute_capacity.

Every programmer needs to know something at least of a whole range of abstractions. Assembly language is very low, C is a bit higher. Ruby is quite high, as is Racket. Wherever you start learning you will eventually, after totally grokking that language, want to go to other levels. If you start at a low level then you have only one direction to move, but if you start at a higher level you can move both higher an lower. Thus you can learn how things are represented (at a low level) and how things might be hidden/regularized at a higher level.

Each programming language that you learn is built on a set of ideas that encapsulate what a program should look like. The view of a C program is very different from that of a Java program. The difficulty in moving upwards in the abstraction scale is that it is often difficult to give up the low-level constructs that you have become used to for others that are more appropriate in the new language. For example, polymorphism exists in most languages. In low level languages like C, the polymorphism is ad-hoc, implemented by setting and testing flags. In a higher level language (Java), polymorphism can be implemented more directly using certain design patterns (Strategy/Decorator) and helper objects. But the programs written by those who started low, too often still use only ad-hoc methods, which potentially leads to programs that are difficult to read and understand (too-deep nesting of structures).

You say you can learn any language using the "paradigms of C++". I know a few programmers who can validly say that, but most C++ programmers cannot, outside a fairly narrow range of languages. Moving from C++ to Scheme or Standard ML, for example, requires a completely new way of thinking about programs. Adopting this new way of thinking is actually inhibited by what you learned well in C++. Not that it is impossible, but it is a harder climb.

Let me give an analogy. If you want to become a medical doctor, you don't start by  gathering herbs and chanting ancient songs. You don't, then, progress to leeches and bloodletting, following an historical trail. It is true, however, that some medical practice is only considered valid because it was handed down from antiquity but actually has no scientific basis. At some point in history, something was tried and it worked. No one knew why, but it became standard practice. But, and the point is, you don't need to start your medical training with ideas from 100 or 1000 years ago, even though many of the things learned then are still valid today. Nor do you need to start your education at a low level.

One misconception that people often have about high level languages is that they can only be understood in terms of some (supposed) implementation in a lower level language. Certainly compilers take this view, but humans don't need to. If a language is minimally useful it will provide a complete set of abstractions that permit you do any computation (Turing complete) solely within that set of abstractions. When I program in Java, I don't need to think about what the compiler will do with a reference  variable (is it a pointer? is it like a pointer? is it completely different?). I just know that it gives me access to an object so that I can send messages to that object. I think in terms of reference and message, not in terms of pointer and function call and don't care if they are similar or distinct. In fact, thinking at the lower level can lead me astray. In a Java program, with overridden methods, it is not possible, in principle, to know which version of a method will be invoked without a complete trace of the program. You may not be able to discern the precise type of an object without that trace, and a distinct execution of the program may take a different path.

Some people think that low level languages are more efficient than high level languages. That may have been true at one time, but isn't necessarily true anymore. If you examine a few statements in a low level language, like C, they certainly seem to be easily implementable on a Von Neumann architecture. The problem is twofold. Programs consist of many many statements and it is easier to write and reason about complex algorithms in a high level language, especially one that is purpose built (bespoke) for that domain. Compilers today can execute tens of millions of instructions to globally optimize programs, something that a low level programmer can't do, and something that low level coding often inhibits. If I write a program describing explicitly how a problem is solved (typical in C), the optimizer is pretty much limited to following that instruction stream (not precisely, I realize, but that isn't global optimization). On the other hand, if a program describes what is to be accomplished rather than how to do it, an optimizer has many more options for coming up with both a high and low level set of strategies for execution.

The second reason that low level programs are only apparently efficient is that modern computers are only barely recognizable as Von Neumann architectures anymore. With multi-level cache (both data and instruction) and multi-processing on (say) graphics processors, the relation between the programmer notations (the program) and what is executed gets farther and farther apart as time goes on.

Summary:

Languages are about abstraction
A decent language will provide a (Turing) complete set of abstractions. Therefore you can think at that level of abstraction.
Lower level language are not, inherently, more efficient than higher level languages, though they may appear so. Compilers can do more than you think if you let them.
A human, moving to a new abstraction level, will have difficulties made more intense the more they are committed to the "old way of thinking".
Start somewhere. For myself (who started low), starting higher gives you a better, clearer path. But you will eventually want to branch out. Learn to think, completely, within the abstractions provided by the language you use. Understand those abstractions in terms of the other abstractions and idioms in that language, rather than by "mentally compiling" everything.

Here is an odd historical note about medicine, that I'm pretty sure doesn't really apply here:

In a few cases it isn't ethical anymore not to use some relatively ancient practice, so science is blocked from advancement in that area. The Pasteur Treatment for rabies is like that. It works, but is a dreadful process for the patient. But rabies is nearly always fatal, so it is unethical to set up a scientific experiment in which the control group gets Pasteur, but the experimental group gets (only) a vaccine.

Define "beginner".  A third grader who want to make a game?  A high school student?  A college grad looking for a new career?  With out knowing that this question is unanswerable.  I teach high school programming.  When someone says "beginner" to me I suggest Kodu, Scratch or Small Basic.  If someone wants to build a game then go for Gamemaker or Unity.  Want to build an app then look at MIT AppInventor.  These are starting points for beginners.


Who should own the intellectual property on a program developed in classes? I am aware of some teachers that own or collaborate with IT companies, so sometimes the assignments that they provide, to the students, are supposed to solve a specific problem that the company may have.

Although I believe that it is always better to solve a real problem, than to use the same old training problems, is this ethical?

I know that, probably, the schools have their own intellectual property rules, but who should be the owner of the code?

Can a teacher use the code freely? Can the student use the code freely? What is your experience on this?

Who should and who does are often different. There are laws and contracts to consider as well as "common law." In my own view, forcing a faculty member to give up all rights to the intellectual property (IP) that he/she develops is just wrong. However the law is the law. Contracts intervene. A program developed in a class for a client is normally done under contract and the client likely owns everything. But you know this going in.

However, a faculty member can't, morally at least, appropriate a student's work unless contracts are in place. Faculty member should, of course, give proper attribution for anything used and also seek permission if there is something useful to be reused. I don't think it is wise for a professor to assume otherwise.

One possibly useful suggestion is to ask the students at the beginning of a term to agree that code they write is done so under GPL or similar license. But it needs to be agreed to.

In general, though, "if you create it, you own it". That is probably not universal, but widely held.

In situations in which contract or the law do give faculty rights to IP created by students everyone is better served, I think, if the faculty member still respects the more general rights of the student. Just because you can appropriate someone else's work doesn't imply that you should.

On the other hand, if the professor provides the question and guidance in the solution, he/she may have some IP rights to the product.

For what it is worth, companies also appropriate the work of employees, but under contract. That is mostly well justified and needed, but there are some variations on it that are also immoral in my view. Preventing a researcher from ever working on the same problems after employment ends should not be allowed in a contract and such should be struck down. But, then, I'm not a lawyer or judge.

Beyond the narrow question it is possible to think "outside the box." If a faculty member normally publishes work on a website he/she can, with the student's permission, publish a student's work under the student's name. This gives the student some visibility and adds a bit of the professor's reputation to that of the student, providing a boost.

I've also heard of situations in which a student and prof go into business together based on joint work.

The lawyers of most organisations, write the contracts as if they are about property rights, and to protect their own rights. The organisation does not want to loose their own property rights.

However software is not like apples: If I have an apple, and you have an apple, and then we swap apples, then we both have one apple. If I have a program, and you have a program, and we both give each other a copy of the program, then we both have two programs. The programs have not diminished. Therefore to give one person rights we do not have to take them away form another.

Therefore with software there is no need to deprive others, for you to have a right over it. (software/music/etc is not property.)

The best way to do this, and protect the students is to allow the pupil to keep her/his copyright, and only giving copyright to the school, with a clause that they can not re-licence (This only gives the school power to prosecute infringement, but not to abuse their power. The pupil could not be prosecuted, as it is impossible for them to infringe the copyright, as they are a full copyright holder. You will need to see a lawyer for advice on this. Or better to talk to the FSF).
And then to use the GPL licence (a copyleft licence). Other licences, including the MIT licences (that are permissive), but especially proprietary licences can abuse the power that the school (or anyone else) has over the students.

This imbalance of power, may also invalidate any contract that you may think you have.

I believe that a permissive licence is just as bad in this situation, as it can use this permission to take advantage;
It would allow the school to create proprietary derivatives, of the pupils work. As the school may be in a better position to sell the software, this may not be fair.

Where as a copyleft licence such as the GPL, makes it much harder to take advantage of the author.

Any work that is licensed under the GPL gives anyone that has a copy of the program the following freedoms:

The freedom to run the program as you wish, for any purpose (freedom 0).
The freedom to study how the program works, and change it so it does your computing as you wish (freedom 1). Access to the source code is a precondition for this.
The freedom to redistribute copies so you can help your neighbor (freedom 2).
The freedom to distribute copies of your modified versions to others (freedom 3). By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this.

However there freedoms are immutable, no one can, legally, distribute it without also giving these freedoms.

\begin{array}{|l|l|l|}
\hline
& Student\  has\ copyright & Student\ does\ not\ have\ copyright \\
\hline
Propratory  & Student\ can\ use,\ modify,\ distribute. & \\
\hline
GPL         & Anyone\ can\ use,\ modify,\ distribute. & Anyone\ can\ use,\ modify,\ distribute. \\
\hline
Permissive& Anyone\ can\ use,\ modify,\ distribute. & Anyone\ can\ use,\ modify,\ distribute. \\
\hline
\end{array}

\begin{array}{|l|l|l|}
\hline
& Student\  has\ copyright & Student\ does\ not\ have\ copyright \\
\hline
Propratory  & Student\ can\ fork\ and\ change\ licence. & \\
\hline
GPL         & Student\ can\ fork\ and\ change\ licence. & \\
\hline
Permissive& Anyone\ can\ fork\ and\ change\ licence. & Anyone\ can\ fork\ and\ change\ licence. \\
\hline
\end{array}


Should I share CS jobs stats at a Girls Who Code session? In an upcoming Girls Who Code session, I was thinking about sharing some stats about computing jobs, and why learning computing gives you an economic advantage, both as a computing professional, and within other fields (CS + X).

When I told others about this plan, they were sketical that the girls would find such stats encouraging.

Is sharing job stats a best practice for reaching out to high school girls? Why or why not?

Here are the three stats I wanted to share:

Computing has more jobs available than degrees granted. Computing has much more job availability than other fields, even other STEM fields. (See graph compiled from [1] and [2])
 6
For every software developer in the world, there is another professional who uses programming in their job, but isn't a software developer [3]. (Some estimate there are actually four more [4])
Workers (not software developers) who program make higher wages than those comparable workers who do not [5].

Expanding my comment and those of others to a full answer seems to make sense now. The short answer is, as Ellen Spertus notes, there is no reason not to, but it isn't enough.

Young people need good, and honest, guidance about what they might expect from their choices. But the future isn't necessarily determined by things we can see at present, so in many ways the best advice to a student is to "be flexible." Their future will be determined both by circumstances and by a series of choices that they make; not just one choice.

Right now, tech salaries are high and job opportunities abound, but a secondary school student's career is years, even decades, away. The world is not likely to look the same over that period of time. In particular, advances in AI may make many software development roles obsolete. At one time, a huge fraction of people in the US were involved in farming. Now it is a tiny fraction. The same is true in manufacturing. While we still have farmers, most farming is managed by giant corporations employing unskilled and low-paid workers. The same could happen in computing. While there will likely always be a need for software development, it might, in the future, be entirely managed by a very small cadre of highly skilled folks.

One of the trends in evolution is specialization. Organisms become more and more specialized to their environment as long as it doesn't change. However, when the environment does change those specialists are normally wiped out and replaced by others better adapted to the new situation. If you know one thing well - better than anyone - you may be well placed in some environment, but if it changes you are lost. However, if, along with specialization, you also foster generalization, you are better prepared for change.

This is why a liberal education which includes some specialization but a lot of generalization is such a good thing. If you can be good at two or more things you are probably better off than if you can only do one thing well. But, even more important is an attitude that your education won't end at some determined age or milestone. If you truly believe that you can and should learn throughout your life, and learn things sufficiently different from what is needed in your profession, you are well placed for most foreseeable futures.

I have an unproven theory, that in the real world, most specialists have a boss (or a boss's boss..) who is a generalist. The one who knows a lot of things and can see the bigger picture is likely better placed to lead than the one who sees the world through a microscope. If you teach, it may well be that the least technical person in your course will end up being the employer of your uber-geeks.

However, those with few resources, have a different problem. While it is great to say Do What You Love, you also need to temper it with Do What You Must, or even Do What You Can. But even if you need to compromise for monetary or familial reasons, the attitude of a lifetime of learning can still benefit the individual. This is, more or less the mantra: Yes I Can.

Also, for those in unfortunate circumstances collective action and mentoring by peers and others is especially needed and especially powerful. If "daddy" is a millionaire you can probably do what you want, but if you come from a more modest background (as I did) you need to gather the resources you can - mostly other people.

On a personal note, I studied Mathematics, but wound up in CS. I might have wound up as an actuary, but it sounded boring. I was meant to do mathematical research, but never really got the chance after I finished my doctorate. Up until about two years before I finished, the job prospects for mathematicians were fantastic. Like CS today, there were lots of jobs and good salaries. But it all fell apart in about a year. When I finished there were no such jobs - none. Several hundred applications resulted in no offers, though I was well respected at the time and wrote a very nice thesis. But I really wanted to teach, and so took a job that I was, in many ways, overqualified for. But it kept me in the profession, even though I had to change fields. I never programmed a computer until after I had a PhD. But I knew how to learn and how to work hard.

What is indisputable is that the ability to code is a career booster for someone in almost any line of work.


How bad is a Computer Science course that doesn't teach Design Patterns? I'm at final year of my graduation in Computer Science in Brazil. The university that I study is one of the best in the country and my passion is for Software Engineering. It disappoints me, in Software Engineering classes, that no Design Patterns are taught at all, my professor only commented about their existence. From my point of view, this is terrible for every student, because the problems in the real world, both in academia and in the industry, can be more easily handled with a good choice of design pattern. So I'm thinking, this can reduce the quality of the course?

There is more to a CS degree than programming and more to programming than Design Patterns. I'm actually an expert in such things and have designed and published a few as a committed member of the patterns community. If I were teaching you programming in some object-oriented language you would certainly learn about and use many such patterns, but you might never hear the names, just the usage as good ways to write programs in a certain set of languages.

However, I have a friend, also in the community, who is well known and has designed many things fundamental to areas of programming languages who doesn't use the standard design patterns you are probably thinking of at all. The reason is that he programs in LISP and CLOS, not Java and C++. His informed opinion about the design patterns is that they are merely corrections for flaws in certain languages, primarily C++. Many of the kinds of things that design patterns accomplish in C++ are done in more natural ways within Common Lisp itself without needing any such mental tricks.

So, it may well be that your curriculum is flawed, but not teaching the patters in the Gang of Four book is not the only indicator. (Some of those authors are friends of mine, in fact).

Moreover, there is more (much more) to CS than programming. Have you learned data structures and algorithms? Have you learned architecture and databases? Have you learned data communications and concurrency? Have you learned to work in teams on large projects? Have you learned to think abstractly and to decompose problems and compose solutions? Those are vitally important too.

I wouldn't worry to much about it. My CS program at Arizona State University (circa 2010) only had Design Patters as an elective class. I knew plenty of people who never took it.

I think this comes down to the difference between "Computer Science" and "Software Engineering".

Computer Science focuses more on the theoretical side of things (algorithms, mathematical models of computing, how operating systems and compilers work, etc). It's stuff you don't directly use very often, but gives you the foundation to do any type computer work you want to do.

Software Engineering, on the other hand, is "how to make stuff". It answers questions of "How do I design the software I'm creating?", "How can teams of programmers best work together?", "How can engineering teams best work with non-engineers?", etc. It's more about the big picture view of how to make software.

CS programs generally don't spend much time on all the engineering stuff. There are so many things to learn about programming and software engineering that there is no way any university program could cover a sizable fraction of it. So they focus on the theory that will help you learn the rest on your own or as you work in industry.

I'll say this much about my experience: Even though I did take the design patterns elective at my school, it was only quick intro. It took years working before I felt like I started to get a handle of why, when, and how to use them well. And I still feel like I have a long way to go.

So as I said, don't worry to much about it. Get yourself a decent reference book, skim through it just to get a feel for what patterns are out there, and then be mindful of them as you go to work as an engineer. You'll figure it out as you go along.


Example for For vs While Loop (in Java) I'm looking for a set of concrete examples that illustrates good use cases of using a for vs a while loop for beginners. I feel that I have a good grasp on teaching them about these loops in the abstract (e.g., definite vs indefinite loops, how we apply those concepts in life), but I would also like to show two (hopefully somewhat contextually related) motivating programming examples - one where a for loop is more appropriate, and one where a while loop is. Obviously either type of loop can be used in either instance, but I would like to prompt students to think more about when to use one versus the other. Coming up with two good examples that are illustrative of this point is eluding me.

To further limit the options available, students only know about console I/O, String/int/double types/variables, conditionals, and while loops. We are using Java.

So, for example, if I wasn't so focused on finding something that beginners could implement, I would show that a good use of a while loop is for a robot that should always be listening for voice input from a user; this is a good use, because we don't know when (i.e., after how many iterations) we will stop listening for voice input. I would then contrast this with a robot parsing through transcriptions of user voice input to identify keywords and respond to them. I've considered trying to translate this into console I/O, but the use of looping to continuously look for console input lends itself somewhat better to do-while loops, which we'll cover next.

I realize my question is likely a rehash of what was asked here, but I wasn't happy with the answers. Answers on that post dealt more about the ordering of topics for teaching loops (e.g., while loops before for loops), or real-world motivating examples (e.g., while I'm not full, continue eating pizza). What I'm looking for is more in line with the later, but I would like to do something that translates well into code.

If I'm interpreting your question correctly you'd like real life examples that translate to code. Maybe something like the following.

You want to drive or ride your bike to the ice-cream shop a few miles away. You don't know how far it is exactly but you will recognize it when you get there (while), VS You want to ride your bike 15 miles out and then return and you have an odometer on the bike (for)
You want to shoot baskets until you have made 100 attempts (for) VS You want to shoot baskets until you have made 50 successful shots (while). Outside the US, substitute free kicks.
You want to write a 15 page paper on looping in Java (for) VS You want to work on your "looping in Java" paper until you are satisfied with the result (while).
You want to boil potatoes until a fork can be easily inserted (while) VS You want to boil potatoes for 11 minutes (for).

To translate these into code you need some imagined functions for the actual activities (void boilPotatoes()).

For some of them it is useful to discuss the empty case: you are already at the ice-cream shop, etc. For others, a discussion of "at least one iteration" might be useful to have.

If you want to include foreach in the game:

You want to polish all of your mom's teacups (foreach) VS You want to polish her ten most valuable teacups (for) VS You want to polish teacups until you run out of polish (while).

So we know that we can use for and while, for all loops, but here are some simple rule as to when to use which one, to make programs easier to read, and understand.

If you can, use foreach: If iterating over a list (or other iterable type).
Note python calls foreach for. foreach can not always be used, but is much safer and easier to use, when iterating over things.

For experts, if you don't have foreach, then use for for bounded loops, that is those that could be implemented with a foreach, those that you know how many times you will loop (or the upper bound, in the case when you will break out early).

e.g.

foreach item in list {
    process item
}

for (TypeOfItem item : list) {
    process item
}

However for beginners for loops, can be very confusing (I am not discussing foreach, or for in python). Therefore prefer while loops over for loops. But foreach loops over while.

See image from LearnableProgramming — Bret Victor, showing program flow through a for loop.

In C like languages (C, C++, Java, C#, …), always use for in the form for(int i=0; i<n; i++) (there may be some exceptions, but rare). So you are using for to construct a foreach, as the language does not have the higher level structure. (C# has foreach; C++ has library implementations; Java has foreach, but uses keyword for)


How to teach beginning students how to find and fix syntax errors? Our college has a course entitled "Introduction To Programming", although I often tell the students that the real title should be "Introduction to Programming... for non-majors... who have never programmed before" (some people will take this course, decide they like it, and go on to major in Computer Science / Software Engineering / etc., but there's no expectation that any particular student will do so).

Given that there's no expectation of prior programming knowledge, we spend some time (in class, on homework assignments, etc) teaching students how to find and fix syntax errors in programs (both theirs, and instructor-provided programs).  (We're using traditional, textual programming languages like Java / JavaScript, and NOT visual languages like Blockly, etc)

My question: What techniques, exercises, approaches (etc) have you used to help students learn to deal with syntax errors?  What are the pros & cons of your approach?

I would start by showing them a few natural language examples, where changing one letter in a sentence completely changes the meaning, perhaps into nonsense.  Most computer languages respond similarly to almost any syntax change.

Then show students program lines with correct and incorrect syntax (of typical mistakes, perhaps taken from previous sessions of the same course), and the corresponding error message(s), and/or incorrect/unanticipated run results.  Quiz questions to test this might be, given a line of incorrect syntax, what is the corresponding error message (or bogus result) and a possible correction.

The important idea is to help students form a mental connection between changes in syntax and changes in (IDE/compiler/interpreter/runtime/etc.) behavior.

I have not done Java, but I will draw from my experience teaching C #, jQuery and an entire collection of platforms I have worked on.

Rely on intellisense. Lot of students, for reasons that defy logic, don't trust the intelligence. Me though, I insist my students to wait (it takes a few seconds, sometimes more depending on how fast the machine is) for the intelligence to prompt things. This guideline alone saves a truck load of syntax mistakes.

Intellisense aka Intelligent code completion, for those who came late, is a feature available in most modern IDEs (visual studio, eclipse. Xcode, Android Studio) where, like when you do bing search, the words are automatically prompted for you. Things like reserved words ( for example int, main and all that) and function declarations, library names and anything else that is fixed. You use this, you NEVER get a syntax error. Easy peasy.

Dont ignore warnings. Another classic beginner problem. Ignoring warnings. Unless it is really something that is trivial (a declared variable that is not used) I insist on fixing the warning, as that could potentially be a syntax issue, or something that is being used properly.

I would go further, ask them to use the Camel Case (any one of its variations) but since not all will end up developers in your course, perhaps this is not useful.

I emphasise preemptively solving the problem of syntax errors here. If syntax errors have already happened, I guess, you fix them line by line. Alternatively, simply start from scratch, follow the above 2 guidelines is what I tell my students.


Analogy for teaching recursion When teaching recursion, what is the best analogy people use to teach the idea of recursion. There are some nice artistic representations

And the idea of repeatedly cutting a phone book or dictionary in half until you find a number/word (basically binary search). The only problem is students don't use phone books/paper dictionaries anymore and the artistic representation doesn't imply an end goal/state.

The Tower of Hanoi was one of the first ways that I encountered recursion.

"The objective of the puzzle is to move the entire stack to another rod, obeying the following simple rules:

Only one disk can be moved at a time.
Each move consists of taking the upper disk from one of the stacks and placing it on top of another stack i.e. a disk can only be moved if it is the uppermost disk on a stack.
No disk may be placed on top of a smaller disk." (from Wikipedia)

To solve the n disk tower problem:

Solve the n-1 disk tower problem
Move the nth disk
Solve the n-1 disk tower problem again.

Solving the 1 disk problem is trivial.

I can imagine coding this as a nice on-screen or physical computing challenge.

Maybe you can start by showing a clip of Groundhog Day. Explain how his days are constantly in the same loop, and the loop does not end until he "fixes" something.

Which in programming would be considered a base case.


How to prepare students for bias in industry I teach at Mills, a women's college near Silicon Valley with a high number of students of color. We do a great job of preparing students technically -- they do very well on the job market and then in their jobs. What I am unsure of is how to prepare students for the transition from a nurturing, feminist liberal arts environment to industry, which is not only more rough-and-tumble for everyone but can include bias based on sex, race, age, etc., which may cause them to leave the tech industry.

How can I prepare my students to not have their careers derailed by mistreatment in industry? I don't want to just scare them out of the major or make them fearful by mentioning discrimination without providing a solution.

[I asked the question. Even though I don't have the full answer, I want to share what we do, in case it is helpful.]

Role Models

Throughout the entire graduate and undergraduate programs, there are female professors and guest speakers, including women of color. In lecture, I highlight the work of all types of people.

Connecting Students to Support Communities

When surveying students at the beginning of the semesters to get their preferred name, contact information, pronouns, etc., I ask them to optionally provide demographic information that can help me match them with conferences and special programs for which they are eligible.

We encourage students to attend the Grace Hopper Celebration of Women in Computing, the ACM Richard Tapia Celebration of Diversity in Computing, Lesbians Who Tech summits, AlterConf, etc., and we subsidize their attendance. In some cases, faculty attend with them.

Fighting the Impostor Syndrome

I educate students about the Impostor Syndrome, repeatedly. I tell them that it is normal to feel overwhelmed and incompetent at times. It does not mean they don't belong in CS; it means they're being challenged. When I correct students' mistakes, I let them know that I've made the mistake too.

Direct Discussion

When an event is in the news and on students' minds, such as the publication Susan Fowler's essay about Uber, I mention it in class and provide context. (On the negative side, her experience was awful. On the positive side, people are listening to her, which would not have been the case in the past.)

In the capstone course this spring, I assigned students the following readings (which, in hindsight, were overwhelming):

Why is Silicon Valley So Awful to Women? by Liza Mundy, The Atlantic
Monthly, April 2017.
Reflecting On One Very, Very Strange Year at Uber by Susan J. Fowler, February 19, 2017.
Silicon Valley's not-so-secret bias: Ageism by Jon Swartz, USA Today, September 15, 2016.
Squarespace staffer claims exec told them "you’re so black, you blend into the chair" by Rob Beschizza, March 15, 2016.
Woman in Tech Tweets About Sexist Dudes in Tech. Dude Gets Fired. Internet Meltdown Ensues by Lindy West, Jezebel, March 21, 2013. [I chose this article for the summary of events, not the subsequent analysis. I told students they could stop reading after Richards' firing.]
Ask For A Raise? Most Women Hesitate
by Jennifer Ludden, All Things Considered, February 8, 2011.

I asked them to write a one-page essay with their reactions to the readings and suggested the following optional questions:

Are you concerned about your work environment after Mills?
Have
people ever told you it will be easier or harder for you to get hired
because of your sex, race, age, or other non-work-related
characteristic? Do you think they are right?
Why do you think people
sometimes stay so long in bad work situations?
Have you or anyone you
cared about experienced mistreatment in the workplace? Was it
remedied?
Have you ever negotiated a job offer or raise? How did you
feel about your experience?
Are there other articles on these topics
that you've read and would recommend? If so, cite and summarize them.

Their answers allowed me to discuss their specific concerns with them individually and in class. For example, some women of color worried that they would be given jobs for which they were not qualified, either directly from companies or through special programs targeting minorities. I let them know that I (a white woman from an upper-class background) got my first programming job through family connections: I was qualified for it, but there's no way I would have been considered (fresh out of high school) without connections. If their families lack connections (which is overwhelmingly the case for my students), they should take advantage of other ways to get a foot in the door, paying it forward later.

Alumnae Examples

On the day we discussed the above readings, a recent graduate came to speak about her job and how she successfully advocated for herself, such as not letting herself get interrupted and telling people when they attributed to someone else an idea that she had originally suggested.

Pre-coaching for Industry

I advised students that they should maintain a network inside and outside their company, keep their resume up-to-date, and save some of their money (if possible) so they can move if necessary. If a bad situation arises, they should consult their support network for perspective/affirmation, document everything offsite, and not blindly trust HR or management. I let them know they could also come to us any time for advice.

Career Counseling

When students are considering accepting jobs, I steer them to companies with good reputations for their treatment of people like them and where we have alumnae or friends in mid-level or senior positions who can help them. If a student gets an offer from a company I don't know, I use my network (LinkedIn, Systers, etc.) to find out the company's reputation.

Cheap and dirty trick: dress to fit in as much as possible. Nerdy glasses, geeky t-shirts, short-sleeved shirts and other staples of the computer geek uniform show that you belong, and work to diminish the perceived otherness that the average developer/programmer might attribute to those who do not look like them.


Starting open source How can I best get students started with an open source project that they would be interested in and welcomed to? I'd prefer that the project is focused on building a piece of software, perhaps a command line based one. My students are high schoolers and are interested mainly in Python, though they are open to exploring other languages.

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

Since you specifically mention high-schoolers getting started with open source, i have to recommend the Google Code-In. I participated all 4 years as a high-schooler and really learned a lot about open source.

The contest essentially has a dozen or so open-source organizations provide "bite-size" tasks. Each task is mentored, so the students have someone specific to ask questions of. There are both coding tasks and non-coding tasks (documentation, QA, outreach).

The contest itself lasts for only a month and a half (December-January), but the hope is that people get into it and stick around with the open-source projects they contributed to. Many of the grand prize winners do exactly that. See, for example, this blog post by one of the 2014 winners. You can also read my blog post, though i didn't win.

For university students, there is the Google Summer Of Code, which is a similar idea with a rather different format. You must apply to be accepted, and do a single large task, and get paid a stipend.

You might want to look at these two sites, which are specifically designed for getting students involved in open source projects:

http://teachingopensource.org/

http://foss2serve.org


Show students the consequences of their design decisions In my experience, university students spend years writing throw away code. They develop assignments, get them auto-marked, then move on.

On the other hand, professional developers are plagued by the long term consequences of their work and those before them. These subtle flaws only emerge over time.

How could a semester long programming course put students through a more realistic development cycle?

I'm not so sure what you're talking about is a great idea.

Students should be writing a lot of throwaway code, especially at the beginning of their education. They should be learning, writing code to test what they learned, and then moving on to the next thing.

Part of being a student is writing code that, 6 months from now, will look like garabge to them. "Why would I have done it this way?" This is a completely normal thing that everybody feels, and it's a sign that they're learning and improving as developers. But it also means that students shouldn't spend a lot of time polishing their code. Instead, move on to the next thing.

The rest of it comes with experience. Don't worry about "design" so much, and just focus on writing code that works. Forcing students to work with code they wrote weeks or months ago is just punishing them for learning and improving.

I think this is pretty hard to do in a single term and I don't think it is possible early in the curriculum. However, a two term sequence, even if not consecutive, might work out. However, I'm not sure exactly what you mean by "design" here. But here are some possibilities.

If you are a believer in separating design from implementation in a traditional way, then a design course followed by an implementation course might work for you. A language principles course, for example, might have elements of design followed by a compiler building course. Other sorts of projects might work as well.

One design for such a course pairing is to have students do the design of some project in one term and then swap designs for implementation in the subsequent term. These can be team or individual projects, and part of the evaluation done by each team is to discuss the quality of the design they were asked to build. This assumes a stable student population, of course, to be really valuable.

However you need to have a fair grading plan for this to work. Students struggling to build a poor design shouldn't be penalized for decisions made earlier by others. Even when students build their own designs, it should be possible to recover from earlier mistakes. Don't let early errors put students on a path to doom.

If you are willing to drop the word "design" from the question, however, the possibilities expand. "How can we show students the consequences of their early decisions?" This is amenable to any sort of development process, including agile, in which design and development are done by the same people and iteratively. Here the suggestion of user @Keelan can be easily applied. But not likely in a single term. If one course has students building tools of some kind and a later course has the students using those tools themselves, they will learn about earlier bad decisions, either of design or implementation. But, again, make sure the students have a path to success even if they have made early mistakes.

It may be possible to shorten the whole thing to two half-terms, but I doubt that enough could be done to really let the flaws be exposed in such a short time. Bugs, like other things, need a gestation period.

I think that it is a mistake to try to do this early in the curriculum because the students already have enough to do and this might get in the way and leave them discouraged. Esteem building is good to do early. Reality training cam come after a period of "seasoning".


How to stop being The Oracle When I did customer service for an application I was developing, I found that most of the time, if I did NOT answer the phone, the user would figure out their problem and learn more than if I did answer. Some people would just call up any time the slightest thing happened, if I kept answering.

With students, when I am in class and they are working on coding assignments, the same thing can happen: they will ask any old question that pops in to their head because I am sitting 5 feet away (usually trying to grade assignments or prepare to lecture). Sometimes the questions are quite elementary. Other times, it amounts to structuring a complex If-Else or something that they could do, but they have difficulty with. The only 'help' I can give is to explain how it should function. They learn that way, but then I become the Oracle.

I do often deflect questions or look at the problem they are having to know that it is something I have taught and then say I need them to work at it a bit more, but this seems to happen a lot. If I was not there, they would be forced to work it through themselves. Is there a way to encourage the students to be more independent, because I have not found it yet.

Rubber Duck Debugging.

A few years ago we bought a bunch of cheap rubber ducks. Students with questions have two options. They can either ask their neighbor or explain to the duck what they're trying to do. If the duck didn't help, then they can ask me.

I've moved to a different school since then and haven't bought any ducks. I really need to buy some ducks.

It's very simple but it make your students hate you. Ask them to do it on their own, using the materials you provided in class. For each question that they ask you, deduct a point. If they care about their grade, they will try to ask you as few questions as possible or will seek help from each other, both beneficial outcomes.


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

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

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

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

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

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

To paraphrase Dijkstra:

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

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

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

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

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

For example:

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

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

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

"Thing zero"

I have nothing, I have one thing, I have two things...

0,1,2...

0x00, 0x01, 0x02...

0000, 0001, 0010...

There is nothing in my register, there is one thing in my register, there are two things in my register.

There is nothing in my array, there is one thing in my array, there are two things in my array.

If you started at one, you'd always have a minimum of one thing.


How do you encourage students to take criticism of their code constructively? How do you encourage students to benefit from code reviews you give them, rather than being discouraged or responding defensively?

Here a few techniques I use in my class when giving feedback on student code:

Use a rubric. CS50 has a clear grading approach: code is assessed along the four axes of scope, correctness, design, and style. Within style for example, I might focus particularly on readability vis-à-vis indentation. If a student is marked down on this item, she knows exactly what she missed and why she may have lost points. The clearer the criteria of evaluation, the better the student response to being assessed on said criteria. I also think it's valuable to share rubrics in advance. Only seeing it after the fact can make students feel like how they were being graded was being kept a secret, which can lead to resentment of feedback.
Avoid "you" statements. This is something I caught myself doing and tried to correct as the year went on. Let's say I'm reviewing a student's code, and I'm commenting on the naming of variables. I might be tempted to say, "You have unclear variable names here." That frames it as an assessment of the student, not of the code, which does not set the right dynamic. I try to make sure I say something like this now: "Your program has unclear variable names here" or "to improve your code, make your program's variable names more precise." The goal is give feedback on the code, not the coder, so language should reflect that focus. (Side note: with how personally code reviews can be taken, I think how we frame the language of assessment is essential to building proper classroom culture when it comes to grades and feedback.)
Reward revision. This one is possibly more applicable at the high school level, but I think it does matter in terms of building a culture of receptiveness to code review feedback. Allowing students to revise their work gave me the ability to see students improve their work based on my commentary. In my mind this is what education is all about: inspiring a continual learning process. The pragmatics will vary from context to context, but requiring some sort of revision or reflection or allowing students to "recover" some/all lost points communicates to them that at the end of the day, you want them to be better programmers. Grades take a backseat to learning. Again, this might make less sense for university students, but in my class this approach goes a long way in terms of students constantly working on improving their craft.

To borrow from Agile practice, you can adapt a form of the
 Prime Directive.

Always lead with it before looking at the product/code/process. It can feel repetitive, and even elementary. So it helps to
rotate the reader of the quote, and open it to team discussion with new members.

Its value grew and became more appreciated every time a retrospective
revolved around a significant incident/bug/crisis. It gets the team
past blame, toward the mindset of self-improvement. Before learning the prime directive, I experienced the blame aspect of code reviews consistently.

Edit:
Adding the quote here:

  Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand.

The purpose as I understand it is to

Create a Safe Zone. Nothing leaves the room. Eliminate fear.
Treat the code as a product of the team, not one engineer.
Action not attitude. Focus team energy on productive analysis and improvement

Feedback

As mentioned by Ben-I. In a lot of ways, code reviews are feedback (to the team). In feedback, there is an opening to achieve alignment.
 Thanks for the Feedback p.232, Stone&Heen

  The opening is important because it sets the conversation's tone and trajectory.

and further

  You're not telling the feedback giver what they can or can't say; you're working to clarify the mutual purpose of the conversation and suggesting a two-way exploration. This helps you get aligned for the rest of the conversation.

Also in feedback, both giving/receiving benefit from practice. In the same way it helps improve your speech delivery, Toastmasters utilize a Evaluator role to practice judging speakers. Have students practice giving, and performing code reviews.


The confusing Unix permissions terminology The GNU manpage (what you'll find on a Linux system) – but pretty much any Unix manpage – of chown (the command for changing the owning user and owning group in Unix) appeal to an “owner” and, as you see, the very name of this command hints at  “change owner”, too.

When people first learn this, they get the wrong idea, that for the command chmod (which sets the file/directory permissions), the abbreviation o (as in chmod o+w file) stands for “owner / owning user”.

In reality it stands for “other users”. So chmod o+w file really adds the writing permission (+w) for other users (who are not the owner or a member of the owning group). It doesn't help that what really refers to the “owner”, namely u (= owning user), makes it possible for one confusion to give rise to another: u is then confused for “‘normal’ users”: anybody not the owner or in the owning group.

Sure, it helps to make people directly aware of this, but even if they can remind themselves that there's some trap here, the idea o = “owner”, u = “normal users” is so seductive, that they retain some insecurity until enough (sometimes a lot is necessary) rote memorization makes it finally sink in.

What would be a mnemonic or other way to explain it which makes the correct notion stick right from the start, so rote memorization isn't necessary?

PS: I'm not formally teaching anyone, it's just what I want to tell coworkers/friends. When I took a university course on Linux I first came across this confusion. There's a lot more about the Unix permission system which is very counter-intuitive, but those are issues arising necessarily from technical aspects. Not an (surprisingly very) annoying and trivial issue caused by bad historical choices for abbreviations.

You could point out that a file has an owning user and an owning group. Since “owner” appears twice, specifying o for “owner” would be ambiguous. That's weak because the owning group doesn't really have any special privileges on the file, unlike the owning user: the owning user can change the file's permissions and other metadata, but the owning group only has the privileges granted by the file's permissions.

I think the best approach is to pair up user and group so that people remember them together. There's user and group: u and g. There are basic file permissions for one user and for one group. ACL entries can apply to either a user or a group. The command ls -l has two columns for ownership, one with the user and one with the group. Beware that sometimes the naming is not consistent. On the system there's a user database (/etc/passwd) and a group database (/etc/group). The chown command takes both a user and a group, but there's also a separate chgrp command and so chown is often used for the user only, which tends to reinforce the association between “user” and “owner”, so avoid mentioning that if you're trying to dispel the association between “user” and “owner”.

UNIX has three rings of security ... There are three levels of permission ... and there's chown, chgrp, and chmod. That's all that anyone needs to remember, and all that anyone should ever be tested on. The rest is easily recovered via man chmod.  I have been a professional developer on mostly Unix / Linux since 1978, and I still don't remember the full syntax of chmod arguments.


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.

Note: This answer specifically applies to programming-based assignments.

I'm a student, and I'd just like to add my opinion here. We're taught programming in school using Turbo C++. Yeah. That ancient compiler which hasn't been updated in decades.

Needless to say, when we search for help and find samples of code on the internet, most of the code doesn't even compile.

And to add to that, our teachers... Aren't always able to teach very well, due to time constraints or whatever.

I happen to be one of the the best students in class, and often my classmates will ask me to help them out. Whenever possible I'll take a look at their code and point out mistakes, but that's tough to do with a few dozen students in the class.

So sometimes I'll leave my code up and let the students take reference from it, but ask them to write the code themselves. Sure, there are a few kids who just straight up copy it, but I feel that the number of students benefiting learning from it outweighs that.


Why is computer science hard? Data pretty regularly shows that computer science programs have among the highest failure and dropout rates of any college program. A number of sources all echo the finding that roughly one-third of incoming CS majors do not progress to a second year, higher than most other majors.

Computer science undergraduates most likely to drop out (ComputerWeekly.com, 2019)
Concern over drop-out rates in computer science courses (The Irish Times, 2016)
Why are computer science drop-out rates so high? (Trinity News, 2016)

I teach computer science majors at a U.S. community college, and the non-passing rates are even higher in this context. A few times in my introductory programming course, I will mention this fact (that computer science is among the hardest majors), partly to set expectations that students will need to work hard to succeed.
This semester I had a student in my virtual office hour ask, "Why is computer science harder than other majors, as you say?", and I was a bit flat-footed for a good response.
So: What would be the best reply to a beginning CS student who asks, "Why is CS hard?"

The difficulty of CS (true or imagined) and the drop out rates are not the same thing. Let me start an answer, but it might take several iterations to get all my thoughts together on the two ideas.
Two themes come immediately to mind.
The first is periodic and I don't know where we are in the period at the moment. But in certain combinations of economic factors and media hype, a lot of students go in to CS not really understanding what they are getting in to but are lured by the, perhaps elusive, draw of big salaries. There is a lot of hype out there about AI at the moment, and self driving cars, and going to Mars, etc. People get in for the wrong reasons and decide they really didn't understand what it was and that they don't really like it. It doesn't need to be hard to drive people away, just boring.
The second major theme is that there is a lot of bad teaching around CS as has always been the case. Some people teach it as misspelled mathematics, which it is not. Some people in elementary and secondary schools are forced to teaching CS and especially Advanced Placement CS when they have little understanding of the topic and just try to stay "one week ahead" of the students. This is, and has always been a recipe for disaster. I don't blame the teachers who have to do this as many are forced in to it (in the US) simply because schools are underfunded and understaffed with too few specialist teachers.
WRT the second theme, it might even be that the current push to teach "CS" in elementary schools is actually part of the problem, not the solution. A serious college level course in CS might be shocking to someone who has only dabbled in trivial elements of programming. In particular CS is NOT programming, though skill in programming is needed.
Too many beginning students and teachers think that programming is "if" and "while" and "assignment" and nothing else. The current AP curriculum, I think, is seriously flawed (dropping interfaces, in particular). Students program in "rich" languages and environments using only the lowest level concepts, never really understanding abstraction or (gasp) polymorphism. Compare that with big ideas that you find in a philosophy or (hopefully) history course.
And if you combine that with asking them to write programs that they find boring, they aren't likely to stick around for long.

I don’t see anyone mentioning the fact that programming ≠ computer science.  These are two entirely different disciplines, and it seems to me that there isn’t enough emphasis on this fact.
Take a look at Stanford’s CS 101 https://online.stanford.edu/courses/soe-ycscs101-sp-computer-science-101 and the list of topics covered.  Not a single one has anything to do with computer science.  Compare those topics to https://en.wikipedia.org/wiki/List_of_unsolved_problems_in_computer_science, and try to figure out how those topics even get you started on the path to figuring out how you might even frame those questions, let along solve them.
Computer science is hard because it’s a branch of symbolic logic and logic is hard.


relationship between ACM curriculum guidelines from 2013 and computing curricula 2020 I have been working with the ACM Curriculum Guidelines for proposing courses and topics related to CS in the Faculty that I am currently working on. The core document that we have been using was the ACM Computing Curricular Guidelines from 2013. At the beginning of this year, it emerged the ACM Computing Curricula 2020, which I believe is an improvement over the original document from ACM circa 2005, which defined the guidelines of CS-related careers. The document can be found on:
https://cc2020.nsparc.msstate.edu/
Here I have some doubts about this initial draft. I have seen that (in my personal opinion) it is a little bit awkward. It mentions the different "flavors" of CS worldwide, and then it shows some tools that could be used to measure to see how much CS one career has, even though it does not mention where and how to use these tools. The nice thing about this document is that it contains a set of competencies that should be attained from each undergraduate CS-related field, which, by the way, vaguely reminds me of the ABET competencies system. However, I miss the style of the Curriculum Guidelines of 2013; in which there were recommendations on how to distribute the Body of Knowledge into different Knowledge Areas. Also, even it gave a summary of the recommended topics in each Tier (core or elective).
In summary, I would like to know if one should use this document of 2020 in conjunction with the document that appeared in 2013. Maybe is that ACM will develop another document as an upgrade to the 2013 curriculum guidelines? Any comments or suggestions on how to use this new ACM CS 2020 guidelines?
Thanks

Actually, since it is a draft report, you have an opportunity to influence the final version. Contact one or both of the Co-chairs. They can also give you some more information on their thinking. I'm not personally involved in this, but know several of the participants. They are likely to be helpful.