Interview lesson on "Computational Thinking" I have been asked to teach a single half hour lesson at a new school for an interview. The topic I was given was "something on computational thinking." The students are 13 years old.

For the first half of the lesson the students wouldn't be using computer, and for the second half they would be on a computer.

I have not been given any objectives for this lesson (WALT or WILF).

The first part seems easy, I plan on using something from http://csunplugged.org. However the 2nd part seems harder. In the past I have connected it to programming, but the class has little programming experience.

What can I do in the second half of my lesson, where the students have access to computers? I'd prefer to avoid a programming task because the students have no background in it and I only have 30 minutes.

I would like to suggest my absolute favorite lesson from my intro to CS class. I usually teach it over two class periods, the first being "unplugged" and the second on the computers, but I think you can cut some corners and still offer a valuable experience.

Overview: "How do computers sort things?"

I start by asking what computers are good at. The answers vary a lot and you usually have to guide them towards "counting", "adding/subtracting/multiplying/dividing", "true and false" and "comparison". If you've done a unit on binary, it's helpful to link that in with the last two and let them show you why it is so easy.

Then I talk a bit about how sorting is absolutely fundamental to Computer Science. I spend a little time explaining how almost any significantly complex program they have ever used will sort something at some point. It's a great algorithm to start with because it is so visual and so intuitive.

So we're going to have a tournament to see who can sort the numbers from 1-16 the fastest. At this point I have them fold and cut a piece of paper into 16 pieces and number them, but in the interests of time, you should do that yourself and just bring in enough sets for ((the number of kids) / 2).

Pair off the students and give each pair a set of numbers from 1-16 and tell them to put them in a line in front of them in random order.

One partner is going to be the "computer". They can not talk and they are "blind" (they can not arbitrarily choose specific numbers). They can only point to two pieces of paper at a time.

The other partner is the "program". The can only say "switch" or "stay".

The partners have to come up with an algorithm such that the "computer" points at two numbers at a time and moves from one pair of numbers to the next pair in a consistent and logical fashion. The "program" tells the computer whether to switch those numbers or leave them where they are.

Almost all of the groups will come up with bubble sort. Occasionally, one group will come up with selection sort.

I put them in head-to-head competition, with the numbers randomized the same way for both groups to keep it fair. Winners play winners until the champions are crowned. Usually there is some sort of prize at the end (chocolate goes over well with 13 year-olds :)

Second 30-minutes:

Here is the crux of the problem for you, as you mentioned: they don't have any programming experience or accounts. So my recommendation would be to ask them to set up Scratch accounts for the students in advance, or (possibly even better) you can just set up 15 "test" accounts and have the skeleton program ready to go in each one.

I am a big fan of pair programming, so I keep them in the same pairs that they were in for the competition. I set a repeating 4-minute timer on the board to change the "driver" (on the keyboard) with the "navigator" (helping figure it out).

I ask my students to "remix" this program: https://scratch.mit.edu/projects/125507639/

But for those that need a little more scaffolding (or have less time, like yours), you could include a little more code, like this: https://scratch.mit.edu/projects/125587510/

Their goal, obviously, is to sort the blocks. How much you let them struggle and how much help you give is obviously up to you, but I can not express the satisfaction you'll get when you start hearing the shouts of "I GOT IT!". I like to err on the side of the struggle. I try to explain that if they are not frustrated, they are not learning - they're just doing what they already know.

If they are done early (or want to continue with a harder challenge after class), they can try the "sorting 300 starter" in my Scratch Shared Projects. It allows for more a random assortment blocks, negative numbers, etc.

Once most (or all) of the students have a working program (or you have 5 minutes left), bring them back in to talk more about the power of sorting.

What kinds of things do we sort all the time in our daily lives?

What if you are sorting REALLY HEAVY objects (buckets of sand) instead of just pieces of paper? Would you use a different algorithm? Why?

You can also show them this great visualization of different algorithms: https://www.toptal.com/developers/sorting-algorithms/

If you have any questions at all, please feel free to contact me!

Good luck!
John


How useful it is for math student to learn programming to find proofs or counterexamples? I study mathematics and sometimes I have difficulties to find proofs or counterexamples to some problems. Is it useful to learn programming to find counterexamples or proofs? How useful it is for mathematician to learn for example Coq or Lean?

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


How to learn to solve trees, graphs questions for competitive programming I learnt about trees and graphs from my textbooks (undergraduate level) last year.

But now I'm doing competitive programming and unable to solve questions involving these concepts.

I fail to understand that a given question needs DFS or BFS for solving. I know these algorithms, but when it comes to questions which don't directly mention that DFS/BFS should be applied then I'm unable to solve them.

I always run away from these questions because I just know the concepts but fail to reproduce them in my code and have just learnt and never coded.

Can anyone help me in suggesting the path that I should follow to learn to solve such questions that appear in programming competitions like "Codeforces"?

Please, provide any references such as videos or any site for noobies.

In fact you are adressing an important issue: You were learning concepts, but you are unable to transfer the concepts to real world problems. This is a major issue in many higher education scenarios and e.g. my students always complain, that they do not find the answers to my question in the course material. Of course they don't, otherwise I would not have to ask the question - I assume they are capable of reading and writing ;-).

Now how can you come to that next level of understanding? The answer once again is practice! You have to understand the underlying structure of a problem (e.g. use a divide and conquer approach to decompose the problem) and build a solution based on well-known blocks (like DFS / BFS, sorting, ...). The final step is to adapt the algorithm to your data structures or other specific needs of your problem.

You have to do this over and over again to get practice. Often it helps if you are trying to understand how others did if for some problems, and websites like Codeforces can give you good examples of problems.

After some practice, you will have gained a good intuition on how to decompose a specific problem. Especially for trees and graphs it is always helpful to draw your data structures and think about how an algorithm would traverse the data structure.


How can we teach good naming practice for students learning Java? In writing software we name things. In Java we name classes, interfaces, methods, variables, etc. How can we teach both the importance and the skill of choosing good names?
What teaching practices will lead students naturally to good practice in naming their programming constructs?
How important is naming in the creation of quality software? In particular, how important is it to teach good naming and insist on it in student programs?
Moreover, what practices impede the student from learning and practicing this skill?
Good naming is important for both the creation and maintenance of programs. Good naming also makes the evaluation of the student programs easier when the student uses, for example, intention revealing names consistently. .
Note that much of this applies to other languages, but Java is a popular teaching language. Java is mandated in the Advanced Placement courses commonly taught in the United States. It is also a common language in first courses taught to undergraduates.

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

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

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

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

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

"what does this variable actually represent?"

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


Instructional Methods for In-class Code Demos When demoing code in class, I have tried at least three different methods of instruction:

Write code live and have students type along
Write code live and have students follow my logic while only I type and narrate my thinking
Start with a full working demo and analyze an already written program

In all circumstances students can access the programs on GitHub after class. Moving forward, I would like to develop a more consistent and effective approach.

What instructional methods are most effective for teaching with sample programs?

I think this depends on the curriculum and goal. If the goal is not to teach them specific algorithms, but to teach them problem solving, then have them write the code first. I come from adult education, and this approach works fine there for me.

What I do is I give gradually more complex exercises, and give them time to develop a solution. I also give them a few keywords, commands that they will likely need. I go around and help with individual solutions. They are allowed to work together, communicate, help each other if they want to. They can use the help, internet, the course book, whatever they can get their hands on.

This means a lot more work for the teacher, as you have to run around, understand different approaches, and not force your solution on them.

If I find a particularly good or interesting solution, I show it to the class (after everyone has finished).

I only solve the program in front of the class once everyone has a solution. (Pretty disappointing, but even this way I see some of them just delete their working solution and mindlessly copy mine.) I always try to emphasize there is no one good solution. There might be better, faster solutions, but as long as theirs is correct and works, it is a good solution.

As for the inevitable speed differences in the group, instead of giving one exercise, I give 3-4. The first is the mandatory, the rest is extra. (Maybe for + points or such to motivate them; luckily in adult education I don't need the extra external motivation.) When the last person finishes (or gives up) the main exercise, that is when time is up.

So I say the most effective way for teaching with sample programs is let them try, fail, suffer, find their own way, then finally succeed. Don't spoonfeed them.


Should programming assignments be graded based on results from unit tests or based on the similarity to the correct implementation? Imagine students in a course on algorithms & data structures, which are given homework assignments to implement things like trees, hash sets, sorting algorithms, etc.

Due to the high number of students per semester and limited resources, grading is heavily assisted by automatic unit tests. The TAs will still scan through the code, but if all or most of the test cases fail and there is no simple fix in sight, students will get 0 points on an assignment.

Unfortunately, this can happen very quickly. Consider implementing a balanced tree as an example. If students fail to correctly reference the nodes, insertion, removal and searching, - despite being implemented correctly if seen individually - will not work and can hardly be tested.

As expected, some students do complain about their poor grade and argue that "although they acknowledge that their data structure does not work entirely, they at least implemented various sub-tasks correctly". This may even be correct, but the TAs very often do not have the time to dig deep in the code and grade the internal functions of the students implementation. Especially for more complex data structures, it would also take too much time to fully comprehend and even debug the (erroneous) implementations.

My question is, if it is okay to grade programming assignments based on this external view (does the implementation pass the tests?) or should grading rather be based on an internal view (are the things implemented by the student correct if seen individually?).

One important remark: In this specific scenario, students were not given the unit tests, since they are expected to test their implementation themselves.

Actually, life isn't so simple as to choose one or the other here. Code needs to be well structured and it needs to be correct. Given that students are learning, you can't really expect that they will be perfect on either of these and so you need to take both in to account. A program could, be well designed and built but have some, as yet undiscovered, flaw that prevents it from passing its tests. If the students hack it up to get tests to pass they are going backwards, not forwards.

CS students have a lot to learn. Programming is important, but not the most important thing. But to advance on many of the other goals of the CS curriculum, students need to build good code. Even better, would be the ability to build maintainable code, since many of them will start their careers in programming-heavy jobs. Even if they go to grad school, much of what they do will depend on being able to write good code.

So, in grading, points should be gained or lost depending on both code and correctness. If the code is not correct, then someone needs to make an analysis about why the code is failing. It could be something simple or profound.

In my view if a program can't be understood easily and/or seems to be hacked together, it should receive few points. If a program, on the other hand, passes few tests then it is a much more subtle problem that needs deeper analysis. Don't neglect it.

In the question heading you talk about the "correct implementation". I worry about that. Students should not be graded on similarity to any reference implementation, certainly. There are more than a few ways to write a correct program.


What and where should I study for competitive programming? I am currently in the 10th grade. I would like to get started in competitive programming. This are the things I know now:
Mathematics - Currently in pre-calculus Well Mathematics in my country is pretty unstructured. You would be studying bits of everything, and not one after the other. So I self studied up to Algebra II (Algebra I, geometry) so that I can cover it in more depth than in my school, though in school I'm learning through trigonometry stuff, algebra I & II stuff and geometry in varying orders.
Programming:
1.Knows the basics of C, Python, C++(main currently learning)
CS50X completed
HTML,CSS ,JS and sqlite3 with python
What I want to learn for competitive programming(I am unsure):
Discrete Mathematics
Algorithms
Data Structures
4.Dynamic Programming
and I am hoping you'll help me to structure the remaining necessities and knowledge required. I found some blogs at many places but they were incomplete i.e. they are not well enough for beginners to you know get started on.
I am aiming currently for IOI.
UPDATE:
I am from India.
National qualifications:
These are the stages of IOI qualification in my country:
1.Zonal Olympiads - Either written(pen & paper) or Programming or both
(about 500-800 participants in each)

Next round National Olympiads if qualified in previous (about 250 - 400 participants)

3.Next if qualified National training camp(about 30)
4.Top 4 are chosen from it to represent at IOI.
Edit: I am from India.
Edit: I am currently taking discrete mathematics online.
I believe I know where to practice.
Which should be first book/course/material to learn?

If your aiming for the IOI, the first step has to be figuring out how to get onto your country's delegation.  In the USA (where I am), that means USACO.  If not, then you will have to determine what that pathway is.  Every country has some method of determining delegates.
The next step would depend a lot on how those delegations are formed within your country.  You may have to join a team, and there will presumably be some sort of coach.  Most of your preparation and learning will probably focus on the competition used in your country.
And in terms of what to study, the competition itself looks to be very, very focused on algorithms.  Until you can find more specific resources to the competitions within your own nation, you could spend time practicing the older, published IOI problems and Project Euler problems, which seem similar in nature.
It's hard to be more specific than that without knowing your country of origin.
Good luck!!


Should assembly language be taught in an introductory course (or soon after)? Should ye ole' fashioned assembly language be taught to help students develop a sense of how actual underlying computational hardware supports/allows running their higher-level or more abstract software?

Something with (a limited amount of) a linear address space (global state memory) and a program counter with jumps (conditional control flow or GOTOs).

Using something like Knuth's MIX, or the CARDIAC cardboard computer (this was actually used to teach programming in an introductory computing for non-programmers course I audited at Berkeley in the late '70's), or perhaps an emulator for an 8-bit retro-computer (such as Apple II or Altair) that can run inside a web browser.

I think there is very limited benefit in teaching assembly so early, and it's more likely to just scare away your students.

When I started learning programming, I thought bare-metal OS development was really interesting, and I started to learn about it (mainly through OSDev). But frankly, assembly was far beyond my level at that point, and it was hard to get anywhere beyond the tutorials they give. Consider that:

Beginners often have problems with learning the syntax of the language, and the underlying conceptual problems ("how do I design this?"). Your students may not be ready for that after an introductory class—learning the concepts and thought processes (how to think like a programmer) is far more important than any language, and assembly only clouds that by making you think about memory, registers, jumps, etc.
Your students probably won't ever need assembly, and they almost certainly won't be writing much unless they go into fields like embedded development, OS development, etc. Even then, it's more likely that C (or a similar low-level language) will be used.
Assembly is intimidating. It's not something that it easy to read, understand, and write. Aside from the technical problems of teaching and learning, it's just scary, and when I tried to learn assembly, it just led to frustration and not a lot of progress.

My opinion is that you should develop the higher-level concepts first, and make sure your students have a solid understanding of how to write code logically. Then, you can begin to 'remove the stabilisers', introduce memory management, and then finally lead to assembly, if that's what you want to teach.


Reduce snap!'s features I'm using snap! in my high school computer science class (11th grade, ~16 years old) and I'd like to reduce the features (~blocks) that snap! provides by default. Reasons:

Simplify the interface
Many blocks are not needed (not "allowed") according to the curriculum
I'd like to have the students see/develop the need for some blocks that simplify tasks ("index of ... in list" would be a good example), and have them implement them on their own.

I started digging through the code, but there has to be an easier way?

This is a bit of a frame-challenge, but what I'm understanding from your question is that your goals here are to: 1) Not overwhelm your students and avoid them getting lost in a plethora of blocks they won't need, 2) Force students to understand how to implement more complex blocks themselves.
Have you considered instead of providing a restricted version of the language (which, could be complex to install and update and ensure every student is using the same version of), simply providing a list of "recommended" blocks? This could help to achieve your first goal, to act to guide students as to what they'll need for an assignment and avoid them being overwhelmed. And, this still allows students who want to explore a larger set of the languages features to do so if they want, something which I think should be encouraged.
As for your second goal, this depends on your class but it may be effective to simply create an assignment around implementing more complex built-in blocks and enforce the restriction specifically for that assignment.


How can I do the best assignments as being a computer science student? As I am a student of BS(CS) computer science and a beginner in this field. As a student in the first semester I don't know about any basic language or other techniques to improve my assignment skills. My instructors also insult me because of doing poorly on assignment having no such pattern and skills. They said I have no idea how to do an assignment no matter that will be technical or either theory work. They said I have no idea to work  in any software or any other tool.

How can I improve my skills of doing my assignment? Like assignment official format, front end display?

I'm surprised by your question. In the first semester of a program you shouldn't already be expected to know much of anything. But you should be expected to learn a lot of things.

But you learn by asking a lot of questions. Also by answering some of those yourself through reading.

But the most important thing to do is to do a lot of exercises and have your professor give you feedback on how to make them better.

To learn how to program you have to write a lot of programs and to think about why they work or why they don't. You have to learn how to use the tools and what information they give you. That also takes practice.

I worry that you say your instructor insults you. Certainly some teachers do that, but perhaps they are really just criticizing your work. But they need to say more than just "this is bad". They need to give you some help on how to make it better.

But, reading and listening to the instructor is not enough. You have to practice. The more you practice the better you get. Just like futbol.

Depending on the rules imposed by your institution and professors, you might also consider forming a study group of fellow students so that  you can try to learn together. Some places don't allow it, of course, but it can be helpful when possible. But be careful not to give the impression that you are just copying assignments from one another. A study group has to be about learning.


How to teach which loop should be used In most languages, there are many different types of loops. The most common ones seem to be for loop, while loops, and do while loops.

What is the best way to illustrate the differences between the loops, not in terms of syntax, but in terms of recommended usage. For example, a while loop with an iterator variables can usually be replaced by a for loop. A while true loop with a break statement at the end could be better expressed as a do while loop.

How can I get my students to use the correct loops in each situation? How can I show them when a loop can be better expressed in another form?

Use the for when you know how many times to execute it, such as counting, or iterating over an array. Use while or do .. while if you don't. The choice between while and do .. while is if you need to do the loop one time before the test use do ... while otherwise use while.

A full explanation can be found on Stack Overflow in this accepted answer.


Framework choice for AP CS A students: Swing or JavaFX? I attended an AP workshop this week to prepare for teaching AP CS A this coming school year. It gave me my first glimpse of Swing, which has now piqued my interest about including some GUI components in my course (something I had heretofore not anticipated). There are a couple other excellent questions/comments here about frameworks for GUIs in Java: Introducing the MVC pattern along with JavaFX and Lesson plan for teaching java graphics. All this got me thinking...

Which framework is more appropriate for students learning Java as a part of the AP CS A curriculum?

I'm looking for something that allows students to get up and running relatively quickly and easily with something small yet meaningful. It won't be able to become a huge component of the class, so I'm hoping one or the other is more suited for somewhat fast learning appropriate for high school AP students.

Note: I hope I'm not unknowingly wading into a religious war akin to emacs/vim or tabs/spaces...

Disclaimer: some do consider this a war like emacs/vim. I don't.
I'll quote you on this: "I'm looking for something that allows students to get up and running relatively quickly and easily with something small yet meaningful".
From this: JavaFX. Along with IntelliJ, and Scene Builder, students can build a GUI very, very quickly. The FXML file which "creates" the GUI also gives an introduction to XML file structure.
It also teaches many Java 8 things. This is vague, but here are some examples:

A lot of lambda expressions.
Work with Collection. The students would need to use the collections in java 8, if they learn JavaFX. This is handy, because those classes are obviously useful outside of AP CS A
The Stream API (which gets buffed in Java 9, coming out soon) has a lot of usage as well in JavaFX.

I could continue this rant forever, but the main point is that JavaFX is self-dependent, which means that it only requires itself and java, unlike Swing, which requires AWT.
I hope this give you some idea about putting a GUI library in your curriculum.

As was pointed out in a comment, JavaFX has an added bonus: It's more likely to become the library your students would use, if their careers lead them to doing GUI in Java. I say this because Oracle said so:

6. Is JavaFX replacing Swing as the new client UI library for Java SE?
Yes.

The link contains more details, but the core of that part of the faq is that it is a replacement. (Which is in no way saying that Swing will not be included in future Java releases, because of backwards compatibility).


Analogy for static objects (or members) I'm trying to think of an analogy to explain how static members, references and objects work.

What I have in mind is saying that static is like the number of computers in the world. That parameter isn't related to any specific computer, but rather to Computer in general.

However I feel like this might confuse students, partly due to the name static (i.e. something that doesn't move).

Can anyone suggest an analogy that shows what static means in everyday things? Preferably something that high-school students can relate to and understand.

I use school colors and principal's name.

If someone comes in tomorrow and says your principal is no longer Mr. Smith, it's now Ms. Jones then that change is made for every object (student) in the school. You don't have to go to each individual student and tell them that their principal has changed.

It worked really well this year because we did get a new principal.


Detailed lecture series for automata theory or theory of computation I need a detailed  automata theory (or Theory of Computation) video lecture series to go hand in hand with the classic text books mentioned in this question

The books are fine but I am having problem in understanding many portions of the texts on my own.

I want to develop an intuition about the theory and related problems which I feel I am quite lacking.

(I am following "Introduction to Automata Theory, Languages, and Computation" by Hopcroft, Ullman, Motwani)

In the course I co-teach on Automata, Computability and Complexity Theory we use the excellent videos by Harry Porter to replace our classical lectures, and use our contact hours instead to practice with the material together with the students.

Porter follows the book "Introduction to the Theory of Computation" by Sipser.


Is learning C++ recommended for beginners? I have heard a lot of people saying C++ is a hard language to learn and is not a good language to start. I myself am a beginner in programming and have jumped straight into C++ as soon as I heard that being a programmer is way more useful for creating games compared to someone who just knows how a game engine works(Its what I heard). So far, I enjoy learning it and have not found it difficult to understand. But I have also heard that it gets harder as you progress. The reason why I decided to learn C++ in the first place is so that in the future when I turn 18, I'll be one of the top choices for big companies and be able to be more experienced than my fellow programmers in the future since C++ is the main language used by big industries. Should I stop now and learn a different language like C or C#?

I wouldn't fuss too much over whether a language is "hard" or "easy".  There are plenty of reasons to learn a language.  Learning for a career is a great reason!

Languages are usually organized around certain central ideas.  Haskell is a pure functional language, Eiffel is a pure Object Oriented language, and C is designed to reflect very closely what a processor does.  C++ is designed to be a cross between C and object oriented programming, so there are several different paradigms at work at the same time.  That can make it a little more difficult to learn because there are simply more concepts at play.  However, the early basics should be fairly easy in any language.

C++ does appear to be the most heavily used language in the gaming industry.  However, there are a few caveats:

What sort of games would you like to be involved with making?  Browser games rarely use C++.
Languages change, but concepts are long-lasting.  While learning, keep pushing yourself to learn new ideas, not just new procedures.  That way, you'll be better positioned to switch over to a different language if it turns out that the wonderful gaming job you land is actually in HTML5, or Python, or in some language that hasn't even been invented yet.


How does IB Computer Science compare with AP Computer Science? I've taught AP Computer Science A for over a decade now, and an administrator has asked me to look into transitioning to IB.  (We already have some programs in the school that use IB, so we would potentially be joining into that.)

Nothing is set in stone, and we may choose not to go down this path.  However, I am having a lot of trouble figuring out what that transition would even look like from the perspective of a CS teacher.  How much programming is actually covered?  Are the curricula similar?  Is IB more rigorous?  What new curricular material would I need to develop?

I've found Mr. Roger's IB Page, which seems to indicate that AP CS A can be an effective first year for the two year IB curriculum.

What is the difference, then, between AP Computer Science and IB Computer Science?

About IB Computer Science.
             Computer Science is regarded as an experimental science, alongside biology, chemistry, design technology, physics and environmental systems and societies – and sits in the Group 4 list of subjects. The IB Computer Science course is a rigorous and practical problem-solving discipline.

AP Computer Science Principles is ideal for students who are less interested in Java or who would like a big picture view of computing. ... Both computer science classes have a great deal to offer high school students. Since they vary in several important ways, students should research each course before enrolling.


Automatic grading of test-cases Last year I taught a programming course, and used an automatic grading system for grading the students' homework (in addition to other evaluation measuares). It worked quite well; the bottleneck was the need to write test-cases for each assignment.

This year, I would like to have the students themselves write the test-cases - both to save time, and to have them practice this important skill.

I thought of the following scheme:

In each of the 10 assignments, 10% of the students will be the "test set" and the other 90% will be the "train set".
The "test set" students will write test-cases - each student will write e.g. 10 test-cases.
The "train set" students will solve the assignment; their solutions will be tested using the test-cases of the test-set.

The problem with this scheme is that, if the solution of student A from the train-set fails on the test-case of student B from the test-set, it is not clear whether it's because an error in student A's solution or an error in student B's test-case. Of course I can look and see who is correct, but this requires a lot of work and undermines the idea of automatic grading.

How can I improve this scheme to allow automatic or almost-automatic grading of both homework assignments and test-cases?

Have you thought about having a solution that you create and test the students test cases against your solution? Then you have a stable platform for running the student defined tests.

Also run test cases which you prepare against the student's code. Now you have graded the two parts independently of one another.

Just out of curiosity, what did you use for auto-grading?


Introducing self containing objects (Node) In some programming languages, many data structures use Node<T> (The examples in the question are in Java, but I suppose they are similar in other languages):

public class Node<T> {
    T info;
    Node<T> next;
    ...

I have seen students stare at the board\screen, perplexed, whenever this is introduced. They are confused by this implementation, because it is "Defining something with itself" (like saying "white is the color of things that are white-hot").

They have difficulty understanding how a class can have a property of itself.
How could I explain to them why this is valid in programming?

This issue makes it hard for them to understand data structures like List,Queue etc.

Context: they are high-school students learning java, and are familiar with primitive types and a bit of OOP.

The sample is not "defining something with itself." Rather it is defining two different kinds of things.

The first line: public class Node<T> { is beginning the definition of a template for things to be made later. That definition will be handled at compile time. The third line: Node<T> next; sets up an object that will be instantiated using some template. Later in the compile process, when the object is created, Java will look in the table for the template called "Node" that can handle some type. Since, by then, the complete template will exist, there's no problem. The key point here is that next is not a template, it is object that will use the Node<T> template when it is created.

If you also define public class Node2<T> extends Node<T>, then at run time, next could refer to the template Node<T>, or the template Node2<T>. Exactly which it is will be determined when the next object is instantiated.

If it hasn't already been covered, that would be an opportune time to cover early and late binding.


Can assignments be graded using blockchain? I enjoyed reading this explanation of blockchain at codeanalogies.com, which imagines a fictitious distributed grading system in a high school math class. The article made me wonder whether it would be possible (in reasonable time and effort) to implement some sort of distributed grading system in a CS class for the primary purpose of illustrating the core principles of blockchain?

For such a system to be useful, in my view it would need to:

produce grades that are accurate and consistent (ie. any grade could be independently reproduced by an instructor if requested by a student)
give students direct experience with some key aspects of blockchain, without requiring them to make too many assumptions
protect anonymity of grades

Such a system would probably require more work than usual, so maybe it would only be practical or interesting for one or two assignments.

Has anyone tried something like this? Or is someone with a decent understanding of blockchain willing to sketch out some ideas?

Unfortunately, the quoted article has serious shortcomings and would be unworkable in practice. In the first place it isn't just about blockchain, but also mixes in quite a lot of other things, such as the bitcoin that is usually associated with it.

The article also misrepresents in some ways the reasons why you would want to do this. The financial crash wasn't, in fact, caused because financial institutions had centralized record keeping but, rather, because they had been given unlimited power to manipulate markets by a feckless congress. The medical record example is a bit stronger, however.

But the article also has the following technical flaws.

The school principle can create grading value (points toward grade = bitcoin) pretty much arbitrarily.
The transaction fees would have to be much (much) lower as they overwhelm the possible gain by participating.
Unless the student grader is also a miner, they have no incentive to participate as they can only give up points via transaction fees.
The reward (potential) is not in any way related to the educational objectives, made worse by:
In the real (bitcoin) world, the miners are so busy mining that they have no time to do anything else (e.g. study). The system actually enforces this, by making the reward harder to get over time.
At the scale of a school, miner pools could easily reach 50%, destroying the whole thing. Some students would much rather do search for treasure than do actual academic work. Why reward it?
You replace expertise in the subject (teacher grading) with amateur action, which is subject to error. If it just matching answers to keys with no interpretation, a machine can do it.
The overall work entailed increases as each exam is "graded" multiple times, plus the treasure hunt.
I envision that it would be more difficult for a student to contest a marking error in this scheme, though it might result if fewer of them being made.
Even in this scheme, exam papers can be lost. Distributing them probably increases the risk.
If teacher vindictiveness is an issue, blind grading can be done without the other complications of the scheme. It isn't actually essential that the teacher knows who she/he is grading.
As to the cost, I'm sorry, but if we paid teachers an actual living wage I'd be more willing to accept the argument. But in the real world, teachers don't really work for money. Lawyers and Doctors have a similar level of education to Teachers.

But these are flaws applied to the "fun" example, not the thing (blockchain + bitcoin) itself. Reading it might lead to a better understanding of the technology, but it is not a lot easier to read and understand than these, from Wikipedia:

Blockchain

Bitcoin

Fun, though.

As a classroom activity it might bring enlightenment, but, I fear, mostly enlightenment about the unworkability and complication of the scheme.

But let me add something about the two ideas themselves. Bitcoin has no intrinsic value. It's imputed value comes only from its scarcity and the expense (in cpu power) of creating new ones.

On the other hand, blockchain, is a distributed ledger that can keep track of anything using an anonymous and distributed system of agreement. It doesn't depend in any way on the difficulty or expense of creating a block, though it needs a scheme to prevent forging blocks. To be true to the idea the anti-forging scheme needs to be independent of any central authority.

For grades, neither of these, independently, seems to be very desirable (or necessary), unless we are in a post apocalyptic world (Road Warrior movie for example) in which there are no central authorities, having all been destroyed, and no centralized way to verify historical records.

However, a few words about bitcoin and similar things as they have worked out in the real world are in order.

Since it has become difficult to generate new bitcoin, two things have happened. Mining rigs are using up a significant amount of energy - and likely generating a significant amount of carbon dioxide. One estimate of the energy used is approximately that of the nation of Ireland. The other is that these rigs and the energy are expensive, so many internet attacks are now done to install bitcoin miners on other people's systems so that they can bear the cost without benefit.

The bitcoin market has also proven to be very volatile. Fortunes have been made (by the early investors/miners) and lost (those who believe the hype). That makes it remarkably similar to a Ponzi Scheme.


Where one can learn CS in very rigorous way? I'm interested both mathematics and computer science. I like math because one can formalize it rigorously and I have seen that many things can be defined by sets. Is there similar thing in computer science, as for example asymptotic notation is sometimes defined in very odd way, see https://math.stackexchange.com/questions/2731290/how-one-can-define-rigorously-the-time-and-space-complexities-of-algorithms ? I'm looking way to learn CS in a very rigorous way.

Be careful of what you wish for. Assuming you want rigorous self study, I'll recommend a few books. They are fairly old, but are classics.

The Art of Computer Programming. Knuth is a mathematician at heart. The link is to the boxed set, but you can buy individual volumes.

Elements of the Theory of Computation. This is as rigorous as you want to be and addresses directly the question of run-time bounds of various sorts.

Similar is

Introduction to the Theory of Computation by Sipser

A somewhat different view of computation is found in

Structure and Interpretation of Computer Programs: A classic introduction to functional programming in Scheme - yet quite deep.

For what it's worth, I have a doctorate in Mathematics and taught CS for over 40 years.


Is there any purpose to having students do fiddly cache homework assignments? I teach undergraduate computer architecture and am reconsidering one of my homework assignments in which I ask students to simulate by hand (on paper) the behavior of different caches on the same access sequence. It is tedious to create such a problem in a way that the caches behave differently in an interesting way, and I'm sure doing the problems is tedious too (as is grading them). I'm willing to do the work and have students do the work if it's actually useful, but I'm not sure it is.

The purpose of the weekly homework assignments it to reinforce the material the students learn from the textbook (Computer Organization and Design by Hennessy and Patterson), lectures, and in-class exercises. There is already a full set of lab assignments that require wiring or coding (in assembly language or Verilog). There is not time for an additional lab assignment on cache simulation.

I have a separate homework assignment that asks higher-level questions about caches, such as which of two versions of code is likely to run faster if cache performance is taken into account. I think writing cache-aware programs is an important skill. Is simulating the differences between direct-mapped, 2-way set associative caches, and 4-way set associative caches an important part of students' education?

It sounds like you've already answered your question, but I'll throw in my two cents:

It depends.

Does every software engineer need to simulate the differences between direct-mapped, 2-way set associative caches, and 4-way set associative caches? Absolutely not. I've been a programmer for about 10 years now, and I think I have a pretty successful career, and I have no idea what those things even mean.

However, should some students, who are particularly interested in these kinds of things, take a deeper dive? Absolutely yes.

So, it comes down to a question of: is this course designed for students to get a high-level overview of computer architecture, or is this a more specialized course designed for students to get more information about the low-level details? In other words, is this a breadth or depth course?

You might want to give students a high-level overview, and then point particularly interested students at further reading, more advanced courses, or specialized fields they might study in grad school.


Order to teach looping constructs in a non ideal language In an ideal teaching language
If the language directly supports them then the order to teach looping constructs seems simple.

Infinite loop: forever.
Simple finite (bounded) loop: repeat n times.
Bounded loops: for i in list or for i = 1...6 (I am not sure which order these two should be in).
Simple unbounded: while condition
Complex loops: all the rest.

However often the teaching language does not directly support these. This may be an argument for choosing a different language for teaching programming.
The problems that I am having
(I am teaching in Python).
I was teaching in the order I outlined for an ideal language, but are getting problems.
For an infinite loop we use while True in Python, however students ask or struggle with this. I can not explain it without explaining while condition. So pupils have to hold something that they do not understand in their head.
Similar for repeat n times in Python it is for n in range(5):, this is a lot to keep in ones head without understanding.
The question
So the question is “what to do?”. Do we start with

Bounded loops: for i in list:
Bounded loops: for i in range(n):
Simple unbounded: while condition:

Or do we do it some other way?

I prefer to teach while loops as part of my unit on if/else statements since the syntax and thought process are virtually identical.

I then introduce for loops when teaching lists (in Python) or arrays (in Java).  With for loops, language impacts which style you likely use first.  With Python, I use the for item in list structure first.  In Java, I use the C style (for i=0; i<...) loop first.

I don't try to introduce all styles of looping at once as I prefer to develop the concepts across units.


Suggestions for teaching selection sort with candy It's the end of the semester, so my students are pretty burnt out, and a bit of sugar might go a long way (plus, evaluations are around the corner ;-). I'm envisioning a tactile class where students would carry out the selection sort algorithm to sort an array of candy bars by length (or height, or size), by physically swapping candy bars. I would also have them write down the number of comparisons required, to get a better understanding of the time complexity. Ideally, every student (or pair) would get 4 pieces of candy.

  Can anyone suggest candy that naturally comes packaged into 4 or more different sizes?

All I could think of is how Hershey bars can be broken along natural dividing lines into different numbers of squares, and how Toblerone bars also have natural break points. But both are chocolate and might melt. I'm embarrassed to admit I'm not much of an expert on candy bar types.

Actually, I might suggest a slightly different tact: provide a variety of candies (small boxes of nerds, Hershey's kisses, and the like) and have them selection sort by preference order.

They can also sort by height, brightness, weight, or duration of the candy experience.

And as long as you're at it, you might first have them just sort it one of those ways however they do it naturally, which can lead to a nice discussion about why we can't articulate what we're doing very well, but it's some sort of massively parallel selection sort.

Then you can do a number of sorts, culminating in your selection sort by preference order.  And at the very end, tell them all to look around at their neighbors sorts to see if there are any obvious trades that they should be making!


How to avoid getting emotionally attached to my students' projects? I run a workshop with a few students. They often do large projects alone that they inevitably run into trouble with. That's completely normal, it's why they need some help in the workshop.

As the instructor, I usually spot the issue and solution pretty quickly. I try and nudge the student in the correct direction, but they don't always get it. After a while, I become personally invested in the project, and I may end up just implementing the fixes I suggest myself (while they watch), and because they aren't responsible for the implementation, they gain less that than if I had let them do it. This happens especially when I help them with the initial design and architecture of the program, as I end up feeling a little like it's mine too.

How can I make myself pull back a little and not do the work for them?

I think this an essential and main part of teaching programming and cs (and teaching in general). The ability to hold the answer and guide the student to it.

What I do is try to follow the thought process of the student. When working with them to help them find the problem, I ask various questions (usually "what do you thing is causing this?" etc.) and by their answers it's possible to see what sentences would guide them to the solution.

This method works great (that sound out of the sky but it's based on student feedback) as it allows the student to feel that they found it on their own. I find that they also learn to spot issues on their own afterwards.

Additionally, it's worthwhile remembering that you are the instructor, and not the student. And that the project is a student's project, so keeping that in mind often helps with holding back from doing the work yourself.

However when all else fails, showing the students how you might do it could be a last (last) resort. Just be sure to explain every step you're doing, so that the student understands. I cannot express enough how bad this last resort is. But if it gets to that, make sure you're not doing their work, but rather show them something similar


Programming exercise Tagging I wondered what attempts were made to use tag(s) with programming exercises so that anyone can search / find (etc.) exercises just like books in a library.

For example (in user story format):

As a student in Java, I would like to find exercise on recursion.
As a student, I would like to find MCQ exercises for iteration

There are a lot of reasons this hasn't happened, and probably won't. The first is that the exercise would need to be published somewhere that was effectively searchable. Some instructors will post exercises online, but not all. Many, in fact, want to keep them private so that they can reuse them in the future. Posting them online often leads to bad behavior, such as searching for solutions, rather than actually doing the exercise as intended.

Another problem would be the establishment of a consistent set of tags. For a small site such as this one, it can be done, even if imperfectly. For the entire world wide web it would be a much harder (impossible?) task.

But if you have done all of the exercises in your course textbook and yearn for more, you can often find books of exercises on various topics. I think this used to be more common than now, but for some subjects they can be found. I remember Schaum's outline series in the past. The still seem to be in print.

Your course instructor can, perhaps, loan you another textbook with even more exercises.


An exercise in utility We have an incentive grading scheme for programming labs such that students get 89% for submitting a program that meets the basic requirements of the assignment, if submitted on time. To get the "extra credit", they have to add something useful on to the basic requirements, still submitted on time. We did this because we were having two issues in the classes:

Students were just doing the bare minimum
They were handing things in late

But, in a weird twist on Pareto optimization they now spend the first 89% of the time trying for the extra credit portion, and the remaining 89% of the time just getting the bloomin' thing to work correctly (Parkinson's Law).

I usually fail to anticipate this, so when I say, for example: "use Bootstrap to get your web page to look basically like this..." and the first thing they do is go to the "designer screen" in Visual Studio and start dragging, resizing, re-positioning, changing fonts, colors, etc, I am stymied. (It does not turn out well.) I was thinking that they would make some programmatic improvements to the very simple example, since most of the basic code could be copied right out of the textbook anyway.

Is there a way to encourage the students to get something working first, then enhance it? Is a grade incentive the wrong way to go about that? I suppose it is really down to me, as it says in the Art of War: "If the instructions are not clear, if the orders are not obeyed, it is the fault of the general." Good thing I do not have 160 students.

Actually, there are two questions here. I'll answer the obvious one first. You can fairly easily solve the perverse incentive problem by having two due dates: one for the first 89% and a later one for the rest. If you have ideas about what they should do for the second part, don't reveal them until they turn in the first part. You needn't necessarily even mark the work after the first deadline, but you can, if desired.

After the first deadline you have a version of the project. You can compare it with the second version to see what changes/enhancements have been made. In situations like this, I usually have students turn in work on paper and in the second version, mark changes (highlight markers) so that those changes are obvious.

The second question is how much you want to encourage student "creativity" anyway. It isn't always good to let students loose without specific direction. There are two kinds of creativity: the what and the how. In the real world, it isn't normally the programmer who is responsible for the what. That is up to the Customer/Client/Boss/Organization. The creativity on what belongs to them. On the other hand, creativity (i.e. excellence) on the how is the key attribute of a good developer. For most assignments that is what you should be looking for. Do they understand the algorithms? Can they implement them efficiently? Is the code clear and maintainable? Is it tested and correct?

So, I worry that if you just give an incomplete specification of the work and expect them to use their own creativity around what should be done, that they will get the wrong ideas about building things. As others have said in answer to other questions here, going outside your charter can be seen as a problem, not a blessing. See this, for example: https://cseducators.stackexchange.com/a/4539/1293

On the other hand, teaching creativity is also a goal of education and there should probably be one or more courses, or at least projects, where students do get to conceptualize, design, and build something interesting. But don't let them get confused.

Caveat. Those who work at startups that define their own product have a different view. There, it is often the case that programmers participate in defining the product, but that isn't the common case.


Explaining Event-Driven Programming in the context of the Structured Programming Theorem I'm a retired college teacher.  I've been asked to "teach coding" to a dozen very bright seventh-graders using the Micro:Bit kits the school has on hand.  I have a total of seven contact hours available.  In three hours, we've learned about algorithms, variables, and operators.

On Tuesday we'll write a program for "red light / green light" and learn the difference between sequence and selection.  The following week we'll do something with a loop and I'll add "iteration" to the vocabulary.  While I probably won't say "Structured Programming Theorem," I was going to tell the kids that sequence, selection, and iteration are "all you need."

The trouble is, the MakeCode block language has "on-blocks" which fire when events occur, e.g. "on Button A pressed."  You can't avoid these.

So, how do I explain events, or "on-blocks" in the context of sequence, selection, and iteration?  (The best I've been able to come up with so far is that there's a hidden loop of if statements checking for events, which is probably how the on-blocks are actually implemented, but unlikely to be satisfying to twelve-year-olds.)

I don't see that there's anything to explain, because there's no apparent contradiction between a set of language constructs being "all you need", and a language having more constructs than are "needed". Languages are designed to have constructs that are useful for human programmers to easily and concisely express what a program should do, not just a minimal set of constructs for it to be possible to express programs.

It's not even necessary to explain that event-driven languages are implemented using hidden conditional statements and loops; and as Buffy notes in the comments, they may not actually be implemented that way anyway. If you want to tell your students that they could be, then I see no problem with that. But consider this:

Untyped lambda calculus is Turing complete, so "all you need" is function definitions and function application. Does that imply that conditional statements and loops must be implemented with hidden function definitions and hidden function applications? Well, no, it doesn't imply that.
The logical NAND operation is functionally complete, so "all you need" is NAND gates. Does that imply that computers are made only of NAND gates? Again, no, it doesn't.
As shown in this paper and amusingly demonstrated in this compiler, the x86 mov instruction is "all you need", i.e. any C program can be compiled to a sequence of unconditional writes to memory (at addresses read from memory). But the rest of the x86 instruction set is, of course, not implemented that way.

What I will suggest is that if you do want to mention that sequence, conditional statements and loops are "all you need", then you should add that real programming languages have more control-flow constructs than just those, because the additional ones (e.g. subroutines/function calls and return, try/catch, event loops…) are convenient.


Can sharing learning stats be beneficial to guide beginner students? Context

The main consensus in most compsci programs I have been at is that a sizable amount of students is inherently unable to learn how to code. An old entry on Jeff Atwood's blog summarizing the issue cites this 2006 article by Saeed Dehnadi and Richard Bornat, claiming:

  Formal logical proofs, and therefore programs – formal logical proofs that particular computations
  are possible, expressed in a formal system called a programming language – are utterly meaningless.
  To write a computer program you have to come to terms with this, to accept that whatever you
  might want the program to mean, the machine will blindly follow its meaningless rules and come to
  some meaningless conclusion. In the test the consistent group showed a pre-acceptance of this fact:
  they are capable of seeing mathematical calculation problems in terms of rules, and can follow those
  rules wheresoever they may lead. The inconsistent group, on the other hand, looks for meaning
  where it is not. The blank group knows that it is looking at meaninglessness, and refuses to deal
  with it.

It even goes on as to propose some of the prospective students to be advised away from compsci courses:

  7 Conclusion

  There is a test for programming aptitude, or at least for success in a first programming course. We
  have speculated on the reasons for its success, but in truth we don’t understand how it works any
  more than you do.

Today, I found a retraction from Richard Bonat, claiming his conclusions were affected by his mental health issues:

  2 How it happened

  Though it’s embarrassing, I feel it’s necessary to explain how and why I came to write “The camel has two
  humps” and its part-retraction in (Bornat et al., 2008). It’s in part a mental health story.

  In autumn 2005 I became clinically depressed. My physician put me on the then-standard treatment for
  depression, an SSRI. But she wasn’t aware that for some people an SSRI doesn’t gently treat depression,
  it puts them on the ceiling. I took the SSRI for three months, by which time I was grandiose, extremely
  self-righteous and very combative – myself turned up to one hundred and eleven. I did a number of very
  silly things whilst on the SSRI and some more in the immediate aftermath, amongst them writing “The
  camel has two humps”. I’m fairly sure that I believed, at the time, that there were people who couldn’t learn
  to program and that Dehnadi had proved it. The paper doesn’t exactly make that claim, but it comes pretty
  close. Perhaps I wanted to believe it because it would explain why I’d so often failed to teach them. It was
  an absurd claim because I didn’t have the extraordinary evidence needed to support it. I no longer believe
  it’s true.

Question

I've been a TA for compsci courses in three colleges and, in all of them, transparency was a core value: past exams, classes, and grades were made available from the very beginning. Failure rates were never lower than 30%, often beating failure rates for subjects widely regarded as more difficult, such as physics or calculus.

On the one hand, some students might feel discouraged to put in the effort to learn knowing that they have a high likelihood of failing. On the other hand, it might be beneficial for them to know hiccups are expected and perhaps compsci might not be the way for them.

My questions are: do students benefit from knowing most of them will likely fail the subject? Should they be informed that there might be a high chance they won't advance past CS101?

We had a question recently that also touched on some of these same issues.

I am a fan of expressing that the material can be difficult, as it sets the tone and prepares students to work hard in a course. However, if failure rates are as high as you suggest, then that suggests something is going seriously wrong.

For context, I teach at a high school where kids apply during 8th grade into 4-year majors. They are tested in math and literacy, and we interview them to see if they are generally engaged kids. We do not evaluate them on programming or CS background, because most of the 8th graders have none.

If accepted, they cannot change their major at any point. That means that our CS kids will have a 4 year CS curriculum that builds upon itself, and it gives us teachers a very powerful motivation not to lose kids at the beginning. It simply isn't a viable option. A freshman who gets lost will probably remain lost for their next 3 years in the school.

Not every kid remains enthusiastic  about CS. That's okay! They applied to the school when they were quite young, and many move on to other interests.  However, over the last 3 years, we have had exactly one student not pass the AP test as a sophomore, and that student was dealing with significant mental health challenges that also brought about high absenteeism.

Now, a university program is not under the same constraints, and not every student at every institution can be classified as "gifted" (whatever that actually means), so I can absolutely accept that our results might be an outlier.

However, virtually everybody can learn to code. It comes down to what work the student puts in, and how well the instructor breaks down the concepts and designs the course materials.

My general advice to achieve high passing rates is to create good supporting materials to use with kids who struggle, and to break things down (and make connections explicit) far beyond what you would think you would need to. I know that that advice is quite vague!

And if you are ever unsure about how to break down an idea really clearly, ask around. (Heck, I could tell you about this one website devoted completely to getting answers to the problems of CS educators ... ;-) But please don't accept a 30% failure rate as the norm, or even as acceptable. So much more is possible!


Looking for a block-based programming language for AP CS P This question is specific for teachers of the United States College Board's AP Computer Science Principles class.

I'm looking for a block based programming language that allows for:

Procedures that return values
For each that will iterate through lists

In addition, we are to teach basic 2D robot programming with commands such as TURN_AROUND(), MOVE(), TURN_RIGHT() etc.

My research has come up with MIT's Scratch IDE; but I was wondering if there is a better choice for high school students.

You will probably want to look into Snap!. It was built upon Scratch and would probably meet your needs. This is from its About page:

  Snap! (formerly BYOB) is a visual, drag-and-drop programming language.
  It is an extended reimplementation of Scratch (a project of the
  Lifelong Kindergarten Group at the MIT Media Lab) that allows you to
  Build Your Own Blocks. It also features first class lists, first
  class procedures, and continuations. These added capabilities make
  it suitable for a serious introduction to computer science for high
  school or college students.

Additionally, I asked a question a few weeks ago about the differences between Scratch and Snap!. You might find this discussion helpful: "What can Snap! do that Scratch cannot?"

Edit: In the context of AP CS Principles, it may also be helpful to know there is a full curriculum available from Berkeley that utilizes Snap!. It is called The Beauty and Joy of Computing.


Creating a rubric for computer arithmetic I'd like to move to mastery-based grading and have drafted a set of rubrics for my undergraduate computer architecture class. I am having trouble with the one for computer arithmetic, which includes two's complement and IEEE floating-point formats. I have the following criteria:

Converting between decimal and two's complement, including
identifying the largest and smallest numbers
Comparing two's complement numbers
Understanding two's complement limitations (carry into and borrowing from the sign bit)
Converting between decimal and IEEE floating-point formats, including identifying the largest and smallest numbers (not counting
special values).
Comparing floating point numbers
Understanding floating point limitations (underflow, overflow, range limits, precision limits)
Choosing best numeric representation, given range, accuracy, and performance requirements

I am concerned that there are too many critiera. (Not shown are the ratings for different levels of proficiency.)  It also raises the question of how a student shows they know how to, say, convert between decimal and two's complement. Do I keep testing them until they show me one successful conversion in each direction, or do they have to demonstrate that they can consistently do so? Is this too trivial of a skill to test, given that they'll forget the details, which aren't really important, five minutes after the test?

I missed this question!
I will attempt to provide feedback in parts:

I am concerned that there are too many critiera.

I don't understand the reason for this concern, so I cannot comment upon it. The criteria seem reasonable to me.

It also raises the question of how a student shows they know how to, say, convert between decimal and two's complement. Do I keep testing them until they show me one successful conversion in each direction, or do they have to demonstrate that they can consistently do so?

I would personally be happy with a one-time demonstration within my own classroom (see below)

Is this too trivial of a skill to test, given that they'll forget the details, which aren't really important, five minutes after the test?

I think it's perfectly acceptable to explain to students that you are asking them to learn a skill that you expect will be temporary (converting a floating point number to IEEE) in order to help them get their heads around a deeper, more profound understanding that you hope will be permanent and intuitive (e.g. the general nature of floating point in practical computation).
In my classroom, I have students reproduce proofs with a similar explanation. I explain that, after memorizing a proof and reproducing it for me, I do not imagine that they will be able to reproduce it again 5 years later.  But I expect that they will come to understand the structure of the proof well enough that the next time they encounter such a structure, they won't be immediately lost, and I also expect that they will roughly remember that the fact that they proved is, itself, true.
In this case, while none of your students will presumably remember, give years out, exactly how to figure out what the least significant bit would be in an IEEE representation, you can expect that the students will (long term!) remember the tiered nature of the IEEE structure, and the broad-strokes, general elements of what it stores.
I think those are good and sufficient goals, and I think that the students will be okay with learning it as long as you break down the expected long-term benefits of the short-term learning.


Through what basic programming language can beginners easily get the concept of programming? I have some students that are from medical background and have no concept of programming. So, which language I should teach to them to make their basic concept of programming perfect?

Actually, this depends much more on the teaching methodology you use rather than the language. The best answer might just be the language that you, yourself, are most productive in. But if you aren't a programmer yourself, it may be very difficult for you to teach them.

But, if I had to name a language that is (a) fairly modern and (b) fairly forgiving of beginners and (c) widely used and (d) a useful tool for people with other interests, then it would probably be Python. If you give up one or more of my criteria there are many other choices.

But the teacher needs to be proficient in the language and its use. Programming is a way of thinking, not just knowledge of the features of a language. I worry that, just because you are asking this question, that you may not have the required background to do a good job of this.

However, all is not lost. I asked a question of my own here a while ago that might provide some guidance to you if you are, indeed, a novice programmer yourself. See the question and at least my answer to How do you teach something when you don't know it yourself.  The short version is you admit your lack of knowledge and learn it along with the students. But first you need to find good tools and resources.

If you use Python, make sure you use V3 and not the earlier and incompatible V2. It isn't any harder to start with the current version.


What can Snap! do that Scratch cannot? I teach a short introductory unit in my course that uses Scratch to get students familiar with programming concepts before introducing the syntax of a text-based programming language. For context, we move from Scratch to C to Python.

My question is this: what can students be taught in Snap!, as another block-based programming environment, that they cannot be taught in Scratch?

I read on their site that it Snap! combines Scratch with Scheme, but as the latter is not a language I've studied, I don't quite see the motivation for this combination.

The analogy is far from perfect, but Snap! is to Scratch as Mycroft is to Sherlock.

For me, the big advantage for Snap! is its provision of custom functions rather than just the custom blocks that Scratch 2 offers - Snap! functions return values that can be passed to other functions and so on, making it much easier to implement mathematical ideas and to build up programs by defining rules and relationships rather than sequences of steps.

In Snap! functions are 'first class citizens', thus functions can be passed to other functions as parameters, or be stored in lists, or (pretty much) whatever, and so Snap! can be used as an introduction to functional programming.

In short, Snap! makes it easier to address much more theoretical CS than is convenient in Scratch, without introducing the need for text based programming.

On the other hand... Snap! doesn't have the same rich range of support materials or vibrant support and sharing community that has made Scratch such a success.


Cheating detection script The pandemics has incredibly increased the number of cheating cases. Do you know of any script (bash or other scripting language) for checking a bunch of Java code submissions for similarity? I know I could use diff, but it would be hard to detect similarity.

Take a look at MOSS from Stanford (https://theory.stanford.edu/~aiken/moss). It is an easy to use free web service that compares files and reports similarities. You set up a free account and submit a request and what is returned is a URL to a report showing the similarities of various files.
I have found that the easiest way to do this is to submit a .tar file structured at the first level as a series of sub directories, each identifying a single student (name, studentID, etc). Beneath each student directory are the file(s) they have submitted. These commonly have exactly the same names as the assignment typically specifies the class names of the Java classes.
For small assignments, you will get a high correlation between students as there is only so much variation possible, but you can look at the "most similar" and get a good feel for whether cheating is likely to have taken place. Depending on how the students actually submit their programs, it may be easy to write a script that automates the process. I'm happy to share details with anyone


Designing rubrics for AP Computer Science-style free response questions When I create questions in the style of the College Board's AP Computer Science Free Response Questions, I always attempt to create authentic rubrics that reflect how such questions would be graded.  However, I have not found any clear guides about how to do this.  I have noticed a few trends, but I wonder if anyone else has more (or something more definitive):

If a method requires a return, making a return is typically worth a point
If parameters are given, utilizing them at all is awarded some points
If arrays are present, looping through them with no chance of an ArrayIndexOutOfBoundsException is awarded 1-2 points. (If you need to loop through a String, that could also go here.)
Dealing with funny edge cases is often worth a point.
Utilizing the appropriate methods from other Objects passed in is often awarded a point, though no penalty is made if they successfully recreate the functionality that the Object would provide.
Appropriately comparing two array neighbors without out-of-bounds potential, if it's that kind of problem, would be 1/2 a point, and correctly comparing all neighbors would be an additional 1/2 point.

You can see rubrics for the 2010 exam here as a sample.  Obviously, being able to create high-quality AP CS FRQ rubrics would help get the kids used to such grading - it could be the grading style used on exams through the entire course.

In the weeks leading up to the test I typically only use the actual past tests for exactly that reason. But even when I don't use the released FRQs I still grade on a 9 point scale so they get used to it.

Here's a few more that tend to come up.

For return methods, create a variable of the correct type, do something to it, and return it.

If it's a constructor, it should initialize the instance variables.

On full class problems - either write a full class, extend an abstract, or implement an interface - it's usually a point or two for the class signature.

  Utilizing the appropriate methods from other Objects passed in is
  often awarded a point, though no penalty is made if they successfully
  recreate the functionality that the Object would provide.

Sometimes. And sometimes they explicitly say that you must use the previous method for credit. #3 on the test this year did that.

I also have a negative rubric point for any of the penalties. Destruction of data, unexpected side effects, returning from a void, that sort of thing.


How many of "The Seven Laws of Teaching" are still relevant for teaching computer science today? Wikipedia  shows that in 1886 John Milton Gregory outlined his "The Seven Laws of Teaching";  asserting  that a teacher should:

Know thoroughly and familiarly the lesson you wish to teach; or, in other words, teach from a full mind and a clear understanding.
Gain and keep the attention and interest of the pupils upon the lesson. Refuse to teach without attention.
Use words understood by both teacher and pupil in the same sense—language clear and vivid alike to both.
Begin with what is already well known to the pupil in the lesson or upon the subject, and proceed to the unknown by single, easy, and natural steps, letting the known explain the unknown.
Use the pupil's own mind, exciting his self-activities. keep his thoughts as much as possible ahead of your expression, making him a discoverer of truth.
Require the pupil to reproduce in thought the lesson he is learning—thinking it out in its parts, proofs, connections, and applications til he can express it in his own language.
Review, review, REVIEW, reproducing correctly the old, deepening its impression with new thought, correcting false views, and completing the true.

My question is in today's on-line high stakes testing environment, how many of his "Laws of Teaching" are still relevant; in particular, to the teaching of computer science at the K12 grade school level.

These "laws" mostly reflect how people learn, so they are still quite relevant.  But going through:

("Know thoroughly and familiarly the lesson you wish to teach; or, in other words, teach from a full mind and a clear understanding") is interesting in a CS context, since we often don't have fantastic knowledge of the material, because it is so new. We have a question about that which has some interesting discussion on teaching what you don't really know.

("Gain and keep the attention and interest of the pupils upon the lesson. Refuse to teach without attention.") This is more a matter of philosophy, I think.  I sometimes do this, but I sometimes quite deliberately do not.  It depends on the goal of the moment.  As an example, there are sometimes things that I will do to help a subset of the students in my class.  I will even sometimes accompany this with directions such as, "if you weren't sure about number 3, then I will go through it very carefully because understanding this idea is key to understanding this field of study. However, if you got it right and feel quite confident that you understand ____, you can turn your attention to the lab for the next ten minutes or so."

("Use words understood by both teacher and pupil in the same sense—language clear and vivid alike to both.") This is (I hope) always the goal of communication, no?

("Begin with what is already well known to the pupil in the lesson or upon the subject, and proceed to the unknown by single, easy, and natural steps, letting the known explain the unknown.") This is surprisingly controversial.  (Consider Anthony Gregorc's learning categories)  However, it pretty well reflects what we know about how the brain learns.  (See the section on encoding), and it is certainly (uncontroversially, as far as I know) the most time-efficient way to impart information.  You might argue that there are possible long-term benefits to less-efficient means of instruction, such as supporting the soft skills in students of teaching themselves.  That is a controversial position, but certainly one that many people hold, particularly with older students, when it arguably has the least benefit.

("Use the pupil's own mind, exciting his self-activities. keep his thoughts as much as possible ahead of your expression, making him a discoverer of truth.")  This is edge-of-your-seat teaching, and is unquestionably good! Though it can be quite hard to do well -- some topics lend themselves to this more than others.

("Require the pupil to reproduce in thought the lesson he is learning—thinking it out in its parts, proofs, connections, and applications til he can express it in his own language.")  Other than the controversy I mention in #4, this is clearly good teaching in any topic.

("Review, review, REVIEW, reproducing correctly the old, deepening its impression with new thought, correcting false views, and completing the true.")  This is how you remove misunderstandings and help students transfer information to long-term storage, so it is vital.  Again, in some classrooms, teachers may deliberately choose not to do this, as it could be viewed as hand-holding when students should learn to be independent learners, even at the cost of immediate progress.

I've mentioned a few times the notion of allowing instruction to move slower in order to help students develop their own learning skills.  I almost entirely fall into the other camp, and believe that direct instruction can also help to create self-learning skills, but much of that depends on the richness of the information being presented.  I also provide some direct instruction on how to self-learn, and how students can monitor their own minds and understanding more effectively.  I don't have any way to know whether I am correct in this approach; it's unstudied, so it is more philosophical at the moment.


What is the best approach to learning things in CS? What's the best approach to learning a library, framework etc.I find it overwhelming initially as to where should I start learn such things. Is it like you start taking up a course and then try to implement it. Or just start applying directly and learn as you go. If it's the latter could you just elaborate what you do? As I start studying in the latter way i.e learning as I go, I find myself getting a lot of doubts and confusion regarding the content. I start with tensorflow for eg, but I end up searching for different things as new things come up while studying, this makes me frustrated and directionless. What approach can I take here?

The best approach to learning just about everything is twofold. You need to practice and you need feedback on your attempt. You learn by reinforcement, not by seeing something once. This is why coursework depends on student exercises, not just lectures and textbooks.

So, to learn a new thing, I suggest that you first get an overview idea of it, say from some internet readings or a book. Don't go too deep into it yet. Then, find a project that you can build using that technology and work on that. Go back to readings and such as necessary when you get stuck, but make the project and its completion a learning goal. Your readings may suggest a project, actually, but don't use too much of the explanation of the project, or especially its solution, to guide you. Build it yourself.

But that doesn't solve the "feedback" problem. This is always difficult for self learners. "How do I know I've done the right thing?" Perhaps you can find a more experienced person to give you feedback. A teacher or professor with wide experience is probably best. But you can also try to find or form a group of people with similar interests that you can meet with to share ideas.

In the absence of other things, if you can find an actual text book on the topic, it will probably have exercises. Do as many of them as you can find time for, without reference to any answer key. Find a way to verify your answers (feedback), even if it is just a testing framework that verifies your intent.

I'll also note that learning on your own is difficult for other reasons. Suppose you know A and want to learn B. Your approach to B will probably be heavily influenced by what you already know of A. But that may not be the best approach. Knowing the C language and trying to learn Scheme, for example, requires a clear break with what you already know and you need to take a new mental approach. Even moving from one language like Java to a "similar" one like Python, requires a fair amount of rethinking.


Lambda expressions exercises and practice While lambda expressions in java 8 are really cool in action, the school curriculum offers no exercises in this. So essentially, students never actually learn how to use lambda expressions and the java 8 functional interfaces that go with it when teaching in java (i.e. Stream, Predicate etc.)

There are a few periods for labs and practice which can be devoted for lambda expressions, but I am not sure what kind of labs I can make, which are focused on lambda expressions (not only utilizing them).

What I did think of is asking them to perform a number of tasks:

given a List of String and some condition (not coded as a Predicate, yet...), return a List of all strings that meet the condition. This exercise is meant as a starter. Just to get them going.
Here the fun starts Streaming. They are given a list of objects (which I wrote) that each have a String and an Integer. They need to return a list of the integers from those objects.

The problem is that those two are very short, and are introductory. I am trying to think of other exercises or tasks which are almost entirely with lambda expressions.

Which kind of exercises could I give the students that would both show them just how cool lambda expressions and the functional API are, but also give them plenty of hands-on experience with what Java's functional API has to offer?

(PS, the students are high school students)

One of the interesting things added to java in v8 is functional interfaces. Previously java only matched things up and verified correctness by type (type names). With functional interfaces, java now looks at the structure of code in certain situations.

I can add examples to this answer to clarify if anyone asks.

One interesting feature you can add is a method to do simple repetition. I like to teach a lot of things before if and while, but sometimes you just need repetition and the most common sort is a constant-number-of-iterations loop.

@FunctionalInterface
public interface LocalCommand
{
    public void accept();

}

/**
 *  Repeat a method a given number of times
 * @param howMany number of times to repeat the method
 * @param what the method itself, as a Command. Especially useful in Java 8
*/
public static void repeat(int howMany, LocalCommand what){
    for (int i = 0; i < howMany; ++i){
        what.accept();
    }
}

Usage:

public void aCommand(){
    // do something interesting
}

repeat(3, aCommand()); // structural matching with the functional interface
repeat(3, () -> {aCommand();}); //lambda expression
repeat(3, () -> {System.out.println("Hello");}); //lambda expression

In java 8 you don't need to ever explicitly say that aCommand is, in fact, aCommand and you don't need a new enclosing type to implement the functional interface. You don't even need to specifically say that it is a functional interface, Java will grok it by structure alone.

With repeat(...) in my library I can do repetition before I need to talk about for and while loops.

I used only the simplest case of a functional interface here. You can use Consumers, etc just as well with only a bit more complexity.


Do you know online courses with Haskell for Theory of Computation? I taught Theory of Computation last Fall and I believe it would be more interesting for students to add some coding implementations. Are you aware of any online course or textbooks in which Haskell (or other languages) are used to teach CS Theory concepts?

This is another not-an-answer that might provide some useful resources. The last is probably the best, but not Haskell related
The two old standards for such a course are:

Introduction to Automata Theory, Languages, and Computation, by Hopcroft, Motwani, and Ullman. Earlier editions were just Hopcroft and Ullman.

Introduction to the Theory of Computation by Sipser.

I don't have the second book, and don't know if it includes any programming exercises, but there might be something in Scheme, knowing Sipser. Amazon's "Look Inside" doesn't seem to work for Sipser.
Two additional books, both very old and hard to get but very highly recommended if you can find them - both short and straightforward with clear explanations are

First Course in Formal Language Theory (Computer science texts)
by V. J. Rayward-Smith, and

First Course in Computability (Computer Science Texts)
by V. J. Rayward-Smith

The final suggestion is a software system with an associated text.
JFlap was created by Susan Rodger and her colleagues at Duke to form the basis of such a course. Students can easily create all sorts of finite automata. The book they wrote to go with this is JFap: An interactive Formal Languages and Automata Package, Rodger and Finley.
Wikipedia has an overview of JFlap.
Note that JFlap writes automata descriptions in XML which should be easy to parse in any language. All of the automata mentioned in the JFLap tutorial are available for download.
I was part of the NSF evaluation of this system and it is really excellent.


What is the closest pair problem useful for? The closest pair problem is the famous problem of finding out the closest pair of points given an arbitrary set of points on a plane. This problem has a divide and conquer algorithm and often is used in algorithms classes to illustrate the divide and conquer paradigm.

I also intend to do the same, but I would like to begin with some comments on why this algorithm is useful. Are there any interesting examples I can use here? A google search reveals nothing.

This is for an introductory algorithms course, and the audience is not expected to be an expert on this topic and has a mediocre level of mathematical maturity.

Rosen, Discrete Mathematics and its Applications, Sec. 8.3, says:

  This problem arises in many applications such as determining the
  closest pair of airplanes in the air space at a particular altitude
  being managed by an air traffic controller.


Use of “learnable programming” (via direct manipulation) software, in teaching I read something on this site, that lead me to read about Bret Victor's learnable programming and direct manipulation.
I was wondering if anyone has used any software like this.
What software have we used? What effect did it have on teaching and learning?
What is direct manipulation, also referred to as learnable programming
Victor tells us that the techniques that we now use, are based on best practice from the days of paper and pen, teletypes. That we have not yet adapted to this new media and what it can do. That typing a program, and then immediately running it, is not immediate enough. Output should change as code changes, not wait for us to press run. We should be able to manipulate the output, to change the code. Not just manipulate the code, to change the output.
 An example: Here we see the programmer, manipulating a variable, by using a slider. We the the effect on the output. We see the effect over time. The programmer is trying to give the turtle the correct bounce, so that the jumping character will be able to get through the gap. The programmer no-longer had to do long calculations, or do guess/change/run cycles. Whey just slide the slider until they see what they want.
see:

Invention on principle (programming perspective)
Stop drawing dead fish (an art perspective)
The future of programming (a historic perspective)
LearnableProgramming good blog post on teaching and learning progrmming

Preference is for Free Software, that is software with freedoms, not with zero price (I do not introduce proprietary software into my school).

App Inventor syncs with a tablet so that as students change the app's code, it changes the app running on the tab. It can't auto-sync media, so you have to re-sync the app when you add new sound or pics. It syncs via wireless network or usb.

Khan Academy offers this slider concept with its Javascript Animation lessons.