Introduction to programming class: use Spreadsheets to introduce fundamentals Are there any "pros" or "cons" I have overlooked regarding using Excel
  as a means to introduce a range of fundamental programming concepts.

This question relates to teaching a programming module at secondary school final year level (one level below first year of university).  I use Python.

Learner profile

Learners often have no programming or web design background.
Some lack essential computer literacy skills- creating and saving files, installing applications and so on (I get a diverse group and have no say in selection)
Learners are all adults, ranging typically from 21 to 61.
Many have been out of education for a number of years.

Rationale

Many beginners find using the terminal and IDEs to be quite alien.  Add to that the need to understand key concepts and apply them, it may present a "barrier to entry".  Using an application that they may have encountered before and likely have on their own computers (when they have one) may allow learners to grasp key concepts in a more "familiar" environment.

Syllabus

These vary widely, so rather than include "fluff" on the particular one I have to work with, I'll expand on the relevant elements below, which are likely relevant to any introductory programming course.

Relevant topics to explore in the Introduction

I'll try to be succinct but can expand on any topics in the comments

Variables: cell ref ~ address in memory- not user friendly. Name a cell- can be used in expression, like a variable.
Operators and BEMDAS
Syntax
Boolean AND OR NOT
conditional statements
built-in functions
create a User Defined Function (possibly- not sure on this one).

Pros and Cons

I've mentioned some of the pros, as I see them.  I cannot think of any cons at the moment:

  Are there more pros I've missed, are there possible downsides, and has
  anyone tried using this before?

Spreadsheets are probably the most popular functional programming language, and is is some what visual. I have taught it for years 7 to 9, but not part of a qualification based course.

Things to be aware of:

It is a functional language, as long as you avoid VBA / macros etc.
You can do functions, though I am not sure about named functions.
I like to put intermediate calculations in to hidden columns. The alternative is very complex formulae / functions, that are hard to read, and hard to write.
The hard part is making it relevant. Don't make all of the exercises about accounting.
Provide spreadsheets that are started, and give them exercises to add/change something.
Don't assume that this is relevant, to them, or that they have any experience. Ask them, give them a choice about how they learn.
If the data sets are too small, then it will not seem relevant, as you could do it my hand more easily.
There is a lot of copy/paste in spreadsheets, this is the main downside, but to use them well you need to embrace it. This is not so for any other, good, language. In the first lesson, have them enter formula, for about 10 rows. Then show them how to use the little dot in the bottom right of the cell, to make it easier. They love this.
Whenever I am teaching programming, I tell them that I am teaching them to be lazy. This helps to engage the lazy ones. Sometimes a hard worker will comment on this, but I tell them “don't worry, one we have learnt to do it the easy way, then this allows as to do more stuff.”.
Most of what you do in spreadsheets can be done in python (except data entry), so you can link it to the python lessons.

While being a good introduction to functional programming. I do not think it is a good introduction to programming. It may be of some help, but I do not imagine the pace of learning will be high.

Most people start with Scratch. The main barrier with this language is that it seems childish (it is taught to primary school pupils ( ≤ yr 6 ). There is another language call snap. It is like scratch, but taught to 1st year undergraduates. It has some extra features, such as create your own functions. With Scratch you can create your own procedures, but not functions. Both of these languages are available as a web service, scratch also has a desktop app. Both you can download and host locally (if internet access is poor).

With snap you can make it look like any other language. I have made it look like python. Unfortunately I could not get all of the blocks to work, but I did use them to create a printed work sheet scratch to scratchy python to python (they did not know that I used snap to help me create it). You can also teach snap to auto generate code in another language. E.g. write program in snap, click generate, and get a python program (I have not properly tried this).


What advantages/disadvantages have you seen with Pair Programming in the classroom Many of us use or have used Pair Programming in the classroom.

See https://www.agilealliance.org/glossary/pairing for a discussion if you like.

@BennettBrown has pointed to research showing its advantages, but not all users may have had positive experiences.

If you have tried it, what have you experienced both on the positive side and the negative side.

Perhaps more important is what else do you need to do in structuring your course to make up for any disadvantages or support any advantages. These might involve ensuring fairness in sharing work or in grading.

I tend to use it at every level, but there may be issues you see in various courses.

The answers seem to indicate a fair amount of misunderstanding of Pair Programming. It is not just two people assigned to a task. That can lead to division of labor, which often fails. If two people just divide up the work and do it unwisely, they have the additional task of integrating their work which can be very difficult. Neither is it one person just working and the other just "reviewing". It is a much more cooperative endeavor.

If you want to really understand Pair Programming, the book Pair Programming Illuminated is a great place to start. If you want to see Pairing integrated into a complete Agile Programming workflow of a small team, Extreme Programming Explained is good. I actually prefer the first edition if you can find it.

I give 11 lab assignments in CS 1, and I assign partners for the first four or five so that students get to know each other, and then I let them choose their partners, or choose to work alone.  I try to discourage them from working alone, but some students just don't want to deal with people, and I feel bad forcing them.  (I also give six projects, worth more collectively than the 11 labs are, and they must work on these separately.)

This is all anecdotal, because I only teach one section of CS 1 a semester, but: I don't see any patterns.  Some more socially awkward students find the right partner and have lots of success building skills and confidence during the semester, whereas others don't, and struggle alone for the rest of the semester.  Frequently, students who come in with previous knowledge (say, those taking the class the second time) will ignore their partners, or do the work and hand them the answer; but others seem to have the "teaching gene" and almost act like TAs for me with the weaker students.  It depends a lot on who the students are, and how lucky I get when I pair them up.

I do give each student a questionnaire the first day, so that I can try to match up the students with similar experience, or students that have already passed Calc I, or something, but (again, based on anecdotal data with a very small $n$) none of these seems to have much of an effect.

I'll be watching this discussion to see if anyone has done a lot of research on who to match up with whom, because I haven't figured it out yet.


What resources would you recommend for K-5 Computer Systems Concept of the CSTA K-12 Standards? In Maryland, we hope to be funded by a grant that will allow us to write a K-5 computer science curriculum to address the Computer Science Teachers Association (CSTA) K-12 Computer Science standards.  This board and the web have useful information for middle school and high school computer science, but more best practices are needed in the elementary school arena.

We are finding sufficient resources regarding the Programming and Algorithms concept, but there are fewer resources for the Computer Systems concept. If you use robotics or microcontrollers (Makey/Makey, Arduino, Micro:bit), share your evaluation of whether these are developmentally appropriate at the grade you used them, and how you aligned your instruction to the Computer Systems concept. If you used other technologies to make the concept more concrete, what technologies did you use?

I haven't seen a lot of resources in the US for that age group, though England seems to publish a great deal of high quality KS2 (Key Stage 2, ages 7-11) material.  What's particularly nice is the focus on Computer Science concepts and computational thinking over simple programming exercise, even at this young age.  Take a look at these BBC Resources from the "Bitesize" Series, which is a series of instructional videos appropriate to those ages).

There are also collected resources here, which includes such regulars as Scratch, but also points to some lesser-known resources, such as Code Club, which has projects appropriate for the age in various languages, and Kids Ruby, which teaches kids to program in the Ruby language with guided tutorials.


Teaching high-level versus low-level concepts In creating a general introductory course on computers or computing (programming and/or CS), does one mostly present high level concepts (recursion, computational complexity, concurrency, etc.), practical concepts (write some code in language X that accomplishes Y), or low level concepts (bits and bytes, logic gates, wire and blink some LEDs)?

If more than one conceptual level (which I assume is necessary to some degree), in what mix or proportion?  And what order might be best for what purposes or goals of the course?  How does one get students started and intested?

This earlier question is about the order of teaching, but before ordering, it helps to clarify the content of that which is to be ordered.

Also, have instructors found benefit including any other semi-related material, such as was discussed in this previous question on the history of computing?

TL;DR Build a world, let the students program in that world.
This is largely a history lesson which, at the end, will give hints about how to teach students to become effective in a modern OOP language quickly.
A deeper principle than Higher to Lower abstraction, however, is the principle of teaching in a Spiral manner. This principle says that the student's education should not be linear, with each thing taught completely only once. Things should be reinforced repeatedly, with each turn of the spiral adding new concepts to old, but those new concepts themselves returned to later, each spiral reinforcing older lessons as well.
Another principle here is that students learn by doing, not by listening or reading. There are a few exceptions, of course, and teachers often fall into the exceptional class, but it is rare. I've written in answer to other questions here that learning involves physical, biological changes in the brain, requiring reinforcement. There is supporting research of course.
History
With that, let me take you back to about 1975 or so. The language Pascal existed then, but C did not. Pascal was not, at that time widely used in education. FORTRAN was. Early attempts to teach using Pascal resulted in "poorly spelled FORTRAN" programs, since that matched the thought processes of programmers and teachers well versed in FORTRAN. It is said that a new paradigm only takes hold after the people holding to the old one die out. This was actually the case with the Theory of Relativity in Physics. Einstein was dismissed (that "clerk") by the superstars of the physics establishment until Poincaré's influence waned (and he died).
Pascal was created with the purpose of having a tool to directly implement Procedural Programming (PP). The essence of PP is this. Envision a Problem, P, as decomposed into a set of sub-problems, P1, P2, .... The sub problems have one of two characteristics. Either they can be immediately solved, Sk = solutionOf(Pk), or they can be, recursively, decomposed into yet smaller problems. Additionally it is assumed in PP, that there is a Known Composition method for putting the solutions to the smallest, undecomposed, problems together into a solution of the larger problem of which they are a part. In other words, decompose into sub problems going down and then recompose solutions going up.
Thus, a Pascal program was intended to look like a collection of simple procedures that invoked other simple procedures until you reach a state in which the lowest level procedures can be written in the primitives of the language. This was also called Top Down analysis and programming.
HOWEVER, early Pascal programs didn't look like that. There was a single massive procedure, or even just a BEGIN ... END. block that did everything, with only trivial parts factored out, usually those things that needed to be executed more than once. Hence, misspelled FORTRAN. Advice in early teaching materials was to factor out a procedure when it could be used several times, otherwise just inline the logic.
That was the state of affairs in about 1980. Then something magic happened. Richard (Rich) Pattis wrote a book called Karel the Robot (1981) that showed how it could be done. The book came with a simulation program in which students could write "Karel Programs". The Robot Programming Language defined in the book and accepted by the simulator did not reveal primitive, machine level, constructs such as integer and real. There was a single robot that moved in a virtual grid-like world. There were five primitive actions: move (one block), turnleft (90 degrees), pickbeeper, putbeeper, and turnoff. Nothing else. beepers (a primitive kind of thing with no behavior) could be carried but there was no protocol for asking how many the robot carried. That was implicit in the program state, not something that could be queried. Beepers could also be found on the corners of the world. It was an error to try to pickbeeper with no beepers present.
In addition to the five primitives, the robot had a rudimentary sensing capability. It could sense a beeper on the same corner and it could sense a wall directly in front. Trying to move through a wall is a program error.
Notably, the robot programming language has no variables. Repeat: no variables. You can treat a corner, conceptually, as something like a variable since it can have several beepers and that can be treated something like an integer, but there is no protocol for converting it to an actual integer, and no way to build it.
With these tools, the programmer is able to write procedures (returning nothing) and predicates (returning booleans). There were no parameters of the procedures. Using the sensing capabilities, the student can utilize selection and looping to build sophisticated programs. Karel the Robot defined a Turing Complete language. More important, the book had a wonderful set of exercises. My contention is that if a student could solve every problem in the book they could, with their learned creativity, write any computer program (Turing Complete, remember). The book built programming skill, not just familiarity with machine concepts and language features.
The book has five chapters and in the original it was possible to cover it all in a bit over two weeks, at which point the path to Pascal was trivial. But at that point students could already produce a correctly structured PP program. No more misspelled FORTRAN.
The result is that students, in their first turn around the spiral, learn program structure with few low level details (five primitives, procedures, predicates, if, and while). The second edition of KtR by Pattis, Stehlik, and Roberts (1995) contains the first edition and adds specific hints on PP such as how to go about the problem decomposition and how to build IF and WHILE structures. But you can do anything. Sorting is fun, with beepers standing in as a kind of surrogate for integers, though you can't really count. Recursion is supported, though not discussed in the original. An interesting problem is to search an infinite space for a beeper.
Creativity Under Constraint
Another aspect of the teaching philosophy underlying this principle of Creativity Under Constraint. A naive view is that you can do more with more tools. However, learning to use a few tools to a very high level of skill builds mental structure that a fuller tool set will not. If a student depends on solving the next problem with the next tool, they will be a bit lost when there are no more tools available and you have to really think.  Creativity Under Constraint tries to avoid this.
As a simple example, consider poetry. If I ask you to write a poem you have few constraints. But that problem is hard hard. But if I ask you to write a Haiku, I give you constraints, but I also give you guidance and structure. The problem, though constrained, is actually easier (but not trivial, of course). This is a Big Idea.
It was vital that KtR provided this rigidly constrained world in which programming occurred, but not so rigidly constrained that any programming idea could not be expressed.
And of course, no one suggest you should only and always write Haiku.
Paradigm Shift
It is natural when a new paradigm arises (Relativity, Procedural Programming, OOP, Functional) for the practice to be thrown into a state of flux for a while, but hopefully not forever. The paradigm shift from a simpler form of imperative programming (FORTRAN) to PP was long and hard. Rich provided a tool that showed the way. It was widely adopted and helped teachers over the hump.
The interesting thing about a true paradigm shift is that it renders the earlier paradigm obsolete. A mounted knight in shining armor stood no chance of success against Henry V and his army of peasant longbowmen. And in turn they stood no chance against properly deployed musketeers. But deploying longbowmen the same way you deploy knights is just dumb.
In CS, however, a paradigm shift may not have such a profound effect, but over time, it will. Actually the last English king who was fully trained as a knight was Henry VIII and that was about 100 years after Henry V and the battle of Agincourt.
But, my way of thinking and teaching is to treat a (lesser) paradigm shift as if it were truly profound. Learn it. Adopt it. Teach it. Your students will be looking forward, of course, not back. And as I've said here before, my job isn't to teach them what I know, but what they need to know. Today that is a good solid view of OOP, for the most part.
And, programs no longer look like FORTRAN, but they, sadly, too often look like Pascal.
The Present State
We have gone through another Paradigm Shift, though it is now quite old, but too many people have not made the jump to OOP from PP. Too many programs are just PP programs with a few classes. Moreover, I see methods that are too long and too complex, putting the complexity into the methods themselves, rather than into interactions between objects viewed as bundles of behavior. Java, and later languages enable this, but using it effectively is an acquired habit (and taste).
The successors to KtR are Object Oriented. Karel J Robot (java), Karel R Tuesday (ruby), and Monty Karel (python), by Bergin, Stehlik, Roberts, and Pattis, all provide a structure, along with a simulation, in which good OO programs can be written using inheritance and composition, but with only a few ideas other than the essential ones. None of the books use integer primitives in any way. Variables are references to objects. These books are more complex than the original and require about half of a first course to cover. But at the end, the student has a clear grasp of the structure of an OOP program and can think about problem decomposition into a set of interacting objects. (These books permit the creation of several robots, not just one.) Once they deeply learn what is presented in the books it is a relatively easy task to introduce lower level concepts (int, array, ...) but also things like Collections and within reach. One drawback of the OOP Karel books is that inheritance is, perhaps, overemphasized, at the expense of composition of objects to build other objects. My personal view is that OOP enables composition primarily and inheritance secondarily, though the latter is more obvious in the syntax provided. Early on, however, Polymorphism is discussed deeply and implemented via composition using primarily the Strategy design pattern. Concurrency is also discussed briefly, since there are multiple robots.
Another feature/bug of the current books is that they use the actual languages (Java, Ruby, Python), rather than a constrained subset. While only a subset is taught, instructors are free to add things not in the books, such as integer valued variables and counting. This is a mistake, as the example below will demonstrate. One of the important (vital) choices of the designers what what NOT to teach or even include in the book. The Java book has a follow up, however, which fills in quite a lot for a full course.

Example:
To illustrate some of the above ideas and extend them a bit also, consider an exercise from Karel the Robot.
The robot, Karel, is at a corner facing East. Somewhere directly in front of the robot is a beeper (possibly even on the same corner). The Karel's task is to move to the beeper, pick it up, turnleft and move the same distance that was traveled to get to the beeper initially and put it down again.
Note: no variables, no integers, no counting is possible, except via recursion with the count held in the runtime stack, implicitly. And, of course, the previous sentence is an explicit hint.
The advantages of this are legion. You have a deep way to talk about recursion, especially the fact that recursion has two "phases": winding - to get to the base case, and unwinding - to return all the calls. To do this exercise you need to do actual work in both phases, so you can talk about the fact that both are useful (and can introduce tail recursion which this example does NOT exhibit).
It is interesting in a way in which a standard recursive computation of, say, Fibonacci numbers is not.
It is an interesting problem because solving it changes the brain of the solver. However. If the student already knows how to count and has tools (int variables...) to solve it, this problem is completely boring and adds nothing (other than a bit of reinforcement) to changing the brain.
Moreover, later on, the instructor can return to this example (around the spiral) when counting is later taught and show how counting both simplifies it and makes it more dangerous, since such things as off by one errors are now more likely.
So, what seems simple, becomes profound because it is introduced into a constrained system. The constraints both give guidance/structure AND deepen learning in ways foreseen (we hope) by the designer.
Copacetic.

Notes: While Pascal set out to be the "best" language for  PP, it turned out to have flaws, especially for team based work. Modula-2 is much better, but is a true successor. However, it took lots of users writing lots of Pascal software to reveal the flaws. C++ started out as a better C+Simula. Object Pascal (from Apple) started out as a simpler Smalltalk, and Java is in that family, as are Python, Ruby, and Scala.


One lecture on VCS: What needs to be covered? I've been asked to do a one-lecture (50 minute) presentation on Version Control. In the class we'll be using Git; there will be a hands-on opportunity to work with Git later in lab. (The Git GUI of choice of the professor is GitKraken).

I don't need to teach anyone to be Git Wizards. I'm not a git wizard myself. But I need to show the class what version control can do, and the basics of using Git to collaborate between multiple people.

@si618 provided a wonderful "Why use VCS" over on StackOverflow, which I am going to borrow (with credit, obviously, the CC license requires it). That covers the motivation portion.

Then I need to cover the actual model of sharing code via VCS. That's the hard part. LearnGitBranching is a wonderful resource I'll likely use to show commits and branches, but the main use of that site seems like (to me) experimenting with more complicated rebase-based operations. And a quick here's-what-vcs-is doesn't (shouldn't) need to rewrite history.

Explaining the model is the hard part; showing the application of the model is simple since I'll likely use the GUI. The command line interface isn't of import. But what really needs to be understood to understand a DVCS model?

commit -- add snapshot to your local history
push -- publish your local history to some location
pull -- download history from some source
branch -- split the line of history into two "timelines" for concurrent work
merge -- collapse bring two parallel histories into one

Is there anything else that really should be covered? These five seem like the key components. Is it worth mentioning that every local master downloaded from the repository is a new copy, and is effectively a branch origin/master -> local/master? Is it worth mentioning that a headless git repository is no different than a local one, and that you can pull directly from a non-origin repo? Merge conflicts happen; should I mention how to go about resolving those?

Distilling an (admittedly shorter than my seniors') career of working with Git into a short "Here's why Git is awesome and you should use it" is difficult. I want to teach Git (and more generally, VCS) and not just "how to use GitHub". Thinking Git === GitHub is one of my pet peeves.

Context:

The structure of the course itself is rather open-ended: the second half of the course is opportunities for students to share something they've spent some time learning on their own (that's where I fit in). Since I potentially have the greatest cross-section of teaching ability and domain knowledge among the students, I was asked by the professor to do a section on Git before the lab where people get to try it out themselves. During that time as well, students will be working in groups to complete a large assignment, so I definitely want them to use some sort of VCS; it'll save everyone a bit of trouble.

The course is an upper level university CS elective.

On How to make git easy to learn:

I believe the two questions are meaningfully different. The other question addresses a (self) learning approach while this question seeks a teaching approach.

More importantly, answers on either question aren't generally applicable to the other. Trivial answers may be able to answer both, but any real meat on an answer makes it only really applicable to one question.

As requested, I'm expanding my comment into an answer. This is going to echo a lot of what I said in this answer, so you might also check that out for some background motivation.

Version control systems are tools that are designed to solve specific problems.

They're great for stuff like:

Storing multiple revisions of a file.
Allowing collaboration among multiple people.
Handling cases where multiple people are editing the same file or even the same section of code.

If the students haven't encountered these problems, then they might not be ready to start using a version control system.

Another consideration is that students need to understand basic directory and file structure interaction before diving into version control. Do they know how to navigate a directory structure? How to edit and copy files? This is less "common sense" than you might expect, but it's definitely a prereq to talking about version control.

All of that being said, I think you should start by explaining the above problems. Discuss how they might "solve" those without version control. Ask them if they've found themselves trying to manually merge files where multiple people were contributing, or if they've found themselves with files named HomeworkAssignment_FinalDraft-3-ReallyFinalThisTime-6.txt. If students have seen these problems, they'll naturally see the benefit of version control.

Present version control as a solution to the problems that they're already experiencing.

In other words, don't make it theoretical. Make the lesson practical and pertinent to what the students actually do.

Go through some example scenarios. Explain how they might use Git to solve the above problems, and focus on real actionable things they can do:

Here's how you'd set up a code repo so you and your team can edit files without breaking everything.
Here is the command you'd run if you wanted to upload your edits.
Here is the command you'd run to download changes from other people.
Here is how you'd resolve merge conflicts.

Even better: have students run through these scenarios live. Have them typing commands and pushing buttons instead of just listening to you. This should be information that they can actually use, not just theory that they'll forget as soon as they leave the classroom.

Don't spend an hour talking about theory. If students have never seen version control before, then they don't need to know how Git stores changes. They need to know how to setup a repo.

On the other hand, don't spend an hour telling them about all the different things Git can do. If you throw a hundred different commands at them, they'll remember zero of them.

Instead, introduce specific problems (that the students have already seen in their own coding), and show the solution to those problems. Have students work through those solutions and practice the commands right away.

  Is it worth mentioning that every local master downloaded from the repository is a new copy, and is effectively a branch origin/master -> local/master?

Students should understand branches (bonus points for using branches to do pull requests and code reviews), but do you really need to get into this level of detail? Imagine students writing this down as you lectured. Would they really need to know this later, or is it just clutter?

  Is it worth mentioning that a headless git repository is no different than a local one, and that you can pull directly from a non-origin repo?

Meh. This seems like trivia to me. Do I need to know any of the above to solve the problems I'm having?

  Merge conflicts happen; should I mention how to go about resolving those?

Yes, absolutely. Like Michael said, this is a very common problem that students will face, so they should definitely know how to handle this case.


on-What are pre-requisites for teaching version control to a high school CS class? I'm interested in introducing version control to a HS CS class, and was considering starting with Github since it's a fairly standard tool used by developers.

What are pre-requisites for understanding version control that I should make sure students master first?

Any suggestions on other ways to introduce this topic to students are definitely welcome!

The biggest one for me would be a reason to use version control. When you're writing small lab assignments, version control probably isn't worth all that much. It's when they get to a point where projects become larger than a handful of methods, or when you're working on separate pieces of a larger project with partners that it becomes useful.

Version control, specifically Git and GitHub, is definitely on my list of new topics to add to my 2nd year course next year. My students are doing collaborative projects right now and it's painful to watch them email code back and forth.


Is it ok to use logic programming(like Prolog) as students' first language? Some use FP, some use OOP, some use procedure.

It seems few universities start with logic programming, why?

I do and am currently teaching a high school student Prolog but not as a first language.

  Is it OK to use logic programming(like Prolog) as students' first language?

While you could do it I would not advise doing it, let a student do it if they asked or be on a committee that would advocate for it.

The reasons are

Prolog is so much unlike other programming languages that there are very few other resources that a student could use as references for learning it and they would be very dependent on the teacher for learning. Many of the students I teach talk to others to round out their understanding of what I teach and while I would like to think that they clearly understand everything I say and get it correct the first time that just does not happen and so the students look to other means to augment their learning. With Prolog it is not only hard to find other good resources, but also students (and especially high school students) are hesitant to seek out help of knowledgeable peers.

With regards to books, there is only one book that I would use as an introductory teaching book and that is "Prolog Programming for Artificial Intelligence (4th Edition)" by Ivan Bratko (Amazon) (WorldCat). Java or Python have several tens of books and several are suitable for an introduction. Then for advanced books, Prolog only has a handful and of that only a few are of value. To learn the true art of programming in Prolog is something that only one or two books really are of mention.

There are a few sites for learning Prolog, but many only skim the surface and of the web sites that teach Prolog most I would not recommend for a self-learner as they can leave you with more questions than answers. For more advanced topics the only web site of value I note is The Power of Prolog by Markus Triska

While there are several places to get online help with Prolog, the one I use is StackOverflow with the Prolog tag.
The key concepts to learning Prolog are not intuitive. Object-Oriented has state, and functional is stateless with pattern matching (one way). Prolog is stateless with unification (think bi-directional pattern matching). Thinking in recursion has to be natural, processing lists must be second nature, constraint problems are common, difference list, use of syntactic sugar with DCGs, the operator definitions such as xfx, xfy, xf are different than most languages, reification, SLD, logical purity, program slicing, predicates vs. functions, MGU, and other concepts not seen in other common languages.
One first has to learn unification and get it correct before moving forward. The problem here is that sometimes the class has to move forward before a student understands unification and then the rest of the course is endless confusion to the student. Also unification is symbolic and getting students to understand that abstract concept is sometimes very hard. On one test I gave to drive the point home, part of the unification test was with English letters, part with Greek letters and part with symbols like a snowman. After unification comes backtracking or backward chaining which gives Prolog non-deterministic programming. List processing is typically next and that is another topic that can lose many students. When teaching list processing I teach induction with a base case and induction step(s). Cut is another topic that loses many students and can make or break many programming solutions. The point here is that you may have to proceed slower at first and then pick up the pace or risk losing many of the students and there are many key concepts that rely on previous key concepts where only a complete understanding will suffice.

Note: I normally provide links to the keywords but here have purposefully left them out so as to give others a taste of what it means to try and understand Prolog by trying to put these ideas together by themselves. I think Prolog is great and use it weekly but I know when and where to use it appropriately.
The best concepts of Prolog are typically incorporated into other languages as libraries or calls to external systems. In particular constraint solving is very useful but systems like Z3 can be used instead for other languages.
There may be other languages that can do what Prolog can do and do more. e.g. Mercury or expand on Prolog as a proof assistant, e.g. Coq
Very few companies seek out employees who know Prolog. Universities want their graduates to get hired. Why teach a student something that won't get them hired? Also since many companies don't use Prolog, if you know Prolog and try and advocate for it in a company, you are probably going to be on the losing side. Not that I find any of this agreeable, but that is reality.
With regards to AI Prolog gives closed world answers and while that is beneficial for some AI problems, IMHO is an Achilles heal for others. As an example, when it comes to classifying pictures I would not use Prolog but a deep neural network.


Quick and easy intro to computer science for kids for an Engineering Field Day We have a large engineering day that hundreds of kids (ages 6-12) and their parents will attend.

The setup is as follows: local engineering groups/societies will have stations and they will have short activities for these kids to introduce them to engineering concepts. We are looking for 1-2 activities for one of these stations. There will be internet connection and we have a small budget (~$100) for getting supplies. We can borrow computers/tablets. Ideally we will have two activities that build on each other and ideally the activities can be scaled so both younger crowds and older students can enjoy and get hooked. It would be a big plus to engage and educate parents as well. It would also be a plus if the activity did not require lots of hardware ($$$) so it is not too hard for students to continue learning at home.

I wanted to do something programming/CS related but I am having a hard time coming up with activities that introduce them to the subject in a couple of minutes. Are there such activities or should I focus on something else?

The help and ideas are much appreciated!

Since Logo was intended for this age group you might explore something there. My quick idea would require two or three screens with some sophisticated and time consuming simulation running on one and the kids/adults exploring simpler exercises that might (or not) build up to the one running. You can run, for example, a space filler (Sierpinski) program and have the students explore turning, etc. With lots of trial and mostly error.

In Karel J Robot, the recursive graphical solution to the Eight Queens problem takes a bit of time and is built up from only a few primitives that can be combined and extended. So that would do for the running demo and the students can explore simpler aspects, such as a robot backing up, for example. The advantage of Eight Queens is that it is easy to explain, unlike, say, sorting.

You can do this sort of thing in most languages - a complex graphic simulation built up from simple parts. The students explore only a bit of it. They can even modify some of the code of the running sim and run it to see what happens. It can lead to a lot of laughter, and some insight. If you sit with them you can suggest things that do something fun/weird/good/bad and ask why that happened. Lots of possibilities.

But the running sim gives an unattainable target in the time frame. Like playing on the beach after professional teams of sand-castle builders have shown their skill.

The suggestion is that if the simulation is built with something like Model-View-Controller that the students only modify parts of the model.


Using Processing as an entry point in an Introductory Course We have two entry points for programming students here: one is web-oriented and features HTML5/CSS3/ECMA6, and the other is in a robotics environment using LabView.  Both classes address the "big 5": variables, objects, functions, conditional logic, and iteration.

We are thinking about a new entry point for a new audience. What features of the Processing language lend themselves to an introductory course?

I am currently designing an intro to programming course for middle school students using Processing. In particular, I am using these two resources to focus the curriculum:

Make's Getting Started with Processing: A Hands-On Introduction to Making Interactive Graphics

Raspberry Pi Foundation's "Introduction to Processing" Resource

Make's resource moves all the way from simple, one-line programs like ellipse(50, 50, 80, 80); to OOP, file IO, JSON, data visualization, etc.

To supplement these resources, I am using videos from Daniel Shiffman's YouTube channel The Coding Train. Of particular value are his short coding challenges where he completes a programming task in the allotted time while talking through the design process.

I find that Processing's power comes from its scale combined with its ease of entry. I can confidently say that students will be writing "real" code on day zero and getting instant results on something other than the command line. Plus, there's the satisfaction of starting to learn programming with a text-based language instead of something like Scratch which can feel restricting and elementary to some students. And, as Daniel Shiffman's videos show, there's really no stopping how far you can go with it.


What would be reasonable to include in an Introduction to AI class for a 7th-8th grade after school program? The class meets just 8 times for 2.5 hours weekly, aimed at 7-8th graders with very basic programming skills.  Possibilities off the top of my head: computer learning (neural nets and/or genetic algorithms), constraint/logic based programming (well, it came out of AI, right?), a Brief History of AI, and/or basic game states and alpha-beta pruning.

I probably can't fit it all in, and I don't want to make it so difficult as to be discouraging.

I don't have a lot of insight into your overall problem, but there is a resource you might consider.

There is a simple game, The French Military Game, in which a person plays against the computer. The totality of game information is small enough that the computer can remember every position in every game played, so it doesn't make the same mistakes in subsequent games. While it is a known win for the human player, after 6 or so plays it is very difficult to beat the computer.

The game is available (Java) in a couple of forms at the Greenroom, a place for educators using Greenfoot. Membership is open to any interested teacher.

The FMG once appeared in Creative Computing, now defunct, as an Apple II BASIC game. It uses a bit of math, but ok at the level you are interested in.

It is, at best, a simple, even naive, introduction to machine learning.

Disclaimer: I'm not associated with Greenfoot or the Greenroom.

The game is also discussed with code in Beyond Karel J Robot though that book probably isn't a good resource for your class.

Another user here (@Ben_I.) points to an applet version with a brief explanation of the game.


Incorporating algorithmic complexity in grading What are some advantages of incorporating algorithmic complexity in grading tests and assignments given to students?

Currently, students in 11th grade at my school are required in tests to write functions that should preform some operation (usually operations on data structures like LinkedList, Stack and Queue).

This works fairly well in terms of checking whether a student knows how to use those data structures.

However, it's not uncommon to see an answer that does, eventually, preform the required operation; and yet its complexity is $O(n^3)$ (no kidding. The specific case I'm thinking of is one where the student worked with the unsorted linked list of stacks1 in 3 nested for loops).

The students are required, after they write their functions, to also write the complexity of their solutions.

In a quest to improve the students' thinking skills, I thought that maybe we should give bonus points if the solutions are inventive and less complex than a head on approach. This means that if a student's function is $O(n)$ for a task that a direct assault would be of $O(n^2)$, they should get more points.

This can also apply to various assignments we can give them, in addition to the tests we already have (or maybe make the tests slightly easier and then add assignments).

The students are in a CS major, and they have experience with java, OOP, Data structures and basic calculations of complexity for various, simple, algorithms)

1We gave them some arbitrary way of comparing stacks (of Integers): The sum of elements.

I wouldn't want to penalize kids who are really relatively inexperienced for not coming up with the fastest solutions on a test. Even if they're in 11th grade and have a couple of years under their belts, they likely haven't been in real situations where run time is important.

If I were to want a specific run time on a test I'd say something like "for full credit make sure your solution runs in $O(blah)$ time."

If I give an open ended solutions and I don't specify any restrictions on run time, storage limitations, or data set size I tell the kids that I won't penalize them for efficiency unless it's so grossly horrible. For example, if they were to write a sort in their code (and I wouldn't really ask this but it makes for an easy example), I wouldn't penalize a kid for coding an $N^2$ sort even if we covered $n log(n)$ unless I talk about a large data set size. On the other hand if they sorted by say an $N^3$ solution or worse, they would lose some points.

In any event, if you're requiring certain run times you have to be careful that you're not just getting kids to memorize and spit back what the teacher expects.

Also remember that there are plenty of times where a simpler, slower algorithm is both clearer and more than sufficient and that complex fast code that doesn't work isn't nearly as good as simple code that does.

To encourage creativity, give multi level assignments. Create lessons where you can have them develop a solution, see that it's too slow, and then refine it. I do that with finding the mode of a data set (https://cestlaz.github.io/posts/2014-11-17-hidden-complexity.html).

You can also create assignments that encourage this and make test data sets and situations that force kids to work on time efficiency issues.


How to best use lab periods One of the major uses of my classroom time is for lab work. This is both a requirement of the AP Computer Science curriculum, and also nominally a benefit, as it allows me to walk around and answer questions.

In practice, however, I have found that the students work on their tasks, and whether they are doing well or not, they don't ask questions, even when prompted individually with a "how's it going? Do you need any help?"

This eventually results in me going to sit down at my own station to do other work for about 10 minutes, and then making the rounds again.

This feels like an underutilization of myself as a resource. It's not as if I don't have students who struggle, and there are always students who fall behind and submit their labs late.

So, how can I better utilize the lab time? Are there techniques to get kids to ask questions when progress slows? Or is there something else that I should be doing altogether?

The problem you describe doesn't exactly fit this answer, but it might be useful to some with a similar problem.

In some such labs it has been observed (and filmed) that students working alone at a station get into some difficulty and raise their hand for help. If the instructor and/or assistant is busy with another at the time, the student with the new problem waits. Then maybe another, and two are waiting, etc.

The solution to this is to have students always working in pairs in the lab, doing things like pair programming, pair research, pair writing (very creative), etc. This has been observed to reduce the waiting to essentially zero as the students solve their own problems. When one student gets "stuck" it is unlikely that the partner is stuck in exactly the same way so they can move on. This is a well known effect in professional pair programming also.

You still need to wander about asking if you are needed, as a pair will sometimes queue a question till you come around while they work elsewhere.

Sorry, I don't have a link to the study on this. I assume it came out of the Agile Community's educator forum.


How far do you take modular expressions? I'm sure that basically every introductory course involves teaching about the ubiquitous mod operation.  In my experience, and I'm sure I'm not alone in this, I've found that teaching my students that "mod is the remainder of division" is insufficient if I want them to make any use of the concept later on.

Beyond showing them how to use mod to check divisibility, I have for the last few years gone into far more interesting operations in order to help them achieve some intuitive understanding of what mod is and how it works.  So, for instance, I show them how they can increment within a modular circle of numbers from 0 to n-1 (a circle of size n):

[some loop structure] {
    x = (x+1)%n;
}

Or, how to move that circle along so that it ranges from m to (m+n-1) (still a circle of size n, but it no longer starts at 0):

[some loop structure] {
    x = (x+1-m)%n+m;
}

Or how to decrement along a 0 to n-1 circle in a language like Java, which deals with negative modular operations by returning the highest negative congruence (ie. -10 % 4 would return -2 instead of 2.  While they are both technically correct answers, Java's answer is decidedly inconvenient for the purpose of moving along a modular circle of numbers, because when you try to move from 0 back to n-1, you get the wrong result.)

[some loop structure] {
    x = (((x-1)%n)+n)%n;
}

Or, doing the same thing by moving n-1 steps clockwise around the circle instead of moving 1 step counterclockwise:

[some loop structure] {
    x = (x+n-1)%n;
}

And, of course, we can generalize this to involve any cyclical pattern of numbers that can be reduced to a proper modular circle where $f(n)$ is the function that takes any number within the cycle to its corresponding location in the modular circle, and $g(n)$ is the function that takes it back:

[some loop structure] {
    x = g(f(x+1)%n);
}

Now, I am reasonable certain that nobody uses structures like this in any production environment.  Part of my justification for going to such lengths with mod operators has been that I am not a teacher of software engineering.  I am a teacher of computer science, and having a firm understanding of modular arithmetic is important for Some Big Ideas later on.  (Like Two's Complement, which has a very intuitive and coherent explanation when you think about it in terms of cycles within a number space.)  And when all is said and done, many of my students really do come out with a good, intuitive sense of how the mod operation works.

But I also wonder if I have just gone plum crazy.  This stuff takes a lot of class time to get the kids to master, and I'm really wondering if the time would be better spent on other pursuits.

How far should modular arithmetic be taken in the CS classes that are early enough along in the curriculum that they still focus on programming?

A specific example that I've used the mod operator before for (and have seen it used in production code this way) is to represent a higher dimensional array (usually 2D, but higher is possible) as a one dimensional array, and then use some modular arithmetic to retrieve the higher dimensional structure. The reason one might want to do this is if your array structure is a substructure of a more complex object, it might be simpler to implement it one dimensionally, and then add more complexity onto that.

I've seen this done when one is "tiling" some 2D space, where each tile maps to some properties, and where each tile's properties may change in time. This could end up being a very complex structure: potentially, a mapping from time, to the first dimension of the tile, to the second dimension of the tile, to each of the properties of the tile. In such a case, the geometric "2D"-ness of the tiling may not be that important (except for perhaps the display), and so the implementation of the internal model of these tiles could be one dimensional instead, simplifying our model.

Here's a simple 2D array example. Say one has a 3 by 3 array, where the "property" is represented by some integer:

1 4 9

0 2 7

5 6 4

Our 2d array may be indexed with [row, column] as follows:

[0,0] [0,1] [0,2]

[1,0] [1,1] [1,2]

[2,0] [2,1] [2,2]

However, we can represent it with only a single parameter as:

0 1 2

3 4 5

6 7 8

(left to right, then top to bottom is just a convention of course)

Now, how do we retrieve the row and column numbers given one of these indices? This shows some nice symmetry between the / operator (that is, truncated division on integers) and the % operator.

If we're indexing rows and columns as in my first example, the "row number" of an index i above is given by i / 3 (again, truncated), and the "column number" of an index i above is given by i % 3.

In general, if you have an n by n array, and you index it as I did above, the row number is given by i / n and the column number is given by i % n.

Another example, and this one gets closer to the intuition you're trying to achieve, is simplifying computations for cyclic functions. If your functions are over the integers, then your operator % is good enough. However, this wouldn't work for continuous functions. Nicely enough, one can take your discrete cyclic model and make it continuous in programming languages by using fmod or an equivalent.

Specifically, for students with enough background in Calculus that have some familiarity with Taylor series, one can think of how one would write a trig function like cosine. One might realize that the 6th degree Taylor polynomial approximation is "close enough" in the range between $- \pi/2$ to $\pi/2$. Then, one can "mirror" that to get one complete cycle of the cosine curve between $-\pi/2$ and $3\pi/2$ (for example.) Then, with this, one might ask how one would compute the value of $cosine$ for any real number, and the answer is quickly obtained by using some modular arithmetic to get your number in that range, and then use our restricted cosine function for that translated number.

This use of mod also relates to Guy Coder's answer: thinking of taking the mod of a number as involving several subtractions is precisely how one might implement the continuous fmod function (however, whereas a discrete mod function's usual "remainder" intuition may be lost here, the intuition regarding the cyclical nature of mod should be strengthened).

In general, I like to think that the kind of mental modeling required to think about mods is going to help these students regardless of whether they literally use them later on in their programming careers.


In a course about Turing machines, how many questions like "Construct a Turing Machine that does X" should I include? In a course about Fundamental Computer Science, which includes Turing Machines,
how many questions like "Construct a Turing Machine that does X" should I include?

There should be at least a few basic constructions, like doubling a string of ones or checking whether a number is even, checking whether one number is larger than another, to show how a Turing Machine works. However, I'm unsure whether to include more difficult problems, like:

Given two positive integers, check whether one is divisble by the other.
Given a positive integer $n$, check whether $n$ is prime.
Given a positive integer $n$, compute the $n$th Fibonnaci number.
Given two positive integers $m,n$, calculate $m^n$.

Also, should I just allow the blank symbol and one other symbol or should I allow any number of symbols? Or maybe a mix. The difficulty will largely depend on this.

Students learn thinking abstractly about these problems. However, this abstract thinking is different from the abstract thinking that is used in most programming activities, so I'm unsure.

I integrate many, many simple TMs into both my lecture and as homework.  I also force them to use descriptors such as $\vdash$ and $\vdash^*$ on their machines.  I've found that it takes a long time for students to get used to basic operations.

They have no problem converting a given TM to its tuple members ($\delta$, $\Gamma$, $\Sigma$, etc.), but have surprising trouble seeing the performance implications of transitions on machines that I provide to them.  With practice, they get much better at this, but it takes (in my experience) a surprising amount of practice, both in encoding and decoding simple Turing Machines.

Some particular traps for my students have been:

navigating halting states (since they cannot transition outwards)
identifying ending conditions of loops
making comparisons between two strings stored on different parts of the tape
learning when it is appropriate to overwrite your data.

All of these take practice.  I do this in-class so that I can assist and guide, but I also have many hours of facetime with my students.  In a more constrained timeline, I would give out homework assignments instead.


How can I convey the idea of a programming language vs. a markup language? When I try and teach web development to absolute beginners, I seem to always get a question about the roles of HTML/CSS/JS and about how the browser renders the HTML. It seems to me that the confusion lies in an explanation of what a markup language is as compared to a regular language (e.g. python, C, java, ruby). What is the best way to give an overview of what HTML is while being sure that my students understand HTML as a markup language?

Would it be useful to include some of the history of HTML? Preface it by teaching markdown? Or some other way?

I also have this problem frequently.  I use the example of Microsoft Word, and I would say something like this:

"Word allows you to give a document the appearance that you'd like.  You can bold, you can center, you can change font sizes.  Word is creating a markup (in this case, it is generating a type of markup called XML).  "Markups" mark up text, just like it sounds.

But, could you create Word itself in Word?  You can edit fonts, you can center text... but does any of that give you the capability to make a whole program like Word?  Similarly, you can't use Word to make Firefox, Chrome, or the alarm clock on your phone.

Markup languages only format documents, but when you need to actually make a function calculator, or an iPhone app, or a video game, that's when you need code instead."


Is there any series of videos in which all the main algorithms are discussed without going into things like time complexity and space complexity The course should be discussed in c language.
I am presently learning basic computer programming through a book and while doing the questions from the book from a chapter say array, I found out most of the questions are based on algorithm, so I want to study all major algorithms before attempting these computer

Your question doesn't make much sense. First, there are literally thousands of major algorithms, and many of them are quite involved. You don't begin your studies with Red-Black Trees because even their purpose will elude you until you've (at the very least) spent some time dealing with sorts and searches.

Second, if you eliminate time complexity and the actual steps to make an algorithm possible, what is left? A vague discussion of the purpose of the algorithm? Needless to say, no such discussion would include any bits of actual programming, especially not in a low-level language like C.

Speaking of which, why are you focused on C? Do you have a particular reason for this choice of language?  C is a "low-level" language, which means it works quite closely to how machines think, and quite differently from how people think. This is sort of like taking a math class that provides only axioms, and makes the student prove all of the important results on their own. I am not suggesting that there is no value there, but (1) it is much, much harder, and (2) you're more likely to simply give up in frustration when you can't seem to do anything at all, even after months of effort.

Beginners, particularly if self-taught, should start in higher-level languages where they can begin to learn how to actually undergo the process of programming without having to worry yet about pointer arithmetic and memory management.


What screencasting tools can be used for online teaching I wish to make a video like this one from codeschool.com.

In this video, the creator looks like he is using some screencasting software where he can write on his screen and talk over what he is doing while he is doing it.

What tools are required to make such videos? In particular, are wacom tools suitable?

Fingers crossed that this one doesn't get closed. I've tried to do something similar, but it hasn't come out well. Hoping that some others have suggestions.

It looks like they're using some sort of overlay or whiteboarding software, and I assume a tablet or stylus. I can see a cursor where their pen is drawing.

I've tried this, and it didn't go well. But, I think that's more a factor of my handwriting than of the idea. Enough years of typing being my main method of written communication has made my handwriting terrible. And it's even worse on a Wacom tablet. Same thing with some student created videos. They're just hard to read.

I'd like to find whiteboard software that also allows typing. Haven't found one yet, although I haven't looked all that much either.

A couple things that have worked...

If I'm in a hurry, Powerpoint has enough animations built in that it's possible to do a fairly decent job. And, they can be exported to videos if you want to upload to YouTube.

When I've had more time I've used Flash. It's deprecated now, but I still have an old copy on my computer. Takes longer, but gives me a little more freedom in what I build. Also can be exported to a video, which is especially important since browsers are starting to frown on Flash.

Edit:

Just played around with the pro version of Acrobat and it looks like it has a pen and text tool that might work for what I'm trying to do. Most of the time I'm just trying to annotate what's already typed out.

Edit 2 - After "screen casting" was added

This year I started capturing my screen as we work through problems and then uploading to YouTube for kids that missed the day or just want to go back for a refresher. I'm using a program called OBS. Works really well. A little Googling brought me to a Windows program called ZoomIt that will let me write and type over the screen as I'm demoing. Think I might bring my Wacom tablet to class tomorrow and give it a try.


Is CS50 AP available for new teachers for 2020-2021? I've taught AP CSP for a few years and am interested in teaching CS50 AP, but I'm having trouble getting started.   The links in the getting started guide at https://cs50.harvard.edu/ap/2020/ aren't working.
I've tried to email ap@cs50.harvard.edu, but no response yet.
Anybody have a suggestion?  Of course I can use the freely available material, but from a recorded workshop I watched there are tools for teachers that could be useful.

I just noticed that CS50 AP has just come back to life at https://cs50.harvard.edu/ap/2021/ with new access information and so on, so I'm all set.


Teaching the tradeoffs of the foreach loop Edit: It's been quite a while since I posted this question, and in the intervening time, I have come to love the foreach loop. However, in order to avoid invalidating answers, I leave the text unchanged below:

I personally dislike the foreach loop, so I tend to avoid them when I program.  However, in spite of this preference, I still end up teaching about them as part of the AP Computer Science A curriculum.

 for (Type item : iterableCollection) {
      // Do something
 }

I am particularly interested in experiences from those who have actually taught this in a classroom (though, as always, pedagogic thoughts from others are also welcome).  What do you do to teach about the limitations, costs, and advantages of this loop structure?

I will put my own answer below alongside the others.

I think the advantages are huge, overwhelming.

They avoid

off by one errors - the bane of the novice programmer
needing to allocate an explicit iterator - avoiding adding names to the namespace.

They enable

thinking about iteration at a higher level than just counting
compact coding

I use them whenever available. The collection knows its members. Just ask it to yield them up. It is a brilliant design.

Programs in object-oriented languages like java should not have to all look like C programs, nor should the programmer have to always dip to the level of C to use them. C is a better assembler (for the pop-11). But few programs need that mind-set.

My preference is to teach concepts from the top-down. Higher level thinking means (in part) "closer to the language of the problem". Then, when necessary go to a lower level - closer to the machine or closer to the level of the solution. In practice you seldom need to go down the scale very far for students to get it. And you never need to recapitulate the entire history of computing to have students understand how to work in modern languages, whatever the paradigm.

I actually try to move even further up the abstraction scale as illustrated in this  post https://cseducators.stackexchange.com/a/1379/1293

I include this in a library so that students learning other things can do simple iterations even before loops are discussed. It is quite useful to be able to do something a fixed number of times without formally counting it. However, it is only especially useful if you want to delay for and while so that you can teach, say, object-oriented abstraction principles.


What are some examples that could be used when teaching subroutines or methods in the context of OO? I'm going to be teaching a group of high school students about programming, and I have a general curriculum designed already, but I can't quite figure out how to introduce methods. I'll be teaching ruby specifically, but language agnostic answers are good as well. A general theme of my teaching will be allowing students to do things the "hard way" first, then showing them an easier way. For example, I plan on teaching them how to print to the console, then I'll ask them to print a word to the console 20 times. I'll use that to introduce looping. Is there a similar way to introduce methods? I'd like concrete examples/activities, along with general advice about how to use those examples.

I almost always teach programming by connecting each component of programming with something in real life. For instance, when explaining variables, I ask the students to imagine them as boxes in which you put things, like food items or gifts or something similar.

For methods, I ask them to think of their friends. For instance, there will be a 'rich' friend, and then there are 'stingy' friends, 'useful' friends and so on. So, bring up a scenario. For instance, lets say the challenge, you are in trouble and you want to ask for help.

You have 3 friends - rich, stingy and useful. Instead of friends, think of them as methods, and you (as in the individual) is the program or the main method. Now, you need help, which friend aka method are you going to call...you will obviously call the 'useful' friend/method.

So, essentially, whenever you want something to be done, you design/code a method for that, just like how in life, you want something done, you call upon a friend. So, methods are like friends who help out get things done.

Of course, in an actual classroom, I pick students, make them do role-play (pretend that they are functions) and make it all very active (and hopefully fun) and it seems to work for me.

and of course, once they get the concept, I jump into code right away, building small methods that do simple print statements, then upping it to display simple variables and then complex stuff including sending and getting values


Motivating examples for switch/case in Java Students first see switch/case as a second syntax for if/else, but eventually they should see its strength in creating cascades.  I know of the traditional example of printing a cumulative song, like "Twelve Days of Christmas", and below I've placed some code I use to illustrate the difference in use-case between if statements and switch cases.  It nicely prints out all 108 lines of the song Alouette in 44 lines of code.

The only other motivating example I can think of is a graduated tax calculator (based on the US Federal Income Tax), where cascades can be a nice way to approach the problem.

These examples are fine, but it's not enough to get the lightbulb to flick on for most of my students.  What I need is a few more motivating examples that really show students why switch/case is useful.  What other examples show this clearly?

    System.out.println("Alouette, gentille alouette,\n"
            + "Alouette, je te plumerai.\n");

    for(int verse = 1; verse <= 8; verse++){
        if(verse == 1){
            System.out.println("Je te plumerai la tête.\nJe te plumerai la tête.");
        } else if (verse == 2){
            System.out.println("Je te plumerai le bec.\nJe te plumerai le bec.");
        } else if (verse == 3){
            System.out.println("Je te plumerai les yeux.\nJe te plumerai les yeux.");
        } else if (verse == 4){
            System.out.println("Je te plumerai le cou.\nJe te plumerai le cou.");
        } else if (verse == 5){
            System.out.println("Je te plumerai les ailes.\nJe te plumerai les ailes.");
        } else if (verse == 6){
            System.out.println("Je te plumerai les pattes.\nJe te plumerai les pattes.");
        } else if (verse == 7){
            System.out.println("Je te plumerai la queue.\nJe te plumerai la queue.");
        } else if (verse == 8){
            System.out.println("Je te plumerai le dos.\nJe te plumerai le dos.");
        }

        switch(verse){
            case 8:
                System.out.println("Et le dos! Et le dos!");
            case 7:
                System.out.println("Et la queue! Et la queue!");
            case 6:
                System.out.println("Et les pattes! Et les pattes!");
            case 5:
                System.out.println("Et les ailes! Et les ailes!");
            case 4:
                System.out.println("Et le cou! Et le cou!");
            case 3:
                System.out.println("Et les yeux! Et les yeux!");
            case 2:
                System.out.println("Et le bec! Et le bec!");
            case 1:
                System.out.println("Et la tête! Et la tête!");
            default:
                System.out.println("Alouette! Alouette!\n"
                        + "Ah-ah-ah-ah\n");
        }

        System.out.println("Alouette, gentille alouette,\n"
                + "Alouette, je te plumerai.\n");

Consider why you might prefer to use a switch in a production environment:

Fall through processing. The blackjack example given by @Peter is a good example of this because it mirrors how we think about the problem: all of the face cards fall into the same case & the code follows suit. Be careful with this though, it's easy to abuse this to get terser code at the expense of readability
Default handlers. Personally, I find this most useful not in a 'single moment of code', but over a series of refinements. For instance, it's common to not have all your logic to handle multiple situations in place when you start coding, but it's also easy to miss a special case that you meant to add later. A default handler is a convenient & concise way to stub out code that you haven't yet gotten to.  Default handlers for that throw an exceptions or log the event can help avoid silent failures & are less likely to get 'coded out' by an mistakenly adding or removing an if or else.
Maintainability. I find it safer to add & remove code from a switch statement than an if / else if / else block as I'm more likely to accidentally omit an else from an else if than I am to omit a break from a switch.
As per Joshua Bloch's Effective Java: "Switches on enums are good for augmenting external enums types with constant-specific behavior." For example if you cannot change the source for an Operation enum, but need add support for an inverse method:

public static Operation inverse(Operation op){
   switch(op){
      case PLUS:   return Operation.MINUS;
      case MINUS:  return Operation.PLUS;
      case TIMES:  return Operation.DIVIDE;
      case DIVIDE: return Operation.TIMES;
   }
}

Readability. I find a moderately sized switch statement easier to grok than an equivalent if / else if / else block.

When possible, avoid contrived examples for motivating usage. Instead, show where you (or someone else) used a switch & discuss why it was preferable.


Using another person to motivate I am learning  various topics on my own, and so is another person that I know. We were planning on studying together around four days a week, a half an hour at a time (perhaps to be increased if all goes well) to help motivate each other.

However, we're studying entirely different topics. Like, not even machine learning and complexity classes different. More like accounting and computer science different. What are some ways to motivate each other and improve each others learning even though we're not learning the same things and we don't have a ton of interest in each other's topic?

I suggested occasionally sharing a "big idea" the other learned, but I was wondering if there were some other things we could do.

I would suggest that you start each "session" with each one of you going over what was learnt in the previous session. Devote ~15 mins for it.

This is not in spite of the fact that you "don't have a ton of interest in each other's topic", but because of it. This "review" of the last session gives, as I see it:

You are exposed to some other field. Who knows? you might end up finding interest in it. Even if you don't having someone listen to one's recount of one's learning provides a platform for a sanity check. The person telling their friend checks each part of what was learnt, as they talk.
It makes it easy to "get back in the game", and you continue learning after those 15 minutes, as though the previous session was just moments ago. This is especially useful, and is overall what makes this suggestion worthwhile.

Plus, showing interest in what your friend is learning is nice, and no one1 ever got hurt from learning something new in an unrelated field.

To elaborate on what I wrote as 1. above:

The sanity check and telling about what you learnt are also useful, because ideally, you'd lower the stem of details. You'd want to keep it to examples and simple explanations. This is extremely good for your own learning2 because as you explain the material, after reducing the number of details and making it simple, you focus on the core of what you learnt. It might be difficult at first, but that's why you each have 15 minutes. Don't be afraid to extend it to 20 if need be. This is a very important part of my suggestion.

Over time you'll be able to extract the core of the material more quickly, and that's a useful skill, unrelated to learning in pairs.

I highly recommend this technique (you can modify it to your hearts content; I won't hold it against you :P). I employed this method with a friend and, although we were both studying CS (but different branches; I was studying machine learning and statistic approaches and he was studying networking), it was very useful (also self-learners ;)) to both learning the subjects and the aforementioned skill.

1That's probably incorrect, but it's highly unlikely that listening to what a friend learnt in accounting would do any damage.
2and for your friends, when they talk about what they learnt


Interfaces and Greenfoot My colleague and I are considering bringing Greenfoot into our AP classes this year, and while Interfaces have been removed from the AP subset, we will continue to teach them.

Greenfoot itself seems to either not have, or to have thoroughly hidden, interfaces.  However, we are not interested in reinventing the wheel if it's not necessary.  Are there good lab activities that heavily feature interfaces already developed for Greenfoot?

Alternatively, are there any strong lab ideas for Greenfoot and interfaces that we could run with?

Yes, Greenfoot certainly has interfaces. I doubt that they would take them out. The people who built greenfoot are likely as appalled as I am about the College Board action on interfaces. But there is no UI element that specifically adds a new interface to a project.

But they may not appear in the same place that most classes do in the sidebar. Look at the bottom of the list.

Use the menu option to create a "New Class". Edit the resulting template to change it to a legal interface. Compile and save. This was with v 3.5.

You can do the same with other "class-like" things such as enumerations. The compiler hiding behind greenfoot is all of Java.

You can also go to https://greenroom.greenfoot.org and ask such questions there (after joining).

Also, many of the labs that you find on both the greenfoot and greenroom sites will use interfaces.


How to help students comprehend the HTML document flow? I'm teaching a student how to create website front ends. This student comes from a SNAP/Scratch/AppLab type environment where they learned basic programming concepts, but to position visual elements they had to either drag and drop or set an x and y coordinate.

This student has an issue where they make every HTML element positioned absolutely, so they can specify x and y (with left and top). This is not considered "best practice" in HTML and makes modifications to their work challenging, and causes other issues in their work. Generally, this is a bad habit I'd like to break them of.

How can I get this student to understand and utilize the normal document flow instead of just thinking about it as x and y coordinates?

Absolute positioning as bad practice

Referencing the StackOverflow question, "Is it considered bad practice to use absolute positioning?", the consensus is, just like nearly everything in CSS, "it depends".

But let's just throw some data at the topic:

More than 50% of website traffic is presumed to be from a mobile
device. Using absolute positioning (especially when positioning from
body) will impact how mobile viewers see your content.
There are
literally thousands of possible combinations for screen sizes and
resolutions. Positioing absolutely will break on most viewports.

These are the two biggest reasons to rely on document flow as opposed to positioning the elements yourself. But obviously, the student(s) are trying to solve a problem they have with the hammer they have.

So, maybe instead of trying to convince them not to, show them how bad it performs under real world situations and provide some alternatives.

Define the problem

Open a browser like Chrome, and using the bottom left corner of the browser window, resize the window. Elements positioned to flow around constraints will reposition, absolute elements will not.
Also in Chrome, open the developer tools and open the "device tool bar". This will allow you to look at the page in a simulated screen resolution for a number of devices.
Visit the web page on the student's phone. Switch the phone between horizontal and vertical views.

Better Practice

Use a grid. There a number of grids available like those that come standard with Bootstrap, but sites like css-tricks.com also have a number of smaller implementations that actually describe the basics of a grid, like this nice one from Chris Coyer.
Be right on the cutting edge and teach grid layout directives that are only in draft proposal (but work in some canary browser releases) this other tutorial on the Mozilla Dev Network.
Be less on the cutting edge and teach Flex.
Introduce viewports to trigger css changes at certain screen size

After some or all of these, reflect by going through browser resizing, etc. explained above.

Some other talking points

I'm not sure what kind of project the student is creating, but some other things to consider under certain circumstances:

Their experience with x, y coordinates will help them a lot if they are doing game development or graphics within a canvas tag or creating SVGs. Discuss when those are appropriate to use in HTML (SVG icons for links under certain viewports, eg).
Discuss content visibility and re-flow on devices of different resolution. Moving or hiding information based on user context (are they on
a desktop with lots of viewable space and a mouse, or are they on an iphone 4 and just want to click the 'buy' button?).


Is it worthwhile to teach assembly nowadays? In the 80s, it was common for CS students (and anyone wanting to do "real" programming) to learn assembly. After all, if you needed speed, hardware access (including direct output to monitor) or working on low powered hardware, you needed Assembly.

But nowadays, in 2018, assembly is pretty much useless except to bootstrap an OS or for compilers (and even that isn't as important as it used to be since LLVM took off).

So is there still a use in programming Assembly?

I think so, yes. However, I also believe teaching assembly isn't valuable because it could hypothetically teach students how to write "faster programs" -- compilers these days are smart enough that most of the time, you're just better off using a systems language and relying on the compiler if you're interested in that.

Rather, I believe the value in teaching assembly (and systems in general) is it gives the students a much deeper understanding of how computers work, which is highly valuable if they want to move on to other subfields of computer science.

For example, suppose a student is interested in exploring security. If they want to learn how things like buffer overflows work, what ASLR is, be able to understand the latest innovations in kernel research, how whatever the vulnerability-of-the-day works (right now, it seems to be Spectre and Meltdown), it's essential they have a good understanding of how exactly their computer, the hardware, the OS ticks.

Teaching assembly (and more importantly, things like calling conventions, the stack vs the heap, and so forth) is a pretty decent stepping stone to help prepare students travel down this path. Of course, I'm not claiming teaching assembly is the only way, but it's certainly a well-trodden and popular route.

We can do the same kind of analysis for other fields -- systems knowledge is potentially valuable for people interested in compilers/PL research, in software validation and correctness analysis research, for people who want to build on top of new tools like Webassembly, for people who are interested in writing hardware accelerated code (using GPUs, FPGAs, SIMD instructions, etc)...

Of course, not everybody is going to be interested in these fields, and even if they are, that doesn't necessarily mean that assembly is going to be directly useful or relevant to them.

But I don't think that's any excuse not to teach the material -- the goal of teaching, I believe, is to prepare students to be successful in a wide variety of different fields, whether that's industry, research, or something else. And if that means sometimes teaching them material that they won't directly need for the foreseeable future, I think that's fine. It's better to be over-prepared then under-prepared, yeah?

tl;dr: having systems knowledge is useful. And if you're going to teach systems, I would imagine that you're basically obligated to teach at least some assembly.


How to teach sums and asymptotics to students who don’t know limits I am to teach sums and asymptotics to first year CS undergraduates who have only high school math.  I thought it would be attractive to follow chapter 14 of https://courses.csail.mit.edu/6.042/spring18/mcs.pdf as far as possible.

However the students will have never seen limits before. What is the minimum amount of material I need to give a coherent picture of how to understand and compute infinite sums? I would like the course to be self contained as far as possible.

For asymptotes in general, one of the easiest examples for beginners is the curve $y = 1/x$ which has asymptotes (at infinity) on both axes. It is easy for them to see that as x gets large y gets small (without bound). Likewise as x gets small, y must get large. You could then look at $y = 3 + 1/x$ for example to see a different horizontal asymptote. Contrast this with $y = x^2$ for an unbounded function and also with a periodic function (sin or something informal that looks like it), that is bounded but has no asymptote.
If you want to go farther, you could discuss a chord and a tangent on a circle. Move the chord parallel to itself and see the two intersection points with the circle converge until you have a tangent parallel to the original chord. This may be more than you want or need, of course.
For infinite series and sums, one of the easiest examples is to first discuss Zeno's Paradox and the sequence 1/2, 1/4, 1/8, ... and its sum. It is pretty clear if you draw the picture that the sum is one and that the difference between a partial sum and 1 is the most recent term in the series. It is also easy to see how to generate the next term.
If you are teaching programming, you can write a program that computes partial sums, but if you do so with floating point then you also need to discuss rounding error, which will get severe, since the sum gets larger as the terms get smaller. Eventually, then, the next term adds nothing at all, due to the fixed precision of floating point data.
But if you want to compute the partial sum in closed form then you can do better in a program to compute that rather than the sum itself. That may be too much to ask, I realize.
That may be enough, but it gives enough of the overall concepts to get you started. And Zeno is always fun in any case.

Here are a few more "interesting" functions that may go beyond what you need, but have interesting things to teach you.
Once you understand what $f(x) = 1/x$ does, you can combine it with other functions to get other sorts of asymptotes. For example $g(x) = x + 1/x$ is asymptotic to the function $h(x) = x$. In that form it is pretty obvious what it does, but less so if you express it as $g(x) = (x^2 + 1)/x$.
Other combinations are possible. If you look at $k(x) = (1/x)*\sin(x)$ you get a function that oscillates but is also asymptotic to zero at infinity.
One of my favorite functions is $m(x) = (1/x)*\sin(1/x)$. As x approaches infinity, this is asymptotic to zero also, but it is much more interesting as x approaches zero. It has the property that it takes on every real value infinitely many times in every neighborhood of zero. The 1/x factor gives it increasing amplitude near zero and the argument to sin makes it oscillate faster and faster. This is a very strange property for a real valued function, but if the student will eventually study Complex Analysis it is an exceedingly important example. I'll leave that explanation for the next course.


Teaching NFAs after DFAs Michael0x2a's recent question reminded me of a problem I've had teaching about Nondeterministic Finite Automata in the past.

I can get my students quite comfortable following and creating DFAs, but when I show them NFAs, they learn to follow without learning to create.  They rarely become comfortable enough with the toolset to make any significant use of it, and when given the chance on any problem, they virtually always restrict themselves to the DFA tools.

How can I make $\epsilon$ transitions and multiple transitions from a single state on the same input character simple and clear enough that students will use the tools with the same fluency and freedom that they can with DFAs?

I don't know how you frame the motivation for NFAs, but something I've found helpful is to put this up front, before introducing them.  Something like the following:

DFAs are the answer to the question "what does computing mean if we only have control and no memory of any kind?"  They are essentially flowcharts, an intuition every student understands.
NFAs are the answer to the "next" question, namely "What can we do if we can execute flowcharts in parallel?  Not just a little parallel, but unlimited?  Let's give them even more usefulness and suppose that we can extract the right answer if it appears on any thread, instantly.  Does this give us any advantage over just one flowchart?"

I've found my students are able to do quite well with this intuition, because they're willing to suspend disbelief regarding the conceptual hurdle that "magic" -- the primary mechanism that defines NFA execution -- cannot be implemented in a real machine.

Then, when they learn that the "magic" of an NFA gives nothing new over a DFA, many of them become quite excited.  As they should :-)

[EDIT]

To expand on my comment, I've found that I can carry this story throughout the semester, as motivation for every one of the theoretical devices.  Philosophically, I think of the automata theory course (at least the first, undergrad version) as centered around the question "what do we mean by the idea of computing?"  This in turn divides into two, interlocking questions:  what power do we get by adding certain capabilities (in memory, memory access, and concurrency), and what price do we pay for adding them?

I gave what I see as the answers to these questions for finite state automata above.

The next one in the story is the idea of adding memory, without worrying about how much, but with only limited access abilities.  Following Sipser and most every other automata textbook, this means memory with only stack access and no limit on concurrency:  i.e. NPDAs.

ASIDE:   I first learned this stuff out of Floyd & Beigel's magnificent text, "The Language of Machines"", and they insert an intermediate study between FSAs and NPDAs, namely the capability of memory that can do nothing but count up and down (what they call "counters").  These are strictly more powerful than FSAs (they can solve the balanced parentheses problem), and strictly less powerful than PDAs, either deterministic or not.  It's kind of a cool thing to add if you can, because it gives an easier to read yet fully formed notion of the idea of simulation as a mechanism for studying expressiveness.  There's also at least one, very practical application that I know of, from language implementation:  checking whether a break statement is correctly placed within a loop.  About half of my compilers students try to do this with the same technique they use for checking nested comments in the lexer:  incrementing a counter when a loop is entered, decrementing it when a loop is exited, and checking that the counter is positive  when a break is encountered. If your language supports nested procedure definitions, this won't work, and the nonequivalence of counter and stack machines explains why.  This side topic takes time, though, and I've only ever seen it in the Floyd & Beigel text, which is, sadly, long out of print.

Anyway, memory with only end access and unbounded concurrency gives you the class of CFGs, of course.  By the time we get through that and the CFG pumping lemmas, I've found my students enjoy the overarching story enough that they appreciate the detour into DPDAs enough to revisit the question "with end access memory, does concurrency give us any advantage?"  I've never found time to really study deterministic PDAs (which is okay for me, since I also teach our compilers course :-) ), but students do seem to enjoy learning that the answer to the concurrency question for stacks is that is does make a difference.  I even managed once to show how the existence of an inherently ambiguous context free language gives an an alternative proof of the nonequivalence in expressiveness.

Finally, there are Turing machines, of course, which represent the answer to the question of what we get when we combine control flow with unbounded memory and no limit on access.  The fact that concurrency once again becomes irrelevant to expressibility is mind blowing to me, and it seems to be to those students that aren't exhausted by the semester, since we're always near the end at this point.  If one needs a good story to explain this, it's in the fact that concurrency can always be implemented by threads and sufficiently powerful thread scheduling (which is, essentially, what the proof of simulation of NTA by DTA is).

At this point, I try to include the Universality Theorem, at least a mention of it.  More than any other result, I find that this one ties Turing machines to real programming languages in a very effective way, because it guarantees that every "real" programming language can be implemented with the minimum tool set of deterministic control flow and random access memory.

Including the Universality Theorem also has the nice advantage of making the non-computability results more concrete.  It's not just that Turing machines can't answer such questions: no real programming language can, and the combination of the Halting Problem and Universality explains why!


Functional Programming - using F sharp I learnt a lot (like kept hearing about it) about functional programming after coming to this community. I had heard of it before but was unaware of its importance. Then, I started including functional programming in my daily conversations with my students.

Now, a couple of students (who are already familiar with dot net) are asking me if I can teach them functional programming. Given that I am a dot net guy, my mentor suggested that I try F sharp.

The question is, is F sharp a good choice for learning functional programming? If not F sharp what are the alternatives.

Note : Any alternatives that you suggest must have full support on windows as well as Mac. For example, F sharp works just fine on Visual Studio for Windows and Visual Studio for Mac.

Actually, I think a better choice would be a true functional language (Scheme, ML, Haskell) rather than a multi-paradigm language.

Of course it depends on your goals. If you really want them to learn the functional programming mindset then don't use a language that lets them escape to other paradigms so easily. F# permits programming in many ways, including imperative and OOP. So, if they have a multi-paradigm language, you can either just let them program using what is available or you can try to enforce a style that may not be natural in the language. I think this would be frustrating - more frustrating than just pushing through the needed transition of thought.

However, in a true functional language you don't have the option of just "making it work" using thought patterns you have already developed when learning a different paradigm. The transition to functional can be difficult, but it isn't made easier by letting students not do it.

If you want them to run, don't let them crawl.

I'll note that I with a bit of a library I can program functionally in Java. But I wouldn't use that as a way to teach functional programming.


Teaching "math function" vs. "CS function" The word function has different meanings in math and computer science. For example, f(x) = rand(1) is a valid (pseudocoded) CS function, but it is not a mathematical function because it has multiple possible return values for a given argument.

When and how is it most effective to bring the students' attention to the contrast? In teaching physics, it is a general principle that when possible a student should experience a phenomenon before being given words to describe it. (E.g., have students feel a torque before defining "torque".) (Arons, A. 1997. Teaching introductory Physics. New York, NY: Wiley). Presumably, there is a benefit to be obtained by introducing math functions, CS functions, and the contrast in a particular order and using a particular approach to active learning, but I am unaware of any published result to that effect. What ideas and data can people contribute to this question?

In mathematics a function is a constrained relation between two sets. You can illustrate that in a number of ways. The constraint implies consistence of operation and uniqueness of result.

If you discuss relations (in math) as well as functions it may be easier to get beginning students to grok it.

In most computing languages, a function is an operation that produces a value (and possibly side effects - horror). There is nothing in the definition of a Java function about constraint, not even that successive invocations with the same input produce the same values. A java function is a machine. Drop in 0 or more inputs, turn the crank, get some outputs. You can illustrate that by drawing a machine with an input hopper, and output spigot and a crank.

Students who know math have a lot of problems early on with things that look like math but are not. Other questions in the "hopper" currently explore other aspects (equality, variables)