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++.


Is it bad to force my students not to return early? A fellow teacher of mine is teaching "basic algorithms" course in high school, and we have quite conflicting opinions when it comes to returning from functions.

She restricts return only to the end of the function, and permits no other way to escape functions. No block guards, too, and no breaking loops using return.

To be clear, the approach she teaches her student with is "Single Entry, Single Exit", when the exit is at the function's end and does not break a loop (instead she prefers using flags, even though sometimes in my opinion it makes the code messier).

In contrast, I prefer teaching my students the option to return early and how it affects their code and flow, and let them decide by themselves what they think is right to do. The criteria guidelines I usually teach are:

Do you return early because of your functions logic, or because you were given an exceptional parameter/erroneous parameter? If we're talking about the latter, it is ok to return.
Are you able to avoid returning in the middle without the cost of changing your whole control flow? If not, it is ok to return.
Will avoiding returning early add unnecessary nesting levels to the function? If so, it is ok to return.

Is it a wrong approach, giving your students the choice? Or is it wrong to force them never to return early?

Edit the answers suggested some very interesting difference between many languages. We are teaching C#, which is a high level language, so I wasn't considering jmps of assembly or lower level C's deallocation of resources.

Actually returning early should be the norm. Return as soon as you can. There are at least two reasons for this, of which the first, efficiency, is the least important. But if you return early then needless statements won't be executed. Nor will you need to devise some special code to get to the end just so that you can return.

However, the biggest and most important reason for returning early is that the programmer can put a limit on what she/he needs to retain mentally about the state of the computation. This is especially helpful in a sequential if situation. There is actually an Elementary Pattern about this ("Return, not else") that says that if you know what should be returned at the end of an if block, don't use an else, but instead end the block with the return. The reader/writer/updater then gets to ignore the previous state and start over in their thinking process.

If you return only at the end, say "return result;" then you have to track all changes to result that might occur anywhere in the function/method. You have to understand it "as a whole" rather than incrementally. But the reading itself is normally sequential and incremental.

Of course if you always write three statement methods, this won't occur, but few have the discipline to really do that. Sadly, some programmers can't understand their own code when it contains very many nested structures and tests.

I'll also note that this is somewhat related to the idea that we generally try to avoid global variables in programming. Too much extraneous information can impinge on understanding. Being able to comprehend a program "one block at a time" without reference to others, even containing blocks, is a big advantage.

Caveat. Of course, the code should be as clear as possible. If returning late makes it clearer, I wouldn't forbid it. But I think that is seldom the case. Forbidding early returns, however, is counterproductive.


How to respond when students ask "is recursion good practice"? Context: CS1-style, intro programming class, using an interpreted language (Python).

I will get a hand raised asking "Why are we learning recursion? Is it good programming practice?"

My response is typically:

We are learning recursion since reducing problems into smaller problems is a key skill, and recursion is just an example of reducing a problem to a self-similar smaller problem.
Also, no, recursion not universally better design. Often, calling functions repeatedly like this wastes space on the stack and the implementation can be much less efficient. Our recursive formulation of factorial for example, is a terrible design. Unless you know the recursion depth is bound by something small (think: logarithmic) and resultant implementation is much simpler, then its not worth it.

Students seem deflated with that response. Why learn something that is not very practical, or is often inefficient? Why learn something that is 'sometimes simpler' when (to them) it seems actually like a counter-intuitive design?

My question(s): how do I get students excited about recursion? How do I better motivate studying recursion? Can I better / more naturally express those conditions under which (or those languages for which) recursion is not a poor design choice?

This is challenging once you accept that CS1 students likely: know nothing about functional languages, where recursion is more natural; don't know anything about side-effect free design or mathematical proofs of correctness; are not using recursive data structures yet; etc. It feels like the 'benefits' of recursion are hard to express to a CS0/CS1 audience.

Quite honestly, I would be upfront with them about the debate. Send them to a couple other SE threads:

Efficiency: recursion vs loop
“Necessary” Uses of Recursion in Imperative Languages
Are functional languages better at recursion?

This now becomes a teachable moment on a number of levels: imperative v. functional languages, recursion v. iteration, "expense" of function calls on the stack. Students appreciate being shown the messy truth behind topics that are sometimes treated reductively and simplistically. Let them wade in the mire and see what they think about these debates. Have them analyze the arguments they mind on here; now they are thinking on much higher, more sophisticated level about program design.

The key line that I take away from all of these is this one: "You almost never use recursion for performance reasons. you use recursion to make the problem more simple" (top answer to the first post I linked to). It's often times an exercise in thinking more so than programming.

From a pragmatic perspective, discuss use cases for something like merge sort and quicksort (recursive) v. bubble sort (iterative). Throw in traversing tree structures as well. There is a time and a place for thinking recursively. Iteration is not always the best choice to make.

Last, from an aesthetic perspective, based on my time studying SML, there is a beauty, an elegance, an aesthetic to a well-written recursive function. It's clean, clear, easy-to-understand. If part of code quality is its readability, then recursion has an aesthetic quality to it that a for-loop arguably does not.


On studying Computer Science vs. Software Engineering to become a proficient coder I’m mostly interested in the coding aspect of the CS and SE majors curricula. And I’m trying to decide between the two.

Each major has its pros and cons, and they prepare you in very different ways for a career in coding.

Computer science courses that are provided at my local university range from parallel programming to algorithm design. There's also computer organization/architecture and web programming.

It is to my understanding that (some of) these are exclusive to CS.

I know this post might attract subjective opinions but I'm not looking for answers that simply fill in the blanks. Instead I hope for a final answer where perhaps one major is preferred to the other. Is a question of this nature feasible?

You can find a fair amount of information about accredited programs in the US here, including links to schools that have one or the other programs.

In general, Software Engineering is more directed at the processes involved in creating software, and Computer Science is more generally focused on the underlying theory.

But, I'd suggest that both programs have a focus beyond just programming. In fact, you don't need any formal education to be a programmer, so either sort of program will help you develop programming skills. But that isn't the actual main focus of either. For example, an individual programmer may have little need to know about large scale software process so long as they can do their part in the larger scheme of things. He or she may be able to build things while having little understanding of the theory.

I'll also say that a "career" as a coder isn't going to be especially rewarding, either in pay or in responsibility. Many people start out there, but it is much more important, in any field, to know what should be built rather than how to build things. A degree program will give you some insight into the more important problem (though more is needed). But an entry level job after a degree may require programming but if it is the end point then your education was really wasted.

I, myself, sometimes do a lot of coding, but it is never the main thing. It is just a tool that can be used for the realization of something important. Focus on that last part, not the actual coding.

Note that Tim Cook of Apple has recently said that you don't need a degree to be a coder. Actually, though, he meant more than just "coder".


How do I explain blockchain using an analogy? One of the next big thing that will get people interested are block-chain based technology. Many people are asking about "WTH is blockchain" and it seems that this will be asked quite a lot in coming days, both from CS and non-CS folks.

Now, I love explaining particulars using an analogy. Is there some analogy that I could use to eli5 to non-CS folks that are curious?

(Really appreciate answers, as I will simply link to this question for people asking about blockchains)

Use a classroom activity, then present that as the analogy.

An old campfire activity, for those that remember it. A growing story that nobody knows the end of, or even if it will end.

The objective is to create a story, with everyone adding their parts, in turn. Someone starts the story by saying a few lines, and ending mid-sentence, just before some action happens. The next person repeats what the first persons said, and has to finish that sentence with something that makes sense, and then continues the story, using their own idea, since they don't know what the first person was thinking. Like the first person, the second stops mid-sentence in what they're saying. The third person repeats everything the second said (which includes what the first one said), and finishes the sentence left incomplete by the second. Adding more lines to the story, this person also ends mid-sentence. It continues in a similar fashion with each person repeating the whole story from the beginning, adding a couple lines, and ending mid-sentence. At some point the "next" person will not be able to repeat, even in their own words, the story so far, and the chain fails, hence ending. If it happens to be too short, or if not every student has had the opportunity to participate, a new story may be started, and try again. Once everyone has had a chance to participate, in as many rounds as you deem appropriate, you can pick up the chain and finish the sentence, and the story, bringing it to a successful completion.

After the story, or stories, have run their course, you can relate the process to a blockchain. Each piece (except the first) depends upon the preceding piece, and is meaningless without it. If, at any point, someone in the chain doesn't hold up their part of the "contract," by completing the previous sentence, the story is ruined. Still, even without an end, everything up to the last incomplete sentence remains valid, and can be traced back to the original piece.

This is totally non-technical, so it will not be of value in discussing blockchain implementations. It will, however, be memorable, and the students should be able to grasp the concepts behind a blockchain implementation when you do present it.


(FOSS) Application to show/explain compilation? I'm looking for an application that I can compile live, in class to show the students that compilation takes time, but brings speed benefits in the end, whereas interpreted languages always take time, but need no compiling.

Of course I can just simply compile and run some hello world (e.g. this FORTRAN version), but that would just zip through in microseconds, whereas compiling, say, Firefox would take forever, involve many confusing additional steps and be way too complicated to illustrate the point (and probably fail anyways).

Ideally, I'm looking for an application that takes a minute to 3 (on a tad older hardware, think 5 years old i5) to compile, and really just takes one gfortran -o hello hello.f90 like command to get started and results in a binary that I can run in terminal that produces some simple and easily visible result (A plot? Some calculator?).

I'd prefer fortran or C and it all should be happening on a Linux system.

The point of that application would not be to show anything in fortran or C, or to detail the intricacies of compiling, it's solely to show that this can take time, but generally is fast afterwards. I intend to maybe talk 5 minutes about the whole thing, about 3 of which, it'll compile in the background. The main subject of the course is teaching python, an interpreted language.

One crazy suggestion, install Python from source. Configure time about 42 sec. and compile time either around 3 minutes, or 48 sec with make -j.

Your class will be using Python anyway, and seeing how long it takes to build from C vs. how long it takes to run Hello World in Python ought to begin to give them some appreciation of the differences.

Otherwise, two options that I'd considered are one with a relative fast compile and the other with a longer compile.

Fast compile - C source

The option for a fast, but watchable, compile is curl, which is probably already on the system. curl is written in C. It is available on GitHub. curl is released under its own license which is similar to MIT/X, but not identical. If curl is on the system already you can perform the configure and make commands, and then stop. The students will be able to see what goes into the process of compiling it, and you won't have to modify your system with the actual install. The original install of curl can be used to show what it does. Of course, once you demonstrate the speed of the binary it's nice to have a flashy result. As curl does not require the returned file to be rendered in a browser, you could have a simple ASCII-art file to download. Hosted on the same computer, and using the 127.0.0.1 IP would, of course, be the fastest, and best show of the difference between compile and run times. A simple demo of what could be downloaded could be "HELLO CLASS". curl https://www.gypsyspellweaver.work/hello_class or from the Gist,

My expirements, using an AMD FX 8300 8-core CPU, gives configure times in the one minute range and compile times in the one minute range. In both cases there shouldn't be the need to add any switches or options, and while speaking you won't have to think about what options was I supposed to use? for the commands. Timing your delivery around the process should be reasonably simple, and the process is fast enough to not become boring for the students to observe.

Slow compile - FORTRAN source

There is a project for physics (good place to look for FORTRAN programs) called Octopus for doing virtual experiments. Octopus is released under the GPL ver 2 license, and contains external libraries licensed under a variety of other OpenSource license. The current list of licenses can be found in the GitLab repository. The program does have some dependencies, all of which were easily found in my SUSE repositories for simple installation.

Again, using my system, I found the ./configure command to be quite fast, typically under 30 sec. The compile time, however, was much longer, avg. of 8 min. Use of the -j flag on make was significant in this case, avg. of 3 minutes to compile. As in the curl case, there's no need of switches or options (unless you want to use the -j swwitch on make for the time savings.

Octopus dependencies

The non-optional dependencies listed on the installation page are:

cpp (should be there already)
Perl (should be there already)
Libxc
FFTW
LAPACK & BLAS
GSL

Since SUSE had these in their repos, I'm guessing they're likely in the repos of other major repos. Just be sure that the development packages, -devel or -dev, are installed as those include the headers needed to build other programs, such as Octopus.

In the case of Octopus I have no real idea what would make a fast, and simple, output for the maiden launch of the program. Their website gives a simple run to use. It involves creating an input file, always named imp, in the current directory and running octopus. The simple input file is:

CalculationMode = gs

%Coordinates
 'H' | 0 | 0 | 0
%

Using that example, the best I can create for a demo is to trap the output to a log file, then display the convergence result data. octopus >&log; cat static/convergence. Using my system as a reference, the typical run time is between 1.000s and 1.025s. Changing the command to octopus >&log; octopus >&log; cat static/convergence so that the command runs twice, using the results of the first run to fine-tune the results of the second run, adds approx. .650s to each run. The output of the single run is a table of 9 results and the double run produces a table of one result.

As a final resource, if none of these ideas work for your situation, or instructional style, you could look through the list of programs, organized by language, on dmoz. Surely something there will work for your presentation.


Do I need Prolog to teach logic concepts? I think that the use of some logic programing language like Prolog, for example, could be a good way to explain the symbolic/mathematical logic concepts but also apply this concepts in a real programming world, however, but I'm not getting it.

The problem is that Prolog are not largely used in real applications. I tried to use this IBM's NLP as an example, but this pattern matching exercise does not covers much concepts from mathematical logic.

The question is: How can I use programming to instruct students in topics related to symbolic/mathematical logic?

Logic is a tool for distinguishing true and false statements. If a statement is proved, then it is true. If its negation is proved, then it is false. Hence the core skill is checking whether a proof is correct and finding/inventing a proof of a statement.

Prolog is based on a subset of logic. A Prolog implementation finds proofs automatically. IMHO, anybody should learn how to find proofs by hand and have a bit of practice before using any automatic prover. Prolog is so weak that it can't find even simple theorems that are of interest, like theorems of Peano's Arithmetic. Moderately complex statements, like the axiom of induction, can't even be expressed in Prolog. No wonder that

  I tried to use this IBM's NLP as an example, but this pattern matching
  exercise does not covers much concepts from mathematical logic.

Prolog surely is an example application of logic, but it is too weak to show what mathematical logic is. A proof assistant is a better way. Prolog is not the only application of logic. Other options are reasoning about programs, hardware, and computer systems, proof assistants and provers, and Artificial Intelligence.


Good resource for practice problems for inductive proofs Every year, I teach my students about using induction to prove that algorithms function as intended.  My purpose, in instructing them, is to help them master the structure of the proof itself.  I use simple algorithms for which we can do fairly easy inductive proofs.  Here are a few examples:

Prove that arraySum will correctly compute the sum of all of the elements in arr.

public int arraySum(int[] arr){
    int k = 0;
    for (int g = 0; g < arr.length; g++)
        k = k + arr[g];
    return k;
}

Prove that this function will return $n^2$:  Assume n is positive.

public int square(int n){
    int sum = 0;
    int count = 0;
    while (count < n){
        sum = sum + n;
        count = count + 1;
    }
    return sum;
}

As you can see, I am not aiming for complicated algorithms.  What my students need (and what I need) is a good source for practice problems.  I'd absolutely love it if they were already carefully solved (so that my students could independently study with them and check their own answers), but I could work with any source that simply has a series of pre-made reasonable practice problems.

Is there any such resource out there?

Any book on elementary number theory will likely have quite a few recurrences as examples and in the exercises of the early chapters. For example, the sum of the first n odd integers is $n^2$. As a recurrence this is just $n^2$ = $(n-1)^2$ + $2*n - 1$. Or possibly it will be shown as $a_n$ = $a_{n-1}$ + $2*n -1$, with $a_1$ = 1.

Some books on discrete math have many of these as well. Some even have these in summation form, rather than as recurrences.

Likewise the sum of the first n integers (start counting with 1) is $n(n+1)/2$.

From these recurrences or sums you can develop a program to give the students or have the students prove the relations and then develop the program themselves.

Even a web search for recurrence relation turns up some ideas.

A rather important sum (the geometric sum) is this: Let r be a real number and k a non-negative integer. If $r \neq 0$ then $\sum_{n=0}^k(r^n)$ = $(1 - r^{k+1})/(1-r)$.

Moreover, if $|r| < 1$ then as k increases this sum approaches 1 - r  which leads to an infinite sum that is pretty comprehensible.

Also David Gries' The Science of Programming has interesting examples that he shows along with how to develop programs from pre and post conditions. The book has been mentioned in answers to other questions here also.


Dataset colection of weighted graphs I hope I'm addressing the right community. I was redirected here from CS.SE. For a project for my students, I need to find some weighted graphs (oriented or not) to benchmark their algorithms (shortest paths, flows...). The idea is for them (and me) :

to test their code on small examples (running code with the processor they have between the ears ;-), but not completely trivial,
to test their code on a bunch of larger examples (say from 10 to 10000 nodes) to find the complexity from experience, and compare it with what they would expect from their algorithms.

The algorithms I want them to study :

Dijkstra,
Bellman-Ford,
Floyd-Warshal
Ford-Fullkerson (for the good ones).

There are a few samples on the companion site of the ALGS4 course from R. Sedgewick (Shortest Paths), it could be OK for benchmarking, but I would like some more datas, encoded in this simplest way (or easily convertible). Examples don't have to contain background (I mean, if there is one, it can be interesting, but then I would have to strip the original datas from all the commentaries...).
Maybe someone here is aware of some samples and could point me to it.
Thanks in advance.

For any problems involving graphs for which you need test data you can use Knuth's less well known work 'The Stanford Graph Base'. This includes many data sets designed to test all kinds of graph problems. The materials are described at https://www-cs-faculty.stanford.edu/~knuth/sgb.html and are available for download at ftp://ftp.cs.stanford.edu/pub/sgb/sgb.tar.gz


How do you read and write a project beyond a one-page script? I have hit a plateau in learning to program in that while I know CS concepts and I can read and write a program such as a diminished find clone, I cannot create anything that's spread across multiple files, and making meaningful changes to something already existing requires some comprehension that I at present lack. When I start reading a new project of someone else's in hopes to make changes, the first, hard, step is that I usually literally do not know where to start, as in which source file to read first, especially if it is a language which has nothing like a Main class. I have done some inconsequential projects in Java before requiring multiple classes, thus multiple pages and no obvious start, but these projects were all small enough for me to hold the entire project in my head.
What's the next step? How do I learn to work beyond making one-file scripts with one or two supporting and header files?

For a language like Java, the way out is to pick a project that isn't just the solution of some equation(s) or a similar mathematical problem. Find a project in which the description of the problem can be analyzed as some "thing" that has discernible "parts". The parts can be modeled as classes and the resulting objects composed into a solution.
One that is simple enough is a calculator. A calculator has a display. It has keys that have actions, which vary depending on the "state". For example, the "5" key behaves differently in the case that the previous key was an operator or another numeric key. The answer of Ben I. mentions design patterns. This is an example of the Strategy Pattern.
Most calculators employ a stack or other hidden register beyond the display. Calculators have an operational strategy of operation that differs for an RPN or an algebraic calculator. The precedence of the operators may be important, or not.
The calculator can print out a tape of recent operations, or not. It can have a GUI or not. If it has a GUI then you can build it with MVC or not.
And if you want a real challenge (the Polymorphism Challenge = writing a program with a limited budget for selection statements), it is possible to build such a thing without a single "if" or "while" statement, provided the user gives the key presses. This will give you very low Cyclomatic Complexity, which is a desirable feature of any program.
But it is the "parts" composed into the whole that is the essence of this.

I've purposely not provided pointers to some of the terms here. You can explore them on wikipedia or elsewhere. But the polymorphism challenge search will lead you astray. Look HERE for guidance.

And using JavaDoc consistently is a good habit. If you are extending an existing project then the JavaDocs already (hopefully) in place should be a good guide to the operation.


Introducing image processing - Should I teach the math During the summer I am teaching a programming workshop for students in a high school computer science major. The purpose of the workshop is to introduce them to image processing, and to have them experience using it.

Naturally, an image processing library is necessary (teaching in java, so probably JavaCV, though I might go for python and then just do openCV, but the question isn't about library choice).

These libraries do calculations with relatively advanced mathematics. Things that are aren't taught in the school, nor anything close to the level of math they know (It requires knowledge of matrix multiplication and many other things).
The students are at an advanced level in mathematics (calculus, algebra, vectors and a few other things).

Should I teach the mathematics behind those computations, before teaching the image processing material? I think they can understand the math, if it is taught. Is that knowledge necessary to understanding how those libraries work?

The image processing in question is feature extraction, edge detection etc.

Examples of a mathematical background is how to write an algorithm to compute the determinant of a matrix, or one for matrix multiplication etc.

I would tread lightly here for a few reasons:

The math is not strictly necessary.
The students signed up for an image processing workshop in the context of programming.  The core skill that they expect to come out with is the ability to program graphics manipulations.  Spending a substantial portion of this time learning about the underlying math, certainly important in a full semester's undergraduate or graduate coursework, only moves very slowly towards what they (presumably think) they signed up for.

Some kids get turned off by math.
One of the unstated goals of every course is to both show the value of the field, and hope that the student wants to go on with the material and learn further.  That means that we want them to like it.  Using a voluntary summer workshop to emphasize the more abstract parts of the material may turn many of them away from graphical processing entirely.

So, don't do any math then?
Actually, I would not say that.  I would touch on a some of the underlying mathematics, but briefly, and (because it is a summer workshop) with the simple goal of illustrating that there is important material that isn't too difficult to tackle if they eventually want to go further into the topic.


Setting up a cloud-server SSH login procedure for a class? (AWS) I'm trying to set up a remote cloud Linux server with multiple logins for a class in Linux basics, BASH and C programming. We want our students to be forced to work exclusively in the shell to improve their comfort and skills with terminals - they already have considerable familiarity with IDEs.

To achieve this, I want my students to be able to SSH into a shared server with unique logins. They should then work in their little sandbox and submit their work in specific directories that I will auto-grade from an admin login.

I'm currently trying AWS's basic EC2, but it's unclear if all of the following is possible:

1) Add username/passwords on TOP of a RSA keypairs. It seems clear that I can do unique keypairs OR username/password, but not yet clear if I can do both...

2) How to use just 1 RSA keypair for all student logins, rather than a different keypair for each login (to facilitate quick distribution/set-up, and to control security at-large conveniently)

3) How to let users set their own passwords - ideally initial password is universal, but on day 1 they could personalize.

I'm starting to suspect AWS may not be the best solution for what I'm trying to accomplish. I've looked briefly at CloudSigma's product but am unsure if there is a cloud service that better fits what I'm trying to do.

Has anyone done something similar? I know many universities do essentially this, though usually with their own servers rather than cloud-based ones.

I believe that using one key for access, even with unique passwords, is inadvisable. Teaching moments aside, each student should have their own, revocable, restrict-able, key pair. However, as I understand the intentions, you should be able to achieve your goal this way.

Short answer

Point 1:

Edit the instance's /etc/ssh/sshd_config file and check that these lines are there:

PubkeyAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords no

Then add this line to require the use of both a key and password to access the instance

AuthenticationMethods publickey,password

Point 2:

Create the one key to rule them all with ssh-keygen or gpg
Copy the private key file to each local machine which will access the EC2 instance
Create user accounts for each student on the EC2 instance
For each user account on the instance add the public key to this file:

/home/$USER/.ssh/authorized_keys

Point 3:

At the beginning of the term/course have each student login to their assigned account on the EC2 instance and set a new password.

Explanations

During the provisioning of the EC2 instance, and probably later as well, you have the option of assigning a key for SSH access. The Amazon EC2 console, Network & Security, Key Pairs is the place to handle the key pair for your access to the EC2 instance. There you can have Amazon create the key pair for you, or import a key pair's public key which you have made locally. The default account, created when the EC2 instance is created, and the key pair you create/import for that account to access the EC2 instance, are the equivalent of root on a local machine, sometimes the username is, in fact root on the EC2 instance. That key pair should be shared with the students as often as you share your password with them. (Can anyone say "never"?).

Point 1 - Password and RSA key required to login

The first three lines control what the SSH host (EC2 instance) will accept. PubkeyAuthentication1 has to be yes (the default) or the host will not even accept keys, valid or not. PasswordAuthentication2 defaults to yes, and could be commented out, or even missing, and it would still work. The caveat here is that thigs will go very bad if it is set to no. (Bad, in this case, means destroying the EC2 instance and creating a new one, as the final settings will require a key and a password, yet no here will prevent the SSH host from asking for one.) The PermitEmptyPasswords3 setting of no just stops the students from accessing their account over SSH with an empty password. It will not prevent them from setting their password to a blank one. If they do, they'll have to get the instructor's assistance to reset the password, and maybe learn a lesson in the process. Lastly, the setting AuthenticationMethods4 specifies what methods are required for authentication.

The EC2 instances are supposed to be operationally equivalent to bare-metal Linux installs. (All be it, without the hardware acquisition and maintenance costs.) Treat yours as such. Each student should have their own, regular Linux, account on the EC2 instance, with all the normal restrictions and settings that you would use if it were a server in your lab room. As the owner of the instance, effectively if not actually root, you can access the student user directories and process/validate/censor them as needed.

The process of creating a new user on an EC2 instance is the same as any other Linux install. sudo adduser new_user_name. As I understand it, newly create user accounts on the EC2 instance will not have the needed directory structure for using SSH access. The process for creating it, and adding the public key at the same time, are fairly short.

sudo adduser new_user_name
sudo su - new_user_name
mkdir .ssh
chmod 700 .ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDcsebwlu3jVUJfPunR8aENmxcRQKva00MDi7aiyeSh7cpzQpCFK/gqTRGmqZvI6H/0QImek5JfPkJDgUkPHfhlawHRKrEzsvCeiPzKuMT1UHs5wASqHuxTJrjklJeR/knFxdCZZ4kyYFFomdFKsLTR5VPLK/2H3c6APs4+XPxE2Q== gypsyspellweaver@cseducators.stackexchange.com" > .ssh/authorized_keys
chmod 0600 .ssh/authorized_keys

Where _new_user_name_ is the name of the user account you wish to create, and the long echo line contains the .pub file contents for the student access key that you've created beforehand. (Description below.) (In this example I used a 1024-bit key just to keep the sample line short. In practice it should be 2048-bit, at least. AWS EC2 does not accept DSA keys, and I don't know if they accept Ed25519 keys.)

Point 2 - One key for all

As mentioned above, the key pair you use to access the EC2 instance gives you root powers. That is not the one key you want the students using. Of course, the key + passphrase setting applies to you as well, once you have set it in the sshd_config file, so even with your key pair, the students would need to know, or guess, your password as well. Still, that's easier than getting the key should be. Making a second key for all the students to use is simple enough, and you can even make it without a passphrase. The command, on a local machine,

ssh-keygen -b 4096 -t rsa -N '' -C student_access@AWS-EC2 -f student_access

will create the key pair, saved in student_access for the private key, and student_access.pub for the public key.

The content of student_access.pub, which is a long single line, is what is quoted in the echo command in the above snippet, to be copied into each students' EC2 home directory structure.

The other file, student_access, is the file which needs to be distributed to each computer, and to each appropriate account on each computer, which is supposed to have access to the EC2 instance. In addition, if the students are expected to have access to the EC2 instance from their personal devices, that same key will have to be made available to them so that it can be imported into their devices. Home computers and laptops are expected. Mobile devices, however, are also possible. I routinely use my cheap Samsung Galaxy J1 to SSH into servers I maintain. It is possible, with more work on your end, to have a different passphrase on each of the distributed copies of the private key. The command above creates one without a passphrase. Removing the -N '' option will cause ssh-keygen to prompt for a passphrase during creation. After the private key is copied to a different computer, of different directory, the command ssh-keygen -p -f student_access will prompt for the old (if one exists) and new passphrases, re saving the private key with that passphrase. Having a passphrase on the key will prompt for it when the key is used, with some caching, causing the SSH access to be double passphrase protected. Of course, knowing the passphrase also allows the student to change it to a blank, also valid, passphrase with no way for you to enforce it having one.

No matter how it is done, with or without passphrases, you could end up having nearly a hundred copies of the private key floating around in student hands. That is per class. In addition, so that they don't loose the key, you can expect that some of the students will email it to themselves, causing it to be even more "distributed" than your original plans.

If, as I do, you prefer to use GnuPG for handling keys, the following snippet will create the key pair, in a soon to be deleted sandbox directory.

mkdir sandbox
pushd sandbox
mkdir -p .keyring/{openpgp-revocs,private-keys-v1}.d
chmod -R 0700 .keyring/
gpg --homedir .keyring --batch --pinentry-mode loopback --passphrase '' --quick-generate-key student_access@AWS-EC2 rsa4096 auth 12m
gpg --homedir .keyring/ --batch --pinentry-mode loopback --passphrase '' --output student_access.gpg --export-secret-key student_access@AWS-EC2
gpg --homedir .keyring/ --output student_access.pub --export-ssh-key student_access@AWS-EC2
popd
mv sandbox/student_access.* .
rm -rf sandbox

The student_access.pub file is, again, the one to use in each user account on the EC2 instance, and looks the same as that created by ssh-keygen above. The student_access.gpg file is copied to each local machine, and account, where the command gpg --import student_access.gpg is used from within that local account, adding it to the user's default keyring.

The option group --batch --pinentry-mode loopback --passphrase '' in two of the commands creates, or uses, a blank passphrase for the key. Removing the entire group results in prompting for the passphrase during creation, and exporting the private key. Alternatively, it is possible to include the passphrase in the commands by placing it inside the single quotes. The command to change the passphrase in this processes is gpg --change-passphrase student_access@AWS-EC2 with a prompt for both the old and new passphrases.

Point 3 - Let students pick their password

This is standard Linux behavior after creating a user for each on the EC2 instance, and takes care of itself. The only protection taken in this setup is to prevent them from making their choosen password as blank. If, as mentioned above, the make that choice, they will be locked out of their account until you issue the command: sudo passwd user_name and enter a new password, which they would be expected to change, to a non-blank version this time.

Alternative setup:

Teaching Linux basics and BASH implies the command line as well. That seems like a good time to also cover some of the aspects of security. The rollout of the provisioning for each term can be included in the corsework. This can include the command line use of ssh-keygen, or GnuPGP (gpg), as the case may be. (Both is also an option.) The inclusion of C in your couse suggests that git could also be included, in which case I would recommend the use of gpg, as that will allow creation of both an authentication key for access to the EC2 instance and a signing key to use on signed commits in the repository. Especially usefull if you have group projects planned.

Teaching about security should also imply that you are doing security with the setup of the students' system. The single RSA key pair seems contrary to that. If a student leaves the course early you would be expected to create a new key pair, and redistribute it all over again. Otherwise that student need only guess another student's password, if it wasn't already shared with them, or they didn't watch it being typed, and have access to a former classmate's account. Of course, that applies even if the student has not left. They could still have learned another's password and then have access to a fellow student's area, and work, on the EC2 instance.

Having a key pair unique to each student can be more complicated. Especially if the local computer situation is such that any student could be using any workstation. It is possible that the use of EC2 instances for the student workarea is the solution to the other problems associated with undesignated workstations in the classroom. Some of the issues can be resovled with roaming profiles for the school network. If that is not something the school has established, however, it isn't any help here either. Using USB thumb drives is also an option, and the SSH key, or GnuPG keyring, could be kept there, either by default as part of the login profile, or manually. The ssh command allows for the identity file to be explicitly named with the -i /path/to/identity/file option, and the gpg command accepts the --homedir /path/to/keyring option as well as the GNUPGHOME=/path/to/keyring environment variable. In both cases the thumbdrive could be the path used.

The other side of the complication can be significantly reduced by using shell scripts for creating and distributing the key pairs, if it is not added as lesson material for hands-on lab work in the course. The first day of class could be built around accessing the EC2 instance prior to public key authentication, where they change their password and create, import, and backup their keys. Use ssh-keygen for the first day. Later, when their corsework has progressed to that point, create, and authorize new keys using gpg, which can be expanded later by adding a signing subkey for git commits, and then an encryption key for other work.

The snippets given above (for creating the keys, and for provisioning the EC2 instance) are well suited for using shell parameters in variables and the entire class could be supplied with keys, and EC2 user accounts, using scripts you create, and cancel the majority of the work you would need to do for each class.

The security issues, in my mind, seem to outweigh the "convenience" of a single key, and scripting can greatly reduce the time and effort involved in using unique key pairs for each student, and even for each device students might have, and wish to use for the class. Android and iOS apps for SSH have either the ability to generate key pairs, or to import them. Some have both options. A few also have the ability to export their private keys for storage.


Teaching a blind high school student I am teaching a blind high school student in my APCSA class.  All students are using a combination of CodeHS and Project Lead the Way curriculum.  Neither of these are very friendly to my blind student because there are so many visual that his screen reader can't interpret.

Does anyone have experience in this?
I'm looking for something that can be done pretty independently as he will be in the class  with others working on a different curriculum.  I want to support him in his endeavors to become a computer scientist but I don't know where to start as an inexperienced CS teacher myself!

Any help would be greatly appreciated.

A quick online search led me to this.

A Beginner's Guide to Access Technology for Blind Students

It covers all the essentials

Screen Access Software
Braille Embosser
Notetaker
Scanner and Optical Character Recognition

I am essentially listing things from that article It seems like something that was written years ago, but I assume, it should be a good starting point for you.

Further, the city I live in does have a national institute on speech and hearing, which includes folks who are sight challenged. If this is something serious, I can drive up there and talk to someone and hook you up with a professor or something.


Looking for a simple, offline, portable, lightweight IDE for C++ with a compiler and debugger I am teaching a second year programming course for adult students. It is an introduction to C++, with a chapter on Git. I'm not covering Makefiles and while I could find a bit of time to talk about build systems, the course is already pretty loaded (as any "introduction" to C++ can be).

The issue is that our school currently only supports Microsoft Visual Studio 2019, which is a behemoth and much too big for the tiny hello-world-ish stuff we need to do. It forces my adult students to go deeper into debt just to buy a new computer to run the thing.

It is also very complex and forces me to teach about managing Visual Studio's projects and files, competencies that are not really useful outside of Visual Studio.

I've been doing a lot of work with online tools (especially repl.it and onlinegdb.com), but our internet can be flaky and I would much rather have an offline tool.

Ideally, that IDE should be:

Simple, so it is not overloaded with features we won't need,
Lightweight, to work on older computers,
Offline, for when the internet goes into molasses-mode,
Portable, since students use various versions of Windows, Linux and Mac.

I am aware it is more of a wishlist and that there might not be a tool able to do all this.

What I've tried so far :

Adequate match:

CodeLite: Seems like a stable and up-to-date version of Code::Blocks/Dev-C++. Must install a compiler and debugger however, but it seems easy enough with GCC/GDB on Linux/Mac and Win-Builds' MinGW-w64 install on Windows. It also requires to add the executables to the $PATH environment variable on Windows.

Partial match:

Sublime Text: Lightweight and easy to use. Build system seems to be unique to Sublime Text however, but is not too hard to use. Nagware which require to pay for the official version.
Geany: Very lightweight, but not easy to use. Would require to teach Makefiles.

Bad match:

Code::Blocks: It is too unstable. It keeps crashing and students are confused whether their code is wrong or Code::Blocks is misbehaving again.
JetBrains CLion: Better than Visual Studio, but still heavy and complex to use.
Apache Netbeans: Current version (11.0) does not support C/C++.
Apple XCode: It is not portable outside of Mac.
Spyder3: Nice IDE, but really minded for Python.
Visual Studio Code: Too many complex configuration files, unique to VS Code.
Atom w/ gpp-compiler package: The IDE is added on top of the text editor. Error messages are difficult to read since they are on popups. Uses command-line GDB for debugging. The gpp-compiler package itself is still buggy.

Also, I tried to compile a list that already exists and is better documented at https://en.wikipedia.org/wiki/Comparison_of_integrated_development_environments#C/C++

My department uses Dev-C++. It's free, simple, offline, portable, and lightweight. Windows native.
Over the years the maintainer has swapped hands a number of times, it's occasionally gone a number of years without updates, and the size of the install has increased. But I like it quite a bit. As of this edit it got a new maintainer and update to v.6 a few months ago (November 2020):

Dev-C++ v.6 by Embarcadero (72 MB, 1/31/21)
Dev-C++ v.5 by Orwell (49 MB, 4/27/15)
Dev-C++ v.4 by Bloodshed (9 MB, 10/10/05)

Mirrors for the v.6 version that avoid the current maintainer's request for a lot of personal data can be found here and here.


Debugging a submission that works well on student's computer but not on my computer I teach a course in C++. Often, students submit a homework assignment that works well in their computer (they send me a screenshot showing that it compiles and runs perfectly), but when I run the assignment on my computer, I get a "segmentation fault". This is, most probably, due to some pointer-related bug or an uninitialized variable, that results in an "undefined behavior": in the students' computer this "undefined behavior" happens to work fine, but it is still an error.

When I tell this to the students, they do not know how to work towards solving the problem, since they cannot even see it on their computer. There are 160 students (with 2 instructors and 3 TAs) in the course, and I do not have time to debug their submissions on my computer, or to give them my computer for debugging.

One solution is to have a shared server, and have all students submit their exercises in the same server, so that everyone - including me - work in exactly the same environment. However, currently I do not have such a server so students work on their own computers, which can be Windows, Linux or Mac.

Additionally, having an identical environment for everyone is not a complete solution, since it is still possible that a submission happens to work well on this identical environment, despite it having an "undefined behaviour" bug. An identical environment thus only guarantees that, if the students do not see an error, then I will not see it too.

How can I help students debug their code in this situation?

EDIT: A related problem is that, when the students submit such a solution and I tell them they have a bug, they say "the bug is in your computer! See, my code works well on my computer!". So a related question is: how can I explain to them that there is a bug in their code, even when they do not see it?

You've said that having an identical environment for everyone would be an incomplete solution, since students' code could still work "by accident" in that environment. One option would be to provide access to two or more sufficiently different environments which would be the same for everyone; such environments could be provided in several ways, for example:

Distribute virtual machine images, with instructions for how students can use them to test their code.
Provide access to virtual machines through a paid service; for example, Codio is specifically designed for use in CS education.
There are some web services such as repl.it, which compile and run your code, and show the results in a console.
Some universities have student-run computing societies offering accounts for students on a shared server.
Different environments may already be available if students are on campus, and the campus has enough different computer labs open for student use at some times.

To catch undefined behaviour when grading submissions, you could test their code in the same two (or more) environments that students have been encouraged to use. Assuming you have a script that can automatically run all submissions, it shouldn't be a lot of extra work to run that script twice.

Another option is to provide students with a software tool which can detect and report undefined behaviour, as discussed in this Q&A on Stack Overflow. Such a tool could also be used to give feedback to students whose submissions fail on your machine during grading; although static analysis and other techniques won't generally be able to detect all kinds of undefined behaviour, the kinds they do detect should cover most or all of the mistakes that students are likely to make.


Book recommendation: basic, broad and solid overview for advanced learners I did a PhD in software engineering, now working in financial IT. I had a proper education in algorithms, data structures, operating systems, networks, software etc. and worked as a tutor for Java, OOP, UML during my PhD.

Now a senior board member asks me for a good introduction into all that "computer and architecture stuff".

I tried hard but don't find a suitable book that has it all on a decent level.

Topics I'd like to see are:

a bit of computing history: from Babbage via Turing, OS/360 ("mythical man month"), PCs to embedded systems like Smartphones, TVs and Raspberry Pis
what is a operating system, what is a file system, what is a database, what is an "application server" (abstract, e.g. including systems like CICS).
what is computation (imperative vs functional)
what is data (relational databases, data structures like trees, lists)
why is the notion of "state" important (finite state machines)
communication and networks: protocols, distributed systems
architecture: layers (ISO/OSI), separation of concerns, pipes and filters

All of this in a proper introductory textbook, but one that is not intended for students but people with a degree in another science.

Actually I am thinking of something history oriented, that also explains the "big" ideas (that are still present in current enterprise setting).

Perhaps someone here can recommend the one and only book, that has it all in a compressed form.

Alternatively a small list that addresses specific topics for non-experts are also interesting.

It is a bit hard to capture all of that. Unfortunately*, the best book is probably The Structure and Interpretation of Computer Programs but that assumes the person is willing to do some programming.

But one can learn a lot on Paul Graham's Essay Page, just by choosing interesting titles to explore.

*Unfortunately = work involved, not just browsing.


Study Advice for a CS Student It's my second year in my computer science degree, 2nd semester.
I feel like I am still not good enough and not satisfied with myself! I still can't program and when I have a task I can't think. I just go to google and copy the solution most of the times! Is it normal? I do study a lot even in the summer, but there is something missing.

What can I change in my study technique, to help me become a better programmer?

I will only answer the 1st question (as Ben says move the 2nd to a new question (the rule is, one question per question)).
So you want to get good a programming.
Where to start
The first thing to do is to stop cheating (your are harming your-self). You will have to start with much easier problems, than you are currently on (It will seem that you are going backwards).
Practice
Then you need to practice, practice, practice. There is an exercise called programming kata, where you just do the same exercise over and over, until you master it.
To copy or not to copy
If you do copy code, then:

you have not mastered it yet, so you will have to repeat the exercise.
copy from your previous projects, not the internet or other people.
don't paste code, type it.
if you have to use the internet/book/other-people, then use reference manuals, Don't copy completed solutions.

Reading and writting
To learn to write, first learn to read. Therefore read other peoples code. It is OK to read solutions. Read then, study them, understand them. Then do the exercise yourself. (It is not about memorising, it is about understanding.)
Choice of language
The language you use will have a big effect. Some languages are unsuited as a beginner language.
e.g. Javascript is not a good choice of language, for learning to program.


Is it a good idea to teach algorithm courses using pseudocode instead of a real programming language? I am a young professor teaching a data structures course for the first time. I'm teaching at an engineering college that provides an academic degree, but the focus is preparing future computer programmers, not academics.

Before the start of the semester I decided to present the algorithms as java code, instead of pseudocode. I felt that this would make the presentation more precise, and show the students how to put these algorithms to practical use.

My experience has been mixed. It seems like the problem is that now the students think that the various algorithms are the java code. They are complaining that, for example, I can't possibly expect them to know the counting sort algorithm, because how can they be expected to learn code by heart? So I am starting to understand the wisdom of using pseudocode.

My question, intended for other teachers, is: What has been your experience when using pseudocode vs using code?

Similar to @Vince, I think it's a good practice to do both. I don't really agree with the cooking recipe analogy, though. Pseudocode describes that the algorithm does, without going into detail how you do it.

I think perhaps a better analogy:

Pseudocode: you need to put an egg into the flour mixture
Actual code: pick up an egg, crack it open on the side of the bowl, and drop the egg into the container. Don't forget you need to dispose the egg shell as well.

There are so many ways to accomplish the task, and the actual code just gives the student an example of how to do it.

Presenting only the pseudocode might make some of your students loss. Presenting only the actual code would keep them in the box and get them focused too much on the details. A mixture of both would be my choice.


Textbook on Optimization Can anyone suggest some good textbooks on optimization for MSc level? Books with more concrete applications and examples on real problems would be more appreciated.

I am more interested in algorithm optimization techniques rather than something more theoretical like computability theory.

Thanks in advance!

My standard answer for this is the following, copied from another answer I've given here.

If you want a thorough study of how to approach and develop algorithms, get a copy of:
David Gries, The Science of Programming
The book will change how you think about algorithms and how they are developed. One of the key ideas is algorithm development from loop-invariants along with pre- and post-conditions. There is a science (hence the name) of modifying post-conditions in order to develop a loop and its invariant.
One of the magical problems in the book is a linear time sort of an arbitrary array that contains only three distinct values (Dutch National Flag). It generalizes to a linear time sort of an array containing a finite number of distinct values.

It shows algorithm development in a way that results naturally in optimized algorithms.
However any non-trivial book on algorithms should discuss optimization and the various ways it is measured (space, time, average, best case, worst case, ...). Books advertised as "introduction to algorithms" may be a bit shallow, of course.
The gold standard, of course, is the multi-volume The Art of Computer Programming by Donald Knuth. The first chapter of the first book is a nearly complete treatise on the required mathematics. In this series, algorithms are presented in a specially constructed assembly like (very low level) language. The Gries book also uses a specially constructed language for presentation, but it is at about the level of Pascal  or C.
However, if you are interested in Functional Programming (Scheme) instead, you want to start with The Structure and Interpretation of Computer Programs by Abelson, Sussman and Sussman. While this book will teach you deep concepts of algorithms, it might not be quite in the way you expect as it doesn't focus explicitly on optimization, treating optimization as more of an organic property of algorithms.
In fact, none of these books start with some "algorithm" and say "now, let's optimize it". I don't think that is a viable approach. Instead, algorithms are developed from the start to optimize on some criterion. But they are interesting partly because it is generally impossible to optimize on more than one dimension simultaneously. So most algorithms involve trade-offs of some kind. Often it is time vs space though there are other possibilities.


Answering “How is this useful to me?” When I am teaching, sometimes, I am asked “How is this useful to me? I don't use a computer. I won't use a computer in my job.”

How can I, quickly, answer this question?

I only have a few pupils with this attitude, so don't want to spend too much time on this. However ideas for a short-ish introduction, or ways to answer the question, will be welcomed.

I know this stuff is useful. For example programming: Some will become professional software engineers; some will just write the odd 10 liner to help solve the problem of the day; some will have to commission a software project, and the software engineers will try to over charge them ; some will never use a computer in their life, but computational thinking is still of use.

Details of pupils: year 7…9 (age 11…14). They are on the course, because it is part of the schools core curriculum.

The grown-up answer: Because it's good for you.

No, really.

At this age the different things you study all give you different kinds of skills and different ways of thinking. Thinking is good and the more different ways you can do that the more likely it is that you will be able to solve the problems as they come along. The different subjects in the early years are put there because people (grown ups) think that they will be relevant in the future.

Being able to think for yourself means you are more likely to be able to detect the lies that people will try to tell you to get you to do things that aren't really in your best interest, like buying something that has the main purpose of compromising your privacy. Math, History, Philosophy, CS, ... all teach you to think in different ways.

And, in fact, programming is useful in many fields. Even philosophy if you want to examine a lot of texts written by old (dead) philosophers. Science can't do without it anymore. Nor can some aspects of literature.

The less grown-up answer: Because it's fun.

No, really.

Well, if it isn't fun then maybe the teacher needs to rethink how the course is taught. Why isn't it fun? Is it the sorts of problems that the students are working on? Are they boring to the students? Is it the way they are supposed to behave? Too much frustration of working alone (or the opposite, I suppose)? Personally, I hate boredom. Or is it that they just don't have any bigger picture of what it is that they are learning, being always lost in the details? You can always ask the students what they "learned today". I used to ask that quite frequently, just to get them to focus on that before they left the classroom.

Ok. That was a bit grown-up too, but devious. Devious can be good, if done right.


Undergraduate Computer Science Projects I am trying to make studying computer science interesting for freshmen students. This will help them apply what is taught in the class to real life projects. My intention is to divide the class into groups and have them select a project from list of projects. These projects must be fun and not discouraging to attempt. It needs to be something they can reflect on after a few years from now and be happy they worked on it.

I currently do not have great list of fun projects for them. Please can anyone assist direct me to a resource or text book that will help out or share a list of projects.

Nna, its a challenge always. Your question resonates with me. I was and still is at the same situation where I am looking for interesting projects for my coding students. You asked for online resources or books or a list. I will share general principles I came to of how to create interesting projects in my similar difficulties (more difficult because I work in a developing country where resources aren’t easily available, and internet service is expensive and sometimes erratic). I’ll share specific examples in some cases.

Before that note something: in view of the level of your students, they may not do great projects “they can reflect on …” and use later yet because of their limited knowledge and experience. However, for beginner what you should strive at is to give them work that will exercise, stretch and consolidate their coding muscles.
My suggestions may not work for you. If they don’t I hope they stimulate enough tangential thinking in you that gets you there. Amen.

Now some “thinkPoints;” for students’ coding projects:

On strategy for giving projects: For freshmen, generally don’t expect “big” projects, give baby projects that are either stand-alone or parts of a bigger project which the students have to tie together at the end of their second semester.

consider posing problems from subjects they take or which you or them can find material for them to understand the issues involved e.g.
For Maths: Algebra, Coordinate Geometry, Arithmetic and Numerical analysis, Matrices, solving cubic equations, simultaneous equations etc.

For Physics: areas of interest may be topics in Mechanics like program to resolves or compose for forces, a program that takes input of any combination of time, distance and velocity etc. and automatically selects and uses the appropriate equation of motion to compute the required value. Smaller projects may be calculating linear & cubic thermal expansivities, receiving gas process inputs and the program making a judgement whether the process is isothermal, isochoric, adiabatic etc.

If they take general studies courses like Economics or are majors of it, better. Give them to develop a program that takes as input prevailing interest rates, liquidity rates and other macro-economic variables (you deem necessary), analyse them and give a prescription of whether the economy is on course, overheating or about to go bust. A more micro project will be like asking them to develop a program that calculates elasticity of demand and advise whether the demand is elastic, inelastic, unitary elastic etc.

For medical people or even others, let them build a program that calculates Body Mass Index (BMI) given height and weight of a person, use the derived value to advice a patient if he/she is obese  etc. and whether he/she is predisposed or not to hypertension and allied obesity diseases. The program should make a prescription of diet, drugs or life style change as is appropriate

Other subject matter, business or operational areas, Etc.

Where you or your students have no expertise in a subject matter in which you see an interesting project topic like the BMI example above, get a subject matter expert to prepare you a project background info paper that provides basic understanding. Take your students through and tell them to go read up more. That’s what every programmer does in subject matters areas (and there are many) of which we have no training or knowledge.

Set up academic type projects: E.g.
A menu-driven quiz that allows user choose a subject to take quiz from. The user picks any random number from a range of numbers of questions (“Enter any Question number you want to answer between 1 – 10”), is presented a question and allowed to choose an option or enter some text as answer. The score is announced and cumulated with previous scores and he/she chooses another question to answer till he/she decides to stop. At the end he/she is told his/her scores and congratulated or encouraged to try better next time.

A program that presents small amounts of materials as part of a lesson, allows student to branch of to find any further information. At certain points in the lesson, the user is given and graded on short quizzes before proceeding to next lesson.

Program to receive raw test/exam scores, convert them to letter grades (A, B, C etc.), and grade points (4.0, 3.5, 3.0 etc.), calculate G.P.A and C.G.P.A, highlights areas of students best performance and advises where the student can improve next term/semester then prints an e-mail to the student, faculty and his/her parents.

A synonym/vocabulary game where the system puts up a definition/usage or synonym and the student has to supply or choose from options, the correct word or synonym.

Take a problem you have in the operations or processes of the department or institution or personal life of the students and use as coding project. In these matters, involve the students. Ask their ideas, you may be surprised at the bountiful harvest of project topics.

For online resources, the easiest place to find good projects are the competitive coding sites like Codebyte, Project Euler, HackerRank, Codewars, CodeChef etc. However, as @Buffy has pointed out earlier, students could go to the sites too. & they could copy and paste code for you therefore doing nothing. So, always borrow project concepts from these sites and give it your own twist, complication and/or a local dimension that they can’t find easy online. & test google your final assignment concept to see if you too find anything thus verifying if they can easily “copy and paste” answers.

I hope even if you find nothing you can use here, your creative juices will have been stimulated to get you thinking of problems for students “baby” coding projects.


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.


IDE vs Editor and terminal for CS1 I am involved in the teaching of CS1 and CS2 at the University of Oslo. We have recently transitioned from Java to Python as our introductory language. We have a strong tradition of teaching students how to use text editors and the terminal to write and run programs, in a Unix environment at our university. Recently, however, a discussion among the teaching staff has arisen about whether or not to transition to using an IDE for the teaching of first-year programming.

Can anyone give me their thoughts on this matter? What are the pros and what are the cons of moving to an IDE-first approach, rather than sticking with editor+terminal?

TL;DR Those two aren't your only options.

The main concern is cognitive load: learning to program is difficult enough without adding incidental complexity.

We've seen an explosion of hybrids in the last few years with good cross-platform support: Sublime, Atom, VSCode, etc. And while you couldn't pry vim out of my cold dead hands, learning it is easy if you already know programming but would be a nightmare if you had to learn it and programming at the same time. Ditto for emacs.

And that also applies to IDEs like Eclipse and Visual Studio. They have their own way of doing things. They take forever to open. They are user configurable but not easily. I'll never forget the first time I opened XCode and basically said "what the hell is all of this?"

Have your students download vscode or atom which work reasonably well out of the box with a healthy plug-in community for growth. They're scriptable in JavaScript and themable with CSS. Unlike notepad it gives you features you actually need to program, unlike nano it uses standard keyboard shortcuts they'll already know from e.g. MS Word (Ctrl-C, Ctrl-V, Ctrl-S, etc). And unlike VS/Xcode/Eclipse it doesn't obscure what you're doing with a bunch of platform-specific goobledegack: you're editing text files.

Edit

Can't believe I forgot to mention this but...

They more or less made us use Komodo Edit (free version of the Komodo 'IDE') in my first programming class, which is exactly the kind of thing I'm talking about and I think it really helped. Simple, no configuration necessary, things that should be easy were easy, etc. Don't know if they still offer it or not but I'd say Atom or VSCode are better along just about every conceivable metric.


Dealing with students who are overly motivated Occasionally I have students who are 'overmotivated': they put way too much effort in to trying to memorize every word of the textbook, every idea, each diagram I draw... They spend all of their off hours, all evening and weekend, reading, rereading, underlining, highlighting, going over the same pages again and again. I look at their textbook and nearly every word is underlined and/or highlighted!

For example, when I project the textbook, there might be a few lines or words on each page that I have underlined, which I explain. I try to cover those vital ideas at least three times on different days and in different ways. There are parts of textbooks where I say "skip this, we will get to it later." These students then come to me with questions about that. I am fine if they want to learn it now instead of later, but I am not fine if they are struggling, drowning in concepts, burning themselves in to the ground, and they try to take on that needless idea that I told them to skip.

What do you do with students like this? I am in the USA, so I am not expecting this level of intensity. It is working against these students' progress.

I don't think this is really a CS problem - though of course some individuals do get "addicted" to computing.

The root of the problem is that these students don't know how to study - and ironically, it's quite likely that the education system they are progressing through has never even tried to teach them that basic skill. But you don't have time to teach them that, and teach the contents of your CS course as well.

Students who have found everything "easy" since the start of their education are often the worst sufferers - eventually they hit the brick wall where just listening to the teacher and "getting it" with no effort doesn't work any more, and then they are completely lost.

The best solution would be to try to get a general "how to study" course into the curriculum for every student - or at the least, start your course by giving them some guidelines (including notes to refer back to!) on the study strategies that work, and those that don't.

But you can only lead the horse to the water - as somebody once said, "Homo sapiens has a fundamental design defect: most members of the species can learn, but none of them can be taught."


What program follows "hello, world"? You've just demoed your first bit of code in whatever language you're teaching. The requisite "hello, world" has been said. The program has been compiled (or interpreted) and run. Now what?

There has to be a program that follows "hello, world" that builds upon the basics of printing one line on the screen.

What is the logical next step in an introduction to a new language and possibly to programming as a discipline in general? We all know program #0; what's program #1 and why?

Note: I know this is subjective, but I'm hoping it leans the good way. I'm trying to ascertain the scaffolding at an introductory level. Once the cliched example is complete (not that it doesn't have a lot to teach in and of itself), what makes sense as the next curricular step? I think the need for justification based on experience, expertise, and facts helps it from being too broad, but I'm happy to revise if necessary.

When I was teaching and mentoring first-time students, what got them really excited for the first time was seeing their name in lights. Write a program that allows a student to enter their name, then print it on the screen 10 times (or 10,000).

It introduces the concept of variables and variable types
It shows how computers interact with the outside word by accepting input from the students
It introduces basic looping and conditional statements in a really simple example
It shows how math and computation works in a computer without simply spitting out basic algebra.

The best part is the students don't have to understand 100% of the program to start picking out the individual parts. The basic program flow is somewhat intuitive. You can start without the loop and add it in later as you introduce the concepts. This simple exercise is straightforward enough to teach the underlying concepts of how programming works in a somewhat entertaining, interactive application.


Pedagogical reasoning behind a minor difference in two loops I keep seeing examples like the first program bellow, in teaching materials.
Is there a pedagogical reason to teach this first program, compared to the second?
answer=input("Do you wish to continue?")

while answer == "yes":
    answer=input("Do you wish to continue?")

print ("Good bye")

2nd program
answer="yes"

while answer == "yes":
    answer=input("Do you wish to continue?")

print ("Good bye")

An argument for the 2nd one
I think the 2nd program is more elegant: it has less repeated code.
note: when I wrote this I copied the 1st line into the other 2 places, then when I tested it I discovered that I missed the closing ", so had to fix it 3 times. This is an example of why repeated code is a problem, when a program needs re-editing. In the second version, the only repeated code is "yes", so still some room for improvement.

This is a really good place to introduce boolean variables (or just to use them, if they've already been introduced. It also introduces the idea of descriptive variable names.

user_wishes_to_continue = True

while user_wishes_to_continue:
    answer = raw_input("Do you wish to continue?")
    if answer != "yes":
        user_wishes_to_continue = False

print ("Good bye")

Note: here I use raw_input, which returns the user input as a string, rather than input, which interprets the  user input as python code (meaning that you have to put "yes" with the quotation marks each time.


Curricular Support for a CyberPatriot Club I currently coach our school's CyberPatriot team. (You can find information on the CyberPatriot competition here.) We are heading into our second year of competing. Last year we did pretty well for being a more casually organized team, but I'd love to bring in a stronger curriculum.

There are helpful training modules provided for coaches, but for more advanced vulnerabilities, independent study and research is necessary for achieving at the highest level in the competition. In particular, the images students must "secure" encompass a wide range of operating systems. Last year had Windows 7, Windows 8.0, Windows 8.1, Windows 10, Windows Server 2008, and Ubuntu 14.04. Additionally, students used Packet Tracer to learn networking security through the Cisco Networking Academy.

The bottom line is that there is a ton of potential information to cover, and there is a precise way to succeed at CyberPatriot. This page explaining how the competition works details the point system: basically you earn points for doing a precise task in securing the system and lose points for making it less secure.

My question is this: what resources can I use to strengthen my students' ability to succeed in this competition? For context, they are doing it as an extracurricular activity, and any resource that is engaging for students to work though on their own is a bonus. They are highly-motivated, but since there is so much out there, it's hard to know where to begin since cybersecurity is not my background.

I'm not sure how engaging these would be, but as a source of exercises and practice content, you might look towards IT professional certifications. There are things like A+ (general IT), Networking+, CCNA (Cisco), or MCSA (Microsoft sys admin), among many many exams that are quite popular and have a variety of study resources online.

This PCWorld article has some decent overviews of the tests. I'm dubious of an article promoting certifications based on studies by a group that sells certifications, but regardless, hopefully it has pointers to resources you might be able to pull from.


Using Oracle's Java Documentation as a Teaching Tool I'm in the process of preparing for the second semester of AP CS A (Java). I want to review objects and classes with my students to prepare for our extended focus this semester on inheritance and interfaces. I've been using textbooks I'm not particularly thrilled with, so I wanted to put together some review material of my own and/or from other sources.

My first Google took my right away to the official documentation from Oracle, and I found it to be a clean, easy-to-understand explanation of fundamental concepts of the language (which can't always be said for documentation). In particular, this section on Object-Oriented Programming Concepts is exactly what I was looking for in terms of simple, clear explanations with code samples. That lead me to ponder the following question...

What, if any, benefits are there for teaching straight from documentation rather than a textbook?

One obvious benefit, which is really a good goal in and of itself, is that students get used to utilizing documentation.  Many students don't use the internet as a resource at all, and those that do often wind up on StackOverflow.  It has been my experience that the very basic searches that those students often perform wind up at SO pages that are rather too complex.  If they want to know how to find a subset of a String in Java, the Oracle documentation is really a better place to begin than Google.

Being able to read and understand documentation gives them a powerful research tool that they can utilize for future explorations.


Any good beginner tutorials for learning LLVM I think the https://llvm.org/docs/tutorial/index.html assumes you know too much. It's written in an unfamiliar language to me, OCaml, and they assume you know about lexers, parsers, AST. Any thorough beginner tutorials out there?

As stated in Buffy's answer, you'll want to first be familiar with the other steps of compilation, because code generation is typically the last step in the compiler pipeline. If you haven't already, I'd suggest looking in to lexing and parsing as well. Optimization is nice as a bonus, but llvm does a good deal of optimization on its IR by itself.
Once you're familiar with the general outline of how a compiler works, you can start building one yourself. There is a language that is designed to be easy to build a llvm compiler for, called Kaleidoscope, and I'd recommend looking up a tutorial for building a Kaleidoscope compiler in whatever language you choose. llvm has bindings to many different languages ranging from haskell to C, although you will likely have the best experience learning in C++ since that's how llvm's API is implemented.


Is the CS50x course enough to get the generic knowledge of a CS grad? I am looking to get into a software engineer role and I need some fundamental knowledge of Computer Science Engineering concepts. Will David Milan's basic Computer Science course from Harvard, CS50x, be enough to accomplish this?

No, not by a long shot, although Harvard's CS50x is an excellent introduction which provides around 10 hours of lectures then problem sets which support approximately 100 hours of practice at programming by solving Computer Science problems (not quite the same as software engineering problems).

Most typical entry-level software engineers (regardless of their background) will likely have spent several thousand hours learning their craft by the time they start their first job (Something roughly equivalent to the amount of time a typical graduate may have had after 3 years at university).

This obviously includes programming and core computer science concepts, but most importantly it involves having hands-on exposure to building some working software (Which is about far more than just writing code -- actually, writing code is only a small part of the total amount of work which goes into building working software).

While it's certainly true that Software Engineering is rooted in Computer Science, and computational thinking skills are an essential prerequisite, that capability is nowhere near enough on its own.

Generally speaking, most software engineering problems also have a degree of subjectivity built on top of that - i.e. they go beyond just needing to find solutions based on logic;  most of the problems faced by software engineers are more about humanity - meaning that the vast majority of issues involved in building software can't be solved just by writing an algorithm.

Just to provide a few examples - this list is neither complete nor comprehensive, but hopefully illustrates the kinds of things that are learned through hands-on experience of working on software projects (even spare-time hobby projects and open-source software):

Requirements gathering and analysis
Software design principles and approaches to software design (e.g. consideration towards interfaces, modularity, and automated testing)
Pragmatism and consideration towards real-world constraints (e.g.  people's time, or their willingness to accept change, etc.)
Communication, knowledge-sharing and collaboration with other developers (e.g. peer reviews, pairing)
UI/UX Design
Communication with users and stakeholders, including managing their expectations and seeking their feedback.
Teamwork and being able to function within processes and procedures that allow many people to contribute to the same project/codebase.

On top of that, there's also the fact that software engineering often tends not to be about using code to solve every problem but to include a lot of effort reusing other people's existing/working/tested solutions to avoid re-inventing the wheel (For example, "devops" tools, app frameworks, cloud services, 3rd-party libraries, O/S capabilities etc.)

This often includes trying out tools/libraries/frameworks to check their capabilities, then figuring out how to integrate your code with those things (e.g. through programmatic APIs, configuration management, build/integration/deployment processes, automation/scripting, etc.)

This is not to say you need to be any kind of expert in these things for an entry-level Software Engineering position, however once you're confident in the core skills of computer science, programming and computational thinking,  it'll be important to focus learning around building software - at which point a lot of issues around tools/APIs/libraries/frameworks start to crop up, and so should the issues around understanding software design, testing, pragmatism, and (ideally) a lot of interaction with other programmers.