How useful it is for math student to learn programming to find proofs or counterexamples?

This is pretty much in the realm of opinion, but as a math PhD and a long time CS professor, I'd guess the answer is no. Programming is fun and programming can be useful, but its application to proving theorems in mathematics is very specialized and a bit limited. And it generally doesn't apply to the sorts of things a struggling math student wants to learn.
There are a couple of exceptions in which programming was instrumental in establishing a proof. One is the Four Color Theorem which was originally proved with a computer because of the huge number of different possible planar maps. But mathematicians, like myself, find that proof unsatisfying and would prefer one that was more analytical and which would lead to more insight. But these sorts of cases are very rare.
But, theorem proving, like anything else is a skill best learned through practice. Once you have tried and eventually succeeded at proving some theorems, perhaps after false starts, you will start to gain insight. Every success can lead to the next success. But it is hard work. And the work may not get easier as you go, since you will probably take on harder problems. But practice, practice, practice.
Programming does, however, give you some practice with thinking logically and breaking a hard problem down into smaller, easier, parts. In that sense programming can be a bit helpful. But to learn math, just do math.
On the other hand, there are automated Theorem Provers that can do some interesting things. But their results don't generally lead to the insight into a problem that a mathematician needs and to build one of them requires deep insight to start with.


Is the algorithm-recipe analogy a good or a bad one?

Actually, you are loading a metaphor/analogy with too much import and influence. An analogy isn't supposed to be exactly the same thing as the thing of which it is an analogy. It is only supposed to be similar to that thing in some way. But not in all ways.

Analogies and metaphors in teaching computing are intended only to overcome the initial static inertia caused when a student has no idea whatever about a concept. To use it well, you need to do a couple of things, one of which is to move away from it as soon as is possible. But the more important thing is to be aware of how the analogy fails to be the thing analogized and to watch for misconceptions in the student's mind that are actually induced by the analogy itself. You then need to give a correcting lesson.

I can analogize loops with cooking recipes as: stir the sauce until it thickens. This isn't an algorithm, of course, since it has undefined terms, especially in the stopping condition. If that gives the students a quick mental picture of repetition then fine. But if they put too much weight on "stir" or think that an imprecise stopping condition is normal in programming, then I need to make a correction.

Sometimes that correction is with another, better analogy, but usually it is just a more precise and technical discussion.

Don't put so much weight on any given metaphor. Use it to introduce concepts but know when it fails and make corrections for those (hopefully few) students who draw the wrong conclusion. You can thus avoid being overly detailed and pedantic, losing students in the interactions between all of the small bits that go into anything complex.

I've been told that professional bakers follow their recipes more faithfully than professional chefs do. More careful measuring, for example. But even bakers have to deviate as the flour they use can vary in moisture content, requiring adjustments.


What is a good teaching example/application for jagged arrays (2d arrays with irregular row lengths)?

Hmm, here are a few ideas:

Calculating student GPA where the grades are all stored in an array of arrays, and the different semesters have different numbers of courses.
Make a lookup table of prime factors.
Consider an array of arrays of paths to hike, and local maximum / local minimum elevations passed along the way. Since there will be a different number of local maxima/minima along the way, the array will naturally be jagged.  Figure out which hiking path involves the least climbing.
Same as above, but now instead store the elevation every x number of meters.  Since the hiking paths are somewhat different lengths, the array will naturally be jagged.  Determine which path has the lowest average slope for a hiker who has difficulty with hills.
(More advanced than AP, probably) Many Sudoku variants often suggest jagged arrays.

Also, for what it's worth, if you organize your midi-like events by time, it's actually ragged.  Different numbers of notes are played (or stop playing) at different times.  If you play a triad, you will have three events.  If you play a triad at the same time as you stop playing a previous melodic note, you now have four events.


Say you want to present a choice of interactive games

   out.println("Which game (...) ?");
   Game game;
   switch (in.nextLine()) {
   case "HI-LO" :
         game = new HighLowGame();
         break;
   case "Riddle" :
         game = new RiddleGame();
         break;
        ...
   }

Here you are. You have polymorphism. The game variable may refer to objects of different types.

Now, how to play a game (in textual form) ?

     out.println(game.getPresentation());
     while(! game.isOver()) {
         out.println(game.getQuestion());
         out.print("> ");
         game.submitAnswer(in.nextLine());
         out.println(game.getMessage());
     }

Polymorphic code. Now what is in a Game?

    interface Game {
        String  getPresentation();
        boolean isOver();
        String getQuestion();
        void submitAnswer(String line);
        String getMessage();
    }

An implementation ?

class RiddleGame implements Game {
    String getPresentation() {
         return "What cheese is made backwards?";
    }
    String getQuestion() {
         return "Guess it!";
    }
    boolean found = false;
    void submitAnswer(String line) {
        found = line.trim().equals("edam");
    }
    boolean isOver() {
        return found;
    }
    String getMessage() {
        return found ? "you got it:" : "no, it isnt";
    }
}

Boring java details omitted.

[rant]
Most introductory examples for OOP are utterly silly and totally inadequate to explain that classes are here to offer services. This unfortunate fact leads them to a lot of misconceptions.
[/rant]

The purpose of OOP is NOT to build taxonomies of animals, or make container objects with a getter and a setter for each attribute. It is not to model even a simplified view of the real world. It is there to write code which does something.

Oh, well, I see you don't like the RiddeGame because it knows only one joke.  So introduce a RiddleProvider as a parameter, whose job is to supply a Riddle  (question + answer pair).

You can imagine several kinds of RiddleProviders, so it is itself an interface with different implementations.

The simplest is the AlwaysTheSameRiddleProvider, which only know one joke, just like me. Others can run a predefined sequence, or a random choice, from an array, or from a file. Again, they offer a service to be used by another object.


Process Scheduling is not "Process" Scheduling - Should I disclose it to students?

Perhaps I'm just naive, but I don't see a dilemma here. Yes, teach them the current state of the art if that is appropriate in your course. Teach them some important historical precedents at some appropriate level of detail. In this case you shouldn't be teaching one edition of a book or one version of a particular OS. If the students are to have a future in the field they will still be working in 30-40 or more years. What they need is the background and skill to keep up with technological changes as they occur.

You already say that you teach them the various scheduling algorithms for associating a software element with hardware. That is more essential than the specific granularity of the elements on either side of the equation. Even the standards of what constitutes efficiency may change over time. Teach them the principles, for which some blend of the old and the new is likely required. This will serve them well in matters other than Operating Systems proper.

You should also look at a more recent edition of your text and at other books. This will help you get a handle on what the authors currently consider to be important. Tannenbaum, for example, would be a good supplement to Silberschatz et al.


Working with students with specific secondary skill

It is not clear for me what "computer science" means for you. Is it at High School level?

If that is the case, you could try to introduce some of the mechanics behind "digital music". How it is processed from analog to digital. How it is compressed, how it is reproduced, ... What does it mean to be 8bit or 16bit, the bit-rate, the sampling frequency...

If the students are more into drawing/painting, you could do the same with image formats.


Learning from research papers in a developing field

Seems like a developing field is a discussion that a community of researchers engages in.  To participate, you'd need to:

Speak the language, e.g. know about quantum computing terminology.

Know the background, e.g. quantum physics and computational theory.

Once you have some basis for understanding the discussion, then you focus on getting your own ideas straight.  In the end, it's really all about you; sharing research results really isn't a goal so much as a duty to be performed when/if you become the foremost authority on some particular understanding.
If you're a younger student, you've probably got a lot to learn and develop before you can really enter that arena.  But, if you're interested in it anyway, it seems like you could do two things:

Focus on the well-agreed-upon concepts.  You don't need to understand them or even be able to use them just yet, but have them in the back of your mind as you progress in your more foundational studies.

Take note of the skills and tools that seem to be most useful in the current community.  For example, if the field seems to be best-attacked through a particular branch of mathematics or using particular computational tools, then you might want to put acquiring those skills on your to-do list.

Getting to Philosophy

Papers often lead me down rabbit holes as well - tracing citations (I could tell a few entertaining stories about that alone), looking up terms ("oh, that's what you meant...well, why didn't you say that?"), and going down that oh-so-fun Wikipedia trail. You know, look up word, read third word on page, click on that, then continue until somehow you end up at philosophy (ironically, the previous page doesn't end up at philosophy, if I did it correctly).

Definitely, Philosophy is exactly where you want to end up!  Anyone who can't trace their field back to Philosophy hasn't understood it so much as memorized it.
If you know exactly how to get from basic philosophical principles to the current state-of-the-art, then you can really claim to understand the field.
Questions

What tips do you have to get the most bang for your buck reading a paper and retaining that understanding?

Lots of profiling.  For all anyone knows, that random gibberish full of typos and conspiracy theories on Reddit is the deepest, most correct theory of physics ever.  But, since it's probably not and there's only so much time in the day, your bets are better hedged by focusing on content that appears to be of higher quality.
To that end, you should develop a bunch of prejudices over what's likely to be better content, then selectively focus on it.  Sure, if you're truly out of stuff to read, then maybe you'll end up going through that weird Reddit post; or, if you've got too much good stuff to read, you might not even be able to make time for Einstein's words.  It's all relative.
Examples of common prejudices:

Prefer scholarly sources for widely understood concepts.

Prefer blogs and communications from top-experts for the-very-latest commentary.

Well-formatted over poorly-formatted.

Thoughtful over thoughtless.

Analytically precise over vague.

How do you help restrain the rabbit hole?

Follow the rabbit hole down as far as you can go without losing sight of the light of day.

Understand where you've ended up, and build a solid foundation there.

Build back up 'til you're out of the rabbit hole, standing on more solid ground.

Rinse and repeat, iteratively falling down further and building back up more.  The more you do this, the greater your understanding grows.

How do you know when a paper's trustworthy?

They never are.  Whenever you read a textbook - even the best-known ones in well-developed fields, e.g. introductory Calculus - never just trust it.  Put each word on trial, and absorb only the ones that you can't tear down.
You often need to memorize large amounts of content without first thoroughly scrutinizing it.  All of this content should carry a red flag in your head that labels it as unscrutinized claims.  If there should come a time where you really need that information, or want to build upon it, you should really scrutinize it first.


Any simple Python GUI projects for beginner/novice programming students?

In my experience, good introductory programming courses meet three overarching goals:

Empower students to create simple programs outside of the scope of the class by giving them the technical skills and the practice to begin being independent. This includes teaching the basics of one usable language.
Inspire students to continue learning and using their skills once the class ends (independently and/or by signing up for the next class in the sequence).
Prepare students for the next step in their learning. In many cases, this means that certain topics and concepts must be covered so that students can enter the next class at the correct level. It should also include giving students practice with the skills needed for basic independent learning including debugging, googling to find solutions to problems, and initial exposure to reading and utilizing documentation.

It sounds like you have seen issues with goal number two, where your students do not feel inspired. However, I am concerned that introducing your introductory students to GUI building right off the bat will jeopardize goal number one. GUI has a lot of overhead, and as you said, your students will not understand what they are doing and will be frustrated by their inability to build anything without heavy guidance/pre-built pieces.

My suggestion is to strike a middle balance. Have them build command line applications that they fully understand, but that are interesting or useful in some way. Better yet, give them some choice in which projects to tackle so that they are more invested.

Here are some neat things that students of mine have built in the command line without any OOP:

Guess the Number Game (the computer generates a number and tells the user if they are too high or too low)
Fortune Teller Games (using arrays and randomization)
Personality Quiz
Hangman Game
Random Name Generator
Text Based Adventure
Reverse Guess the Number Game (The user picks a number and the computer has to guess. This is a great jumping off point for first introducing the concept of an algorithm, since the program needs to make "smart" decisions.)
Minesweeper, battleship, connect four, etc. are great for 2D arrays/lists when you get there
Flash Card Application (students can even actually use this to study for tests for other classes!)
Calculator (if that's too easy, have it do harder math. Can your students build a calculator that solves algebraic equations? Can they make it take derivatives? Solve trig problems? You can apply it to whatever math they likely are learning at the time)
To do list manager
An application that manages a student roster or waitlist for a class

I hope these ideas help!


How do I teach problem solving and logical thinking to students of age group 12-18yrs through online session

I would go back through old copies of GAMES magazine (libraries may have a stash somewhere).  They go the whole way back to something like 1977 and generally have lots of puzzles of various levels.  Apparently they merged together with another company back a couple of years ago.

https://gamesmagazine-online.com/product/vintage-games-packs/

In particular, I'm thinking of some puzzles where you are given a bunch of statements about a group of people and then have to derive all the information about them from logical inferences.  Generally, you'd have to lay out a diagram of some form and use that to either associate or block particular combinations until you figured everything out (much like sudoku but with logical constructions of words--this stuff predated sudoku by a long way).

As the teacher, you can "run the diagram" while the students can try to discuss the various implications of the statements.

Good luck.

(Edit: I just remembered a book I had a long time ago called "Puzzles for Pleasure" by E. R. Emmet--also a good source).


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.


What technique should be used to make video tutorial for BS(CS) students?

I don't have a lot of good suggestions for you. However, if you really want a professional quality video, you need to use a professional. The videos deployed by Open University UK, for example, are prepared in the BBC studios with large (large) budgets. I assume you have to get by with something less.

Different platforms have different tools, but there are video/audio capture applications for most of them. You might also need to use various camera and microphone setups, including wearable microphones, in order to capture what you want.

But you will still have a big problem. One is that it is difficult to capture audio in such a way that it can be heard and understood by your audience.

A bigger problem is the time (and software) needed to edit what you capture so that it makes sense to the viewer. Pacing and sequencing are very important.

The key to success for do-it-yourself, however, is to use repetition and feedback to learn how to do it, the same way that students learn. Make something with some tools and then get someone to give you feedback on it. Repeat and repeat again until you get it right. Eventually you will make something you like. Or decide to hire a professional.


Software to produce an interactive presentation?

Here are two ideas that might meet your needs:

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

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

Best of luck!


I used a Parsons problem to teach functions. I used Google Slides to put different colored text boxes on one slide and gave the students instructions to arrange the text boxes in the proper order. A screenshot of what the activity looked like is below:

I wanted students to have experience with the ordering of function calls in C. There are technically two correct ways to approach this, but because I specify the requirement to use each block, there's only solution here:

Seeing how information gets passed from function to function and how to lay out the structure was helpful for students. Focusing on those skills outside of/separate from the syntax helped because students only had to worry about one thing at a time.

As I look ahead to next year, I want to do more of these problems, especially when teaching loops and sorting algorithms. They are quick and simple to make and differentiate instruction effectively. In the context of AP CSP, they provide great practice for the AP Exam which includes a number of code samples to read and understand.


Is there any formal education for programming? Other than a CS degree?

The short answer: no!

The long answer:
In my opinion if you really just want to focus on programming either a paid programming course could be the correct choice or just self-taught learning by doing. Of course you'll miss lots of theoretical things that will be important for an abstract view of programming. And also more complicated problems might need the theoretical knowledge you would gain at university.

If you want some certification of your knowledge, I would recommend you to gain enough knowledge in a language that has certifications and just get this certification.


The confusing Unix permissions terminology

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

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


How can I explain the difference between CS and coding to a layperson?

I regularly have to explain what computer science is to parents, and I have lately settled into this explanation:

Technology keeps changing all the time. You get used to the menus in Microsoft Word, and then they change it to the Ribbon. You learn to program buttons in Java using Applets, and then Applets get removed from every major browser as a security risk.

But there are some things that never change, because they're in the realms of mathematics, or they are fundamental organizing principles.  For instance, computer right now work in binary, 1s and 0s.  The properties of binary numbers themselves aren't going to change no matter what new technology comes around tomorrow.  We might create a computer that's not based on binary, but the properties of binary itself are fixed.  This is the realm of computer science.  Computer science is the foundational stuff that doesn't change.

It's highly mathematical, highly theoretical, and there are a lot of proofs involved, but when you study computer science, you are studying the deeper question in the nature of computation itself, and that's stuff that never gets dated.


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

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

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

To solve the n disk tower problem:

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

Solving the 1 disk problem is trivial.

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


Why are pointers a key topic in a CS curriculum and oft cited as something people don't get?

This question is actually not so far off from asking why operating system memory management can be confusing to some students.

Ultimately, we only have two fundamental tools for managing memory: pointers, and calculated offsets from pointers. That's it. In spite of GypsySpellWeaver's assertion, they don't particularly support OO, they undergird literally everything.

How does the computer know what line of machine code to execute next? Pointer. How does it know where the stack frame currently is so that it can find your variable? Pointer. How does it know where the system functions are so that it can print to the screen? Pointer. Pointers are not hard at the most trivial level of understanding. They are hard because, when you actually start to look into how they are used (or manipulate them yourself), you wind up deep in the weeds in some confusing places. They are the simplistic entry point to a host of deep, rich, and complex ideas.

Here's a quick "for instance": students don't come in fundamentally understanding the stack and the heap, and without that, much of what we do with pointers doesn't make sense in the first place.

Understanding memory in a computer is not a trivial task.  When I write

int z = -1

... a student naturally expects z to be a number.  But, of course, it's not. It's a reference to a stack offset at which is held a series of ones and zeroes.  The compiler stores z as something like stackpointer+8, and that's what gets written into the compiled code. The name z goes away.

char* x = &z + 1 is literally nonsensical, unless you understand that memory is fundamentally typeless, and what a memory address actually is.  This isn't trivial stuff for someone whose whole experience with computers has been installing and using apps to play games and chat with their friends. Nor is the result of printf(x), or printf(*x).

Fundamentally, a student needs a rich mental model of the whole machine to understand pointers on anything beyond a trivially simplistic way.


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


System to validate run time complexity requirements

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

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


Allowing students to work cooperatively on a computer, and retain access to their work

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

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

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

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

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

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

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

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


Common questions students may ask when they learn OOP?

I read through most voted questions tagged object oriented on softwareengineering.stackexchange.com and stackoverflow.com. I feel some questions on  softwareengineering site are quite common when learning OOP while questions on stackoverflow are more related to practical programming questions that are more likely asked by professionals.
So I listed some questions from softwareengineering site,

Why is it good to split a program into multiple classes?. This question was indeed asked by a high school student.
Do objects in OOP have to represent an entity?. My students do ask me this question.
What's the benefit of object-oriented programming over procedural programming? this one is somewhat related to the "manage software complexity" question in my question and I do discuss with my colleagues another interesting question that was asked on quora How does Linux maintain such a large code base when C isn't an object oriented language? Is the code base all messed up?
Does OOP fulfill the promise of code reuse? What alternatives are there to achieve code reuse? I am not sure if students will ask this question and I have my own double to the question too.
When writing object-oriented code, should I always be following a design pattern?. This site also has a question about design pattern, How bad is a Computer Science course that doesn't teach Design Patterns?
Explanation on how “Tell, Don't Ask” is considered good OO. Only after they gain some coding experiences can they ask/appreciate the question. But it is a good one.
Should I create a class if my function is complex and has a lot of variables? One answer there was also my recommendation to my students when they have such question, "Use a class, but also provide a free standing function, that only constructs the object, calls the method and returns the result, the class that you use internally really becomes just an implementation detail of your public function"

Quora also has some interesting questions I feel people will ask when they first learn OOP, I list some here:

Can anyone (in a programmer's position) survive in the modern tech industry (software or no software) without OOP?
How often do software developers use OOP?. One answer there by Kurt Guntheroth is interesting "Any time you write a program longer than about 1,000 lines, you should use OOP. 1000 lines? Why’s that ...?"
When is object-oriented programming not a good fit?

Hopefully I can get some other answers.


Hand-on ideas on tutorial on setting up a cloud-based server

Let me give an idea, though it will shoot down your proposal, I guess.

Face to face time with students is precious. Use it only for those things that are best done that way. Three or four hundred years ago lecture was very efficient since even books were unavailable and very expensive. A hundred years ago books became reasonable for a student to purchase so lecture changed a bit and the book and its exercises took on a larger role.

Today, as you suggest, we can do live demonstrations of things and have interactive sessions. But the time with students is still precious. If you want to demonstrate something or have students do something in a lab where they follow your direction, you should make sure that the topic is something that is really important and advances your main teaching goals. Setting up servers isn't likely to be in that category unless the course itself is about server management.

The problem with work-along demos is that the students, if there are more than about ten will get out of sync. Some of them will be confused. Some of them will, when typing or otherwise interacting with the machine, miss an essential instruction from you and get lost. They will get blocked if they see something unexpected, and if it is new to them, the unexpected is expected. They will come up with questions and wait, fairly passively, until their questions are answered.

If you are doing something truly essential, then all of these difficulties are worth it in the long run. But for the inessential and even for some essential things use handouts or web pages. Use official documentation that you point to, perhaps supplemented. Give them a way to ask their questions in a way that doesn't intrude on face time. I found a mailing list dedicated to each course as a way to do this. Especially when other students are encouraged to answer student questions.

Use the "big impact" methodologies for the "big impact" ideas. Face time is the biggest of all. It is often even a waste to use it for lecture - a broadcast mechanism, rather than a personal one that might be used instead.


Physical analogy to introduce a Delegate in .Net programming

I know that you are looking for a physical analogy, but I'd say I agree with @ctrl-alt-delor about the 'link to what they already know' part.

I usually start by introducing a simple algorithm, then show how that algorithm can be parameterized. Then we move on to OO, where I discuss how an algorithm can be parameterized with not just a value, but with a piece of code (i.e. creating an interface, and passing an implementation of that interface to a method). For the interface, I always use an analogy like USB.

Then we move on to the delegates, where I introduce delegates as if they were an interface with one method, Invoke(), and whatever you pass to the delegate gets called in that Invoke() method. Then we move on to delegate internals (how they are immutable, and multicast etc.) I also have examples and practices that we do to show them that every solution that uses a delegate can be translated into a more OO version using interfaces (again, referring back to interfaces).


How to embed TIC-80 into Computer science 101 course

Being on this site since the beginning, I have many times now encountered this notion that for introductory courses, higher level languages mean that students will deal with more abstraction and lower-level languages mean that they will deal with less abstraction, but I believe that this is fundamentally incorrect.
I'm going to actually recommend a frame-shift that I hope you will find helpful, and along the way, I hope to also persuade you to a different way of thinking about introductory programming courses.
I myself learned on BASIC and Pascal, so I have no specific objections to these languages.  There is plenty of learning to be had in such languages!  But there was also plenty of abstraction. It's not as if the "Read fetch execute" cycle, memory management, operating system architecture, or secure program memory segmentation are somehow magically apparent to a Pascal beginner, nor is that an appropriate goal for a beginning programming course.  All of these languages (even C) are truly "high-level languages" full of metaphors and abstract ideas, and none of them will give a student any sense of what is going on under the good.
Don't believe me?  Consider how much is "explained" to a student in this Pascal code:
type
   color = ( red, black, blue, silver, beige);
   car_color = array of [color] of boolean;
var
   car_body: car_color;

Contrast that with this Java code for Greenfoot, which is a system made to teach beginners in Java, and spawns a Zombie at location (50, 50):
world.addObject(new Zombie(), 50, 50);

How much of what is going on "under the hood" will be understood in either example by a beginner?  How clear is the expected behavior from what we type?
The purpose of high-level languages is:

To abstract away what is happening inside of the computer.  People didn't want to learn new assembly languages, architectures, and capabilities for every new processor.  Abstracting away what computer do is #1 on this list because it is the most important, and it is what drove us away from assemblies and into high-level languages in the first place.

To make some kinds of tasks easier to accomplish.  The above code example is great.  The compiler makes and manages an array for you!  No multiplication to find the offset from the initial memory location on the stack needed!  And the fact that I can now, in that same Pascal program, write:

if car_color[blue] then
   writeln('blue paint has been applied' );

...is fantastic.  It's useful!  It makes the programmer's intentions clear!  But it tells me nothing about blue not existing in the run-time execution at all, since it was remapped by the compiler to a 4-byte integer, or how writeln sends information to the console.  The compiler allows me to work at the level of a metaphor, and handles the details all the way down.
I guess here's what I'm getting at: when you study any programming language, you are studying at the level of that programming language.  Importantly, all of the stuff below that level is 100% opaque, and this is by design.  It is in no way true that studying a non-OO imperative language will leave students feeling like everything makes sense, but studying an OO language will leave students feeling like everything is a mystery.
Both approaches uncover a tiny bit about one particular layer, and still leave basically everything as a mystery.  It will take your students many more years of study before they feel like they have a handle on what computers actually do.
This is not to advocate for OO specifically, but rather to suggest that you reframe your question like so: since no particular programming language choice is going to explain things at a higher or lower level than the particular metaphors employed by that specific language, which language choice will get my students a lot of mileage as they go forward, both in terms of what they are capable of in my course, and in terms of what explorations it opens up for them afterwards?
My recommendation for that question is probably Java, Python, or JS.  Since you're starting from the language Scratch, you might naturally go a game-building route to start, using PyGame in Python, Greenfoot in Java, or GDevelop in JS (Note: I have no experience with GDevelop, I just found it with a Google search).
Good luck with your course!  Hopefully it will be a very satisfying and enriching experience, both for you and for your students.


How do teachers motivate students to persevere and learn?

Your instinct are dead-on.  Students, at least in grades k-12, are not terrifically motivated by what they will "need" in the working world.  There are plenty of good reasons for this.  First of all, what they will do for their work seems very abstract and far-off.

Also, viewed from a vocational lens, there is a quite reasonable shot that they won't actually need the things we think they will.  They might not be going into (or might not think they are going into) the careers we are thinking of, and in any case, jobs are so heterogeneous that to make almost almost any statement of what work requires nearly meaningless.  Add into the mix the speed at which the world seems to be changing, and our predictive abilities just get worse and worse.

But not everything is lost.  People, including kids, are intrinsically motivated to learn when conditions are right.  But we have to get a lot of different elements all moving in the same direction, and for some students, this is easier to manage than for others.  Some students love school and think of it as a place where they can thrive, but some others are a little broken and burnt out, or feel unsafe either about approaching difficult topics, or about their surroundings, and these problems can make intrinsic motivation very hard to tap into.

The end-goal is to help kids feel safe to try their best, that the ends are actually achievable, and that the material connects to their current world.

-- Organizing the world for motivation --

Teacher Beliefs

Let's start with a few ideas that have to come from the front of the room.  Certain teacher attitudes permeate the classroom.  These attitudes are not sufficient by themselves to motivate kids, but if they're not there, nothing else is going to go right.

The teacher believes in the material being taught.  They think that it is both useful and interesting.  (And hopefully a little amazing, too.)
The teacher believes that the students are absolutely capable of learning the material.
The teacher loves their students, and genuinely wants to see those students thrive.
The teacher praises good student practices above and beyond student accomplishments.  There is a lot of research to back this up; students who receive praise predominantly for being right, for being smart, or for being the best at things often become wary of difficult material and of the unknown.  Why throw yourself into something if you can't succeed like you have in the past?

By contrast, if you are typically praised for good process or for working hard, then when the material gets hard, that praise still feels quite accessible.  You can still organize your own learning and work hard.

Student Beliefs

There are a few things that the students need to know, and these should be directly taught and modeled at every opportunity.

They are safe in school.  There are people who care about them, there are people who are their friends, and there are people that they can go to if they are down or get into some sort of trouble.  (Particularly in the k-12 arena, this requires some active monitoring on the part of the teacher, and may necessitate some intervention as well. People don't thrive when they are frightened or lonely.)
Intelligence is not fixed.  Intelligence is more like a muscle, because you can flex it and make it more powerful over time with work.  Improvement is always the goal, not just the end-product.

Classroom Practices

Once the beliefs above are in place, we can actually do the work of motivating the students:

What makes something intrinsically interesting is connections.  The more connections that can be drawn from the material to the world that the students already know about, the more intrinsically interesting the material is.

Those connections can be to the students' social worlds (that's where you end up with entertainment tie-ins; if the kid knows that "all the other kids" think that Beyoncé is cool, then class material that relates to Beyoncé is now instantly connected to that child's social world.)

Of course, it's better if the connections are deeper and more thoughtful, but if you're working with kids who are difficult to motivate, take no shame in working any angle available to you.

The more the connections, the better.  The richer the connections, the better. The more surprising the connections, the better. Connect ideas to what they've seen in the past. Connect ideas to weird things you've just shown them. Connect ideas to the world around them. Take pains here to make the invisible absolutely explicit.
Help students to monitor their own progress and set their own short-term goals that lead to the big picture that the students can actually accomplish.  (This is hard to do. Even adults are often bad at assessing their own understanding, so teachers can create activities to help kids reliably monitor their own learning.)
Keep your criticisms of students both constructive and loving.  Always make explicit how your criticisms are really aimed at helping the student, NOT cutting them down, and make clear that there will be accompanying support to help the student learn to do better.

It is achievable

It is.  It's not easy, but it's possible to get kids really excited about learning all sorts of things.  If you watch some videos of amazing teachers (YouTube is an incredible resource here), you can watch this motivating work taking place at every grade level and in every sort of classroom imaginable.

Learning to apply these ideas to your classroom is hard.  Watch an amazing third-grade music teacher, and then watch an amazing 11th-grade math teacher, and their practices will seem very different at first glance, but the core underlying ideas are actually the same.


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.


First programming Language : C or Python?

The question is actually more complex than it might  appear, and really the answer can depend on the context. For example, at what age are the students when they are first taught to program? Is this in Primary School, High School or part of an undergraduate programme? The answer might be different in each case.
It also depends on the purpose of teaching the initial programming language (IPL). Is the purpose to lead towards a practical skill (vocational programming), or is it to enable the teaching of some knowledge of algorithms (pedagogic programming), is it to enable the functioning of some devices (engineering programming) or is it to prepare students for further study? Each of these questions could lead to a different language as an IPL.
For a very early age start of programming one does not have to worry about employment or future curricula so something engaging is important, so tools such as MIT Scratch have a role. For later childhood Python fills a nice niche, particularly as it can run on a wide variety of inexpensive  platforms (such as Arduino's, Raspberry Pi and so forth) which  provides accessibility and make it within the reach of the classroom and individual students.
Conversely, if one is looking at an undergraduate IPL then it may depend on which degree programme is being considered. Is it a degree in Computer Science, Engineering, Biology, Chemistry or Physics? One would then need to take into account what graduate employers might be looking for and tailor to that market.
Python might have value in some of these programs but the students would also have to learn other languages at some point. For example, Computer Scientists would need a wider experience that would embrace C#, C++ (among others). Electronic Engineers might need C, but Computer Scientists less so. Biologists might need R, Chemists and Physicists might still  need Fortran!
However, I would say that I might never recommend C as an IPL, and would start at C++ even for the most hardened Electrical Engineer. I only show Computer Science students C in specific contexts (like working with flex and bison)!
One thing I say to my students in the course where I look at Languages is that there is no one best language. The choice of language for any particular situation is so very context dependent on resources available, skills available, the purpose of the programming and the end goal of the task, and for an IPL that advice still holds true.


Neither is always better, and both have their strengths.

The idea of scoring higher marks as a criteria for better is going to be unpredictable without knowing who is granting those marks. Someone who is heavily in favor of one style over the other may grant higher marks to low quality uses of their favored style than they would to high quality answers in the other style.

The idea of being faster is both personal and situational. If someone is more comfortable using one over the other, they will usually be faster with that style, whichever it is. Some projects seem to do better in one style than they do in the other, even when the person doing the project is proficient in both styles. This is related to the strengths and weakness of each style.

Pseudo code is more free-form, and allows one to concentrate on how to solve the problem or design the algorithm without having to choose the proper symbol to draw, or how to leave room for other branches on the chart. Pseudo code is also closer to the programming statements that will be used, eventually, to implement the algorithms, and can speed up the coding process. Being free-form makes it harder to spot missed checks on conditionals. It is also harder to see the overall pattern of a larger algorithm in pseudo code.

Flowcharts diagram the algorithm in a visual manner that makes the entire algorithm visible. When the logic gets complex, this visual representation enhances the ability to trace all branches and confirm that every conditional has been fully handled. It can also show cases where things are getting to complex, and need to be re-factored. The downside to this visual representation is that the creator frequently needs to interrupt their work on the algorithm to make adjustments to the chart, or to redraw sections that no longer fit on the page/screen they are using. These points are even greater detractors when the flowcharts are created on paper rather than in a program designed for flowcharts.

The apparent speed gains from pseudo code's closeness to the final language can be offset by the error checking, and corrections needed, but not spotting logic error in the planning, which is one of the strengths of a flowchart. In addition, the larger picture view provided by the flowchart that can lead to re-factoring, can lead to more compact and efficient code, which is a gain every time the program is executed, even if it took longer to code the first time.

Ideally the students should be taught each method, using exercises that are both a good fit and a bad fit for that method. After leaning the two methods they should have exercises that help them learn how to select the proper one for a given situation. While it may not be appropriate for the classroom, often a programmer on a larger project will use both methods: the flowchart to see the whole picture, and plan the program's overall flow, and pseudo code for many of sections seem to be compact or straight forward.

Bottom line is that the best one to choose is the one that gets the job done right the first time. A fast solution, which then needs lots of corrections is not so fast after all, and a pretty picture of the program can still have logic errors if the programmer is not looking at the real problem the correct way.


Looking for software that would enable me to cast a screen over LAN

I know of two bits of software that can do what you want.
They do what you are looking for, display stuff on their screen and do demonstrations on their screen. They also lets you spy on your pupils, blank screens, lock screens (useful if they are not paying attention), and shutdown computers at end of day.
AB Tutor
I have used this software, in the schools I have worked in.
On the negative side it is proprietary, and expensive.
Veyon
I have not used it. But it is Free Software and cheep.
See http://veyon.io/


Is there any value in teaching goto statement or flowcharts?

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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.


JavaScript to teach Theoretical Computer Science

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

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

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

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

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


How to provide individual grades for group project work?

In "Assessing Individual Contributions to Group Software Projects" (WCCCE '03), William Gardner discusses a number of strategies for adjusting team programming project grades for individual performance and ends by recommending a "share-out" approach:

  The essence of share-out is that each student is conceptually given a
  pot of points, and must allocate them among their peers based on some
  stated criteria. The allocation then represents that student’s
  numerical evaluation of his or her team members.

  In order to provide a straightforward, effective criterion for the
  sharing out, each student was given 100 points and told to allocate
  them according to the amount of credit each team member deserved in
  terms of the total project work. The term “credit” was intentionally
  selected to be both intuitive and elastic, a single metric that could
  easily serve as a proxy for time and quality of effort....

  Students were required to give themselves at least 100/N points, in
  recognition that there would likely be little enthusiasm for
  self-incrimination, but then the self-evaluations were not averaged in
  with those of the team members. With this constraint in place, ethical
  struggles over whether to admit one’s own poor performance were
  shunted aside. If some students really performed poorly, their team
  members could do the dirty work; their own confessions were not
  required, nor could their grade be inflated by making phony claims.

The paper provides further details.

Update: Since the paper is 14 years old, I contacted the author to ask if he has any updates. He kindly replied that he had not taught a software engineering course since then so had no further experience to report and that he stands by his recommendation.


How can I speed up the construction of high quality testing materials?

I have a few suggestions based on my experience this year. I have one prep over two blocks, which meant that for every exam I wrote, I wrote two versions. Moreover, because I take a standards-based approach, students end up retaking the exam but a modified version at that. For some exams, I ended up with 4 versions. Here's how I sped up my own process:

Focus on proficiency. Not every questions needs to "trick" students. (Indeed, "tricking" should never be the goal of an assessment: it should be an accurate measure of what a student knows and can do at a particular moment in time.) If I believe proficiency is 70%, then 70% of the points should be relatively straightforward questions that all students should earn. Maybe another 20% consists of slightly more challenging questions, saving the final 10% for the questions that might focus on the most subtle of details. By focusing on what all students should be able to do, I can worry less after the "craftiness" of my questions and get right to the heart of the matter.

Write questions designed with substitution in mind. Let's say I'm asking questions to test a student's knowledge of basic Linux commands since it's necessary for our IDE. Whether I ask about ls, cd, mkdir, touch, etc. should be irrelevant; they are all fair game. Thus, one approach is to tell students to review from a list of terms, and come up with a potential set of 4-5 answers. Then, from class to class, you can simply change what term you are asking about. The answers don't change, but the questions do. No student will know in advance which terms will be asked about just that they will be asked about.

Keep the method, but change the input. I recently assessed students on Python, and I wanted them to be comfortable with two key concepts: the use of range() for iteration and the basics of string access and manipulation. I didn't have to change the instructions from class to class very much, but by changing the input, I gave the two classes unique exams. They knew to expect questions on strings and iterations, but until they are faced with the actual input, this bit of information does not necessarily help them answer the question.

I may have more ideas come to me as I read more responses, but here's my final, overarching thought:

EXAMS ARE NOT SURPRISE PARTIES. Students, assuming they have been present and attentive in class, should not be surprised by the content of your exams. Let them be occasions for students to show you what they can do. While we as educators might stress over the perfect question to ask about, say, an ArrayList, it should always come back to this: "How I can fairly and accurately assess what a student knows?" It is not, however, a chance for us to show how clever we are. Get to the point. Be clear; be fair. Let students prove how much they have mastered. Keep that mantra at the forefront, and test design can become simpler and faster.

ADDENDUM:

Learn LaTeX. I use LaTeX for the creation of all my exams. While the first couple exams took some time to get just right, now that I have written a large number using it, I cannot imagine using anything else. It takes care of the formatting, the indenting, the point scale, everything. I don't waste a lick of time worrying about how it will print or format, especially when I need to include code samples. The time you invest in learning it will speed up the time it takes to format your exams.


These are both part of Apple's Everyone Can Code initiative, and both are appropriate for a high-school and college audience.

The Intro book is intended for non-programmers, and teaches programming fundamentals and Swift syntax, with 90 hours of lessons included.

The non-intro book gets into more complex UI development such as working with table views and navigation, and topics like consuming web APIs, and includes 180 hours of lessons:

App Development with Swift Curriculum Guide (where I took that screenshot) also shares helpful outlines of the two curricula that can give you a sense of the differences at a glance.

Here is the Overview from that guide explaining the difference:

  The Intro to App Development with Swift and App Development with Swift
  curricula were designed to teach high school and college students with
  little or no programming experience how to be app developers, capable
  of bringing their own ideas to life.

  The Intro to App Development with Swift course introduces students to
  the world of app development and the basics of Swift and Xcode. The
  course culminates in a final project where they can choose one of two
  basic iOS apps to build.

  App Development with Swift takes students further, whether they’re new
  to coding or want to expand their skills. If they’re already familiar
  with Swift, Xcode, and iOS development, they can move through lessons
  quickly or go straight to the labs, where they’ll build miniprojects
  and test their code in playgrounds. By the end of the course, they’ll
  be able to build a fully functioning app of their own design.

The document goes on to further explain the two courses as follows:

  Intro to App Development with Swift

  This introductory one-semester course is designed to help students
  build a solid foundation in programming fundamentals using Swift as
  the language. Students get practical experience with the tools,
  techniques, and concepts needed to build a basic iOS app.

  App journal activities take students through the app design process,
  from thinking about the purpose of an app to market research and early
  user testing. By the end of the course, students will have created a
  plan for an app they’d like to develop. Even though they might not yet
  have the skills to build the app, the work they put into the framework
  will set them up for future development.

  App Development with Swift

  This two-semester course features 45 lessons, each designed to teach a
  specific skill related to either Swift or app development. Each type
  of lesson takes a different approach:

  Swift lessons. These lessons focus on specific concepts. The labs for each are presented in playgrounds so that students can
  experiment with code and see the results immediately. Playground files
  are provided.
  App development lessons. Focusing on building specific features for iOS apps, these lessons typically take students step by step
  through a miniproject. The labs help students apply what they learned
  to a new scenario.


Is there a better way to validate student learning?

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

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

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

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

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

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

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

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

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

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

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

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


How to convince students that self learning is an important skill?

In a few days there is almost nothing you can do. Certainly you can't change their habits and attitudes about how to learn in just a few days. You can try, however, to change their behavior by making their current behavior unprofitable. If it is still possible, make the final work an important part of the evaluation. But that is only a band-aid on the problem, not a cure.

It is true that a number of students want to "be learned". I tell students that "I can't learn you." But my own behavior, not just talk, has to reinforce that. If I teach primarily through lectures and evaluate them based mostly on what they can retain from the lectures, then it is perfectly natural that they take a fairly (or completely) passive role in a course, leaving all of the "learning" up to me.

But if you teach the course again, you can start early and come to a real solution - of behavior, at least, and possibly attitude. Rather than give lectures, give projects, from the beginning. Answer questions often, if not always, not with the answer, but with the strategy for getting the answer. To be successful they will need to change behaviors learned in other courses that aren't very effective in the long run. With adult students the effect is probably even stronger, as they have a longer history of passive learning.

So, from the beginning, stress projects, teamwork, finding your own answers, verifying your own programs, telling you things rather than asking you things, and so on and so forth.

Search around for "Active Learning" and learn to teach in a compatible way.


Balance between teaching and projects in a club

I am currently a co-leader of a programming/FIRST club at my high school, and for us the key has been project based learning. We are always working on something. It might not be relevant to our upcoming competition, but we always contextualize lessons in terms of what we're working on. That way everyone stays interested in the current project and sees the utility in the lesson being taught.


How to explain what code is to my parents?

Coding is like writing a recipe for the computer to follow so that it solves your problem. The computer "reads" each step, and follows it, eventually reaching a solution. Some programs are better than others, just like some recipes are better than others - they are faster, they produce a better result, etc. Programmers aren't really the cooks, though - the computer itself produces the result. The programmers are more like the cookbook authors, producing the recipes (programs) for the computer to follow.

Now, I don't know about you, but I've followed a recipe before, and there have been times where I've been left wondering, "Have I put in 2 or 3 cups of flour?" or having mixed in an extra couple of chocolate chips (quite by accident, of course). A computer doesn't have these problems. It can make your "recipe" much more swiftly and accurately than you can. However, this gives you no excuse for providing the wrong recipe. No amount of accuracy will make brussels sprouts into ice cream, unfortunately.

Lastly, @dckuehn brings up a great point. No analogy is perfect, and this one is no exception (heheh). Whereas, in a recipe, you really try hard not to vary the input so as not to vary the output, most programs take different kinds of input and produce different kinds of output, according to the same rule. Sort of like you can put a bunch of different cookies in the oven to bake them - not the same input, not the same output, but a fairly similar process inbetween.


What are some fun projects for non-CS majors?

Another fun game is "Spelling Bee" from the New York Times
(https://www.nytimes.com/puzzles/spelling-bee). You supply a file containing words. The student program reads the file and selects words that match the rules. The milestones are from a past project from Reed College.

Print all the words that can be spelled using a fixed string (e.g. "AZDIRWY"). The first letter is the required letter.
Prompt the user for a string and print a list of words or take the string as a command line parameter.
Generate a score for each word and the total score.
Generate the graphics to draw the string as it appears in the paper (six hexagons containing optional letters surrounding a central hexagon with the required letter), along with the list of words.

You could potentially go a slightly different direction and let the python program generate HTML output and view the results in a browser. This illustrates dynamically generated HTML.
Another variation would be to preprocess a "dictionary", removing all words that are too short or contain more that seven distinct characters. Then create multiple files, one for each possible beginning letter. You now have cut down the search space. You might also have the students sort the answers, perhaps by word score.


What is the best way to learn an object oriented programming language with framework, data structure and alogrithms?

You certainly don't need a list longer than this one. If you do even half of this you will have learned enough to know pretty much what should be next. Having a complete list now gives you very little.

What you really need is practice and feedback. For practice, find some significant problem and build a program to solve it. Use the best methodology you know about (including testing) and if it works, fine, otherwise look at some other methodologies. You can often find problems in books or online, but knowing that something is significant is harder for a self learner.

But the biggest impediment for the self learner is getting adequate feedback. Just because something works isn't evidence that it is actually good or well structured. For feedback you need someone with more python knowledge than you have and who can comment on your code and even on your approach. That is one of the big advantages of taking regular courses. A teacher/professor can provide problems that are just hard enough to stretch your skills, but also give you the feedback on what you are doing and point to the next steps.

But reading about all those things won't make a programmer out of you, nor will building a "complete" list.

Write programs. Get feedback. There is no shortcut.


How should one go into learning algorithms and data structures? What do you think is an efficient way to do so?

First, if you aren't taking a course, get a good book that has a lot of exercises. Use the exercises to guide your learning. Try to find a way to get some feedback on your attempts.

The way you learn just about anything deeply is to get a lot of reinforcement and feedback.

On the other hand, it is seldom necessary with today's languages and libraries to implement standard data structures. It is however, necessary to understand the fundamental of each and their relationship to various sorts of efficiencies when applied to various sorts of problems.

One way to get a deep understanding is to learn the technique of developing algorithms (not just data structures) from pre and post conditions.

My go-to book for doing that is by David Gries. It isn't cheap, but it can change the way you think about programs. I've mentioned it elsewhere here.

If you don't have other ways to get feedback, you might be able to form a group of like minded people who exchange work and comment on each other's attempts.


What non-programming book is vital for learning the CS mindset?

The hardest part of determining anything in computer science is the requirements first.  If you don't know what the program should do, then there is no way to do it correctly.

Thus, Winnie the Pooh is a wonderful book on the matter.  It clearly describes time and time again how simple misunderstandings of the base assumptions lead to absurdities of action.  From tracking a woozle of one's own making (and debugging where the error was actually being originated) to trying to define a heffalump and building something completely wrong as a result.

With the summary of Winnie the Pooh in "In which Christoffer Robin gives a Pooh party, and we say good-bye" we realize that our jobs as writers of code is to take the stuff of dreams and make it into reality.

Winnie the Pooh has the advantage over many other books by being accessible by all levels of readers and can often be found in less expensive books compared to many other textbooks.


Why don't more universities teach revision control?

I suspect it's a combination of several factors:

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

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

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

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

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

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


How can we teach good naming practice for students learning Java?

Fair warning, I do not demand any particular naming convention (such as NetBeans) from my students.  This leaves me with variable naming only for the purpose of clarity.
I speak constantly to my students about the two different audiences for code: the computer itself (which is the one kids naturally think about), and other is human beings, which students find more difficult.  And I also strongly believe that this is the single biggest impedance to good naming: students don't think that it matters, because they think they are writing for a computer.
I also grade all of my labs using code interviews, and my students are aware that I will be looking for clarity above almost all other considerations.  (There is good reason for this; deeply clean and clear code also has very few bugs. When you engage in the difficult process of cleaning and refactoring, you can polish your code until there is basically no room left for them!)
My intuition is that good code correlates much more with good writing than it does with good mathematical skills.  Good code demonstrates a clean rhetorical structure.  This part of the code cleanly and clearly accomplishes this task, while that part carefully lays out the thinking and organization for that task.
This could simply be a function of the kinds of people who are naturally attracted to coding, but I have found that asking kids to write clean code is often very difficult for them.
What works
I have found that the following question is a useful overriding guide for most of my students:

"If you were not someone who had just spent the last 15 hours looking over this code in detail, what are the odds that you could figure out what it was doing at a quick glance?"

Naming norms
This is the best tool that I use, and these work for all of my students.  There are a few direct practices that I ask for in all submitted code:

With regard to booleans, what do we know if this variable is true?  Create a name based on the true condition.  (e.g. if this variable will be true whenever the foo is inside the bar, we would name the variable fooInBar)
With regards to accessor methods, what information is being returning?  Simply name this information.  (totalTrials(), unusedElements(), nextItem(), etc.)
With regards to mutators, what command (verb) is being issued? Use this verb, possibly with an attached noun.  (increment(), consume(Item i), fixVertex(), etc.)
Single letter variable names should be used only for throwaway counters and such. (e.g. for(int k = 0; k < items.length(); k++))
For other variables, we enter into broader territory, and things can get trickier.  Which brings us to...

Miscellaneous variables
Unintuitively, I have had mixed luck with the question,

"what does this variable actually represent?"

This is the question that I ask myself while I code, and it works for many students, but for students who really struggle to come up with good names, the question does not seem to grant much insight.
This doesn't mean that I don't use the question, but it has become a last resort. Students who present poorly named variables often seem unable to cleanly articulate what a particular variable is accomplishing.
If I'm honest, the fact that this question rarely helps strugglers makes little sense to me (and is rather disheartening), but I have come to accept it as a fact.  Going back to my intuition that strong writers create clean code, there could be some language difficulty going on here, but that is only a hunch.
For such strugglers, I might help them by having them describe the variable in broad terms, and writing what they say.  I will then sit and progressively distill what they have written with them until we arrive at a good name together.  Unfortunately, this practice is time intensive and does not scale well, but it works, and I haven't found any better solutions for my strugglers.