How might I structure an assignment with two "levels"? I've been mulling this over for several hours, and have looked at a tangentially related question here.  That question was about making a task more challenging for a "more confident" learner. I have what I call "hacker versions" of programming tasks in code, such as producing a GUI version of RPSLS rather than the CLI style we do initially in class.  There were no extra points.

Here, I was wondering can I/ should I have a "simplified" assignment that would be "easier" and be weighted "downwards".

The class have previously completed a use case (table and diagram) for accessing a course on Coursera, so they had to identify a range of use-cases, including identifying 'extend' and 'include' cases.

I teach a course (introductory) in software architecture at roughly the level of first year in third level.  The outline for the assessment (1 of 8 summative assessments) states "Derive a test case from a provided use case".  Examples in class were the "classic" ATM test-case, as well as a vending machine and an e-payment site.

At the same time, in another module (code) we used the doctest module (Python) with the testmod() function to check test cases in the docstring.

I created a simple use-case diagram for submitting an assignment on Moodle.  There are a number of test cases that this prompts.  I am/was considering another (perhaps simpler) use case based around the type of code we did in class and this prompts several types of exceptions and even an alternate flow.  I wrote some code here as an example of what I am considering.

The test-case template would have to be completed by the learner to show that they have considered all the possible problems that can arise... for example, a negative int should raise a ValueError, using two strings should raise a TypeError and so on.

I did a sample test-table in class based on a area_circle(rad) function, and so I was thinking this might be an option for the "less confident" (as described on CS50 pset2 referenced in the first link) but as I think about it more, if the learner completes this then they achieve the learning outcome, and I should NOT have it weighted to be of less worth than one which could be considered more difficult.

Now, after all this, I am inclined towards giving both options to the class, with no differentiation between points, but I still wonder:

1) Should I offer both options?

2) Is there ever a case for creating an assessment with "less worth" to allow a learner achieve some marks, or if the "lesser" task demonstrates that they meet a learning outcome, is this unfair?

Has anyone done something like this (easier version with less points)

I know I could have been more succinct in my question, but appreciate any feedback you can give. Thank you.

I didn't go through all the details, but can share an experience. I once taught a database course to a bunch of good students. The course covered lots of things such as relational theory as well as the internal structure of the data in such a database system.

For one assignment I gave the students a choice, either a simple one or a rather harder one. The harder one was to implement B+ trees if I remember correctly.

The easier one had something to do with hash maps or such.

The instructions were that you could choose which, but if you'd already in your life built a hash map then you would find the easy one boring and the other would be interesting. A surprising number actually did the harder assignment.

They were weighted and graded the same. There was no benefit to the harder one other than learning.

But the students were eager to learn and that made it possible.

But I'd recommend against a system in which only low grades could be earned from a simpler assignment. I think that is psychologically damaging. Like deciding to fail before you even start.


Code highlight for classroom use I am thinking about "dissecting" my code with students, going line by line and commenting (why is this the condition of the while? What does this piece of code do?)

A simple example can be found here: https://docs.google.com/document/d/1mxTE_E2_YKq-yhaXAfBxYP11uaRm7bSXTnP55bMnPyQ/edit

However, I would like a better tool for the job. As you can see, in docs, the comments are far away from the code and not linked to their respective by any visual cue. They are also all on the same color.

I tryed some highlighting tools for docs, but they seem to just highlight,not add colored comments

I am looking for ideas, inside or outside google docs, to do the job.

For inspiration (no way am I ever doing something this pretty!) here is an image from a headfirst book

I would suggest two things. Both of them, however, require that you give them printouts of the code so that they can make notations of their own without having to use any tool. Just write on the paper. Also, I'm assuming that your code is in small pieces, say, short methods. For me, a method is long at about five lines and a method that covers a page is incomprehensible. I have anecdotal evidence from industry that the latter is also true.

One method, assuming that you have given students the code is to just project it from your normal IDE and highlight it with the mouse. Ask the students about it and talk about it. Asking is probably more effective. You don't need to write anything.

Another uses a tool like Powerpoint. Build a deck in which each page shows exactly the same code but with different sections highlighted as you desire, using one or more colors. You can flip between pages as you talk, flipping both forward and backward as needed. But, again, ask the students to explain, rather than giving your own explanations. This way you can pick up misconceptions they might have and correct them. Make sure that the code itself has the same alignment on each page. Then when you flip, only the highlighting changes and students don't need to readjust the context.

Perhaps you can project against a writable surface rather than a screen. If you project on a whiteboard (and can ignore the glare) you can use marker pens to annotate - especially when the students say the right thing.

Make it interactive. Broadcast is much less effective.

Also, since you are putting effort in anyway, make sure that you always use intention revealing names in your demo code. Don't use x, y, z, i, j, k. Make the names come from the problem being solved, not the solution. For example counter is a name from the solution. But negative_value_counter is a name from the problem (of counting negative values - duh). In this way, if you are primarily teaching them about how to structure programs, you can focus on the structure (if, while, ...) rather than having them wonder about the purpose of abstract names.


Should I Provide Answers To Exercises? I'm preparing some exercises to introduce software developers who have no experience with Scheme to the language. Part of the exercises are simple things like:

Create a function that squares a number passed to it

I've been sort of debating whether or not I should include answers to the exercises or if I should provide them as a separate document.  I think it would help the students to be able to examine one approach to doing this--a reference implementation as it were.  But I do have some concerns about the students not even trying to do the exercise themselves before looking at the answers.

Should I provide answers to the exercises? If so should I include them as a part of the document with the exercises or as a separate document?

I realize this is a vague question so if I need to narrow it please just tell me. I can't think of a less generic way to ask the question right now.

I post solutions after the due date of an assignment. And usually, I'll go over them in class as well.

Two birds...

Students get to see at least one working solution, although I try to come up with several.
Posting the solution serves as a good block to students asking to turn in assignments late. They'll understand pretty well that they can't turn it in late after I've already posted solutions.

I've been trying this year to make videos of me working through the problems. Sometimes they'll be screencasts of me working through the problem in front of the class. Sometimes they'll be a little more scripted and recorded when there aren't students listening. Usually it's the shorter problems where I'll just record myself during class and the longer ones that I script out a bit.

Another activity I like is to do code reviews. I'll screen shot several student submitted solutions and we'll go over them anonymously. I'll include a couple that are really good solutions. But, better than that, I'll also include a few that are really close but not quite a working solution.

On some assignments, especially those that are a little more difficult, I'll provide a pseudocode algorithm with the assignment as a bit of a cheat sheet. Nothing that can be just typed in, but sometimes students need a little bit of a nudge in the right direction.


Strategies for self-learners to transition into working on larger projects A common problem I've noticed many beginners (especially self-taught ones) run into is figuring out how to transition from working through tutorials and exercises to working on full-fledged projects. There seems to be almost a "cliff" of sorts that many find challenging to scale for a variety of reasons (that are probably not worth enumerating here?).

One way to make it over this "cliff" is to find a teacher that can help guide you through progressively more challenging projects. Of course, this isn't a path available to self-learners by definition.

The next best alternative is probably to find a tutorial or online course that does something similar. Unfortunately, these resources either appear to be hard to find or simply inadequate (?), based on my (anecdotal) experiences answering beginner questions on another forum.

Taking all this into mind: What concrete advice would you give to self-learners who are struggling to transition to working on larger projects?

Edit: To answer @BlackJack's question: by "larger project", I mean a project that:

Does not immediately follow from a tutorial or exercise: finishing the project requires a fair degree of independent work.
Is "large" and "challenging" relative to the expectations and abilities of a beginner -- for example, it might take a beginner a few weeks to complete a "large project", but an experienced programmer might be able to pull off the same thing in a weekend.
Is not a "single-file project": there are lots of things you need to do and lots of details to keep track of.
At the very end of the scale, a "large project" might be the sort of thing an intern or an entry-level junior developer is asked to do. (Most beginners will probably likely need to complete multiple easier projects first before they're at this level, though.)

Some examples of large projects for beginners:

Implementing an interpreter or compiler for a programming language
Writing a video game (either a feature-rich prototype of a novel game, or a polished clone of some existing game)
Writing a webapp or mobile app with a non-trivial frontend or backend (for example, implementing their own basic search engine)
Rigging together some relatively complex automation using a few Arduinos/Raspberry Pis

You have set a difficult task. The reason is that there are two dimensions here, not one. The first is that larger projects are usually built by teams and not by individuals. Certainly if you are interested in preparing for employment, then teamwork is essential. The second dimension, independent of the first is that larger projects are normally built to the vision and specification of someone other than its builders.

This leaves four cells in a grid. You probably already have experience building alone and to your own vision. This is the easy case. The hardest is building in a team to someone else's specification. You can get there immediately but it is very difficult to transition that way. Instead you can first move through one of the other cells.

You can find a team to work with you on some project of your own vision. You can, perhaps, find a description of such a project online or in a course description. You can also just try to replicate some software that you normally use that seems big to you. Build a spreadsheet program, for example. The hard part, however, is to find the team to work with. Note that the project need not be terribly large, but you will learn important large-project skills in any case.
An alternate way is to move into the other cell. Build something yourself, but with another person specifying the program. This will be a lot harder than what you usually do, but is an essential step. One way to find the problem is to find the client. It could be a teacher with a need. It could be a local social service with a need. It could be anyone with a need. But you need to give complete control over what is to be built over to the client, while you are creative only on the how to do it. Again, the size of the project is less important than that you are learning how to work with a client.

Once you have some experience in one of the above, you will be ready to move to the externally specified-team built cell. But the experience in the simpler case may give you some insight into how to find the team and the client. Scaling at this point will be more reasonable than you think.

Good Luck.

I should not that even in formal education, when a project is specified by a professor, it isn't quite the same as working for a client. The typical university project normally grants the student a large part of the design space. A true client will not. Normally the professor won't ask you to change direction in the middle of a project. A client might. A professor might grade you. A client might just reject your work or ask you to do it over. A university project is normally thought out completely in advance by the professor. A client may make it up as you go along.


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

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

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

Here are the three stats I wanted to share:

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

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

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

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

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

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

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

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

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

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


Real world example application built with Python and JavaScript? Does anyone have any suggestions on a small program or application to write that would help a Python beginner work with JavaScript? For example, when one is learning JavaScript, building a small to-do list application is often practiced.

Is there something that meshes well with Python and JavaScript? Looking to gain some experience in writing a real-world application rather than watching video courses.

I have just written myself a web-mark server, to store book marks to my website. I got fed up with the proprietary ones, and decided to make one of my own (probably could have found a ready made one with a Free Software Licence).
It used Couchdb. This involves writing code in Java-script (the manual says that the server side code can also be written in python, I chose JavaScript, so it would help be learn it), but because it provides the framework, you write lots of small functions. You will also end up learning about the no-sql db couchdb, http, and client side web design (html, css, Java-Script). I used jquery and knockout.js on the client side.
First things first
Because I did not follow a tutorial, I ended up looking stuff up as I went. This would probably be to effort-full, if it was your first language, as you would be looking up everything, and not know what to look up (how can you look up how to do a foreach in java-script, if you have not yet heard of a foreach.
Therefore it would be beneficial to find a tutorial to do first, then work on a project.
You can also work on an existing project. There are many Free Software (Open Source) project that you could help with. It is much easier to contribute to an existing project, that to start from scratch. If you want you can contribute to my bookmark project. (If you do work on someone else's project, and it if for an assessment, then ensure that you tell the assessor what bits you worked on).
Learning two languages at a time may make things confusing, and make it take longer to learn. However research into natural languages shows that, for babies and infants, learning two or more languages at a time has a positive long term affect. Though it does slow externally measurable performance at first. For these children the languages are in different contexts, one for each parent, or one at home / one at school. I would suggest that you focus on one language, until you get sufficiently skilled.
Python seems to be widely used as a teaching language (1st scratch, then python). JavaScript has may pitfalls. A good language to learn Object Oriented is Eiffel. However you could learn, non-OO first (OO just adds to structured, most modern languages are structured or structured+OO). Therefore, if you have not used scratch, then have a play with it, then start on python.
Other project Ideas — python

Unix command line tools: rewrite some of the Unix tools (I did this in C in 1st year at university).
Create a web-server: there a libraries in python.
Something with a Raspberry-Pi: these thinks have connectors to add some sensors and output devices (barcode scanner, rfid reader, LEDs, motors, relays, buttons, …). They also run Debian Gnu/Linux ( Gnu/Linux runs on 490 of the top 500 super computers (the other 10 are other Unixes), ⅔ of web servers, most of the internet infrastructure, and a lot of inbedded systems.
A game: 2D (the SDL library is very good), or text adventure / interactive fiction.


Distributed Pair Programming in distance education We've done pair programming for years with the rule of two kids, one screen, and the kids sitting next to each other.  We have found this to be a tremendously valuable process.

Now that all instruction is distance learning due to COVID-19, are there virtual solutions that would allow our students to simulate something like this?

My suggestion would be to utilize seprate tools for elements of the process rather than try to find a packaged solution, or modify an existing tool which is 'not quite right' for the task.

Quick summary is:

use Discord for communications, text and/or audio

Restricted channels for each pair to utilize while coding
Open channel for students to contact the instructor

use the GoLive feature of Discord for the "driver" to stream their active IDE to the "navigator" (GoLive will stream a "terminal" window, it does not have to be a game.)
use git to "lock in" the code between role switches with commits
use GPG keys for signing of commits and to authenticate the SSH pushes
use GitLab as the remote repository

Use Discord for communications

As the instructor:

Create a Discord server
Create a public text channel for the students to reach you in
Create a public text channel for the students to share in (you can monitor, but don't communicate here)
Create a role for each assigned student pair
Create a private text channel for each role above
Create a private audio channel for each role above
Enable each role to send/read messages, or connect and use GoLive, in the role-specific text and voice channels
As students join, however you get them to connect, assign them to the role which matches the assigned pairings

As the owner of the server the instructor will be able to read the chat in all text channels, hear the conversation in any audio channel, and view any of the windows being streamed. Instructor preference and style take priority, but my suggestion is to limit any messages sent by the instructor to the designated channel. Moderator type actions can, and of course should, be taken in any channel. Going remote still leave "classroom discipline" in the instructor's hands.

As the school term progresses, it's likely that pairs are reassigned frequently. Perhaps as often as each new project. Once a project is graded, the associated text channel could be reset, or removed.

Use git

While git may not be The one true source control system, it is a popular one. The command line use of it can be quite complicated, especially for advanced purposes. The basics of it, however, are quite manageable for students. GUI tools also exist, though I'm reluctant to endorse any one, or even recommend their use. With students learning to use git it is probably better for them to learn the CLI commands, which will work on any OS, and on any system with git installed. The GUI they learn might not work on the system they have to use later, for work or for advanced classes. The GUI probably won't work if they have to use SSH for any reason as well.

Using git, as long as both students have access to the repo, allows for one to make changes, commit the results, and pass control to the other when they switch roles. As an extra benefit, since the current "navigator" will have the last committed version locally, they can scan through the file(s) to review other parts while directing the "driver". Ensuring that identifier names and parameters are used correctly, for example, without disturbing the "driver" with those details, allowing the driver to concentrate on the section of code being changed.

As a benefit to the students, they'll have the ability to unroll changes that were leading down a dead-end. As a benefit to the instructor, each commit will be blamed to the student driving. Additionally, by following the diffs, it's likely that when the team gets lost in the weeds, the instructor can see what thinking started the problem, and help them to see the way out.

Use GPG keys

The "remote" aspect of this is challenging for instructors to "watch" the students work. Having to worry about who is doing the work and who is not only adds to the work load. Requiring that the students GPG-sign their commits can help with that some. Not only will the repository assign the updates to the user, it will also verify that the user claiming the updates is the same one who signed them. There is no encryption involved, just a signing of the commit to prove who made it. Using it, however, might require the students to install GnuPG on their systems. Encouraging them to do so shouldn't cause any issue, and it can be a good habit to develop for later as well.

The process of setting up a key for use with the git program, and for connecting to the remote repository is fairly simple. Even from the command line.

Generate the key pair to use. The key pair needs to have both singing and authorization capabilities.

gypsy@spellweaver:~> gpg --quick-generate-key "Student Name <email.name@some-school.edu>" future-default auth,sign
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key A822359C643A77A4 marked as ultimately trusted
gpg: revocation certificate stored as '/home/gypsy/.gnupg/openpgp-revocs.d/11716FF672B9DD368C174F26A822359C643A77A4.rev'
public and secret key created and signed.

pub   ed25519/A822359C643A77A4 2020-03-19 [SCA] [expires: 2022-03-19]
    Key fingerprint = 1171 6FF6 72B9 DD36 8C17  4F26 A822 359C 643A 77A4
    Keygrip = 92F62A329D3CBBBE64BFA8DABC6F4348623AB256
uid                            Student Name <email.name@some-school.edu>

The ASCII version of the public key will be needed when setting up the repository.
This block will be copy-pasted to the repository within the user's account settings.

gypsy@spellweaver:~> gpg --armor --export A822359C643A77A4
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEXnMHZxYJKwYBBAHaRw8BAQdAjh6qOGnp5b0GTNZEHL4wIrIljwxLlxfU8/F5
l8TZVNC0KVN0dWRlbnQgTmFtZSA8ZW1haWwubmFtZUBzb21lLXNjaG9vbC5lZHU+
iJ0EExYKAEUWIQQRcW/2crndNowXTyaoIjWcZDp3pAUCXnMHZwIbIwUJA8JnAAsL
CQ0IDAcLCgMBBAYVCgkICwMFFgMBAgACHgECF4AACgkQqCI1nGQ6d6RXEAD/Rdhz
kh+gNvnO367JYqdoIwFiIsW4a2mq3d4nqNE6migBAM3m8cMO2Ww2u5+O7l8P4GuI
EMTlK2WWckAEJUGS1pMO
=6LSb
-----END PGP PUBLIC KEY BLOCK-----

The public key needs to be saved in SSH format.

gypsy@spellweaver:~> gpg --output id_ed25519.pub --export-ssh-key email.name@some-school.edu

The public key will be needed when setting up the repository on GitLab.
The last line is what will be copy-pasted in the settings of the repository for the SSH key.

gypsy@spellweaver:~> cat id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII4eqjhp6eW9BkzWRBy+MCKyJY8MS5cX1PPxeZfE2VTQ openpgp:0x643A77A4

the git program needs to be set to always gpg-sign commits and told which key to use

git config --global commit.gpgsign "true"
git config --global user.signingkey "A822359C643A77A4"

Use GitLab as the remote repository

Usually GitHub vs GitLab is more about personal preference than any project-based requirements. The granularity of permissions in GitLab is better than GitHub, allowing the instructor to grant access to the assignment repos on a per-user basis. GitLab allows for unlimited private repositories without having to create a paid account. Let's face it, as a rule educators don't have the spare funds to support enterprise level tooling. GitLabs give for free what GitHub will charge for. As it is student work, private repos seems more appropriate on two grounds. First, normally student assignments are not available to the general public. Even more so when dealing with under-age students. Second, by having private repos, with only the pair of students working on it being granted access, the ability to copy one team's work by another team is greatly reduced.

Three additional factors available from GitLab which might be useful are: 1) Discord Notifications, 2) their Continuous Integration (CI) pipeline, and 3) the ability to install a local, or self-hosted, GitLab for greater security. Depending on the language being use, the CI pipeline might help in keeping variations in build environments between student systems, or between their system and the instructor's system, from hiding or creating errors.

Tidbits and Notes

One possible downside to Discord is that it can also be used for video calls. That, however, is a something which is available through the "friends" section rather than in the "server" you would be responsible for, so it shouldn't count against you, or the application.

A bonus for Discord is that the odds are high that most of the students already have it installed, and know how to use it. They probably know how to use it better than the instructor would.

For the current crisis (COVID-19) Discord has increased the size of GoLive streams to 50. That shouldn't matter unless it's decided to us the GoLive feature for the instructor to do demonstrations, which is also a possibility.

If the students have an assigned email account from the school, it is probably a good idea to require that such email be the one associated with the GPG keys and the accounts on GitLab. Official required communications should be done by email using that address as well. Assignment instructions, due dates, grades, etc., rather in the untracked space of Discord.

To "invite" the students to the Discord server, create short-lived, single-use invites for each student, and send that in an email to them rather than a general invited for the class.

For most Linux systems, git is a simple install, directly from the default software repositories. For Windows it takes a bit more work. A guide, which seems to be pretty good, is How to install and use Git on Windows.

An advantage, and possible disadvantage of using the GoLive option is that each student can have their own version of the IDE, customized to their preferences. It's even possible they could use a different IDE than they would in class, and different from what their partner is using.

The potential problem with this is that they could become lost in the IDE and the instructor, having never used that one might not be able to help.

An unplanned benefit could be that new insights into student preferences, including IDE choices, can be obtained by noticing which IDE students gravitate towards, and how they use them. Once classroom instruction is able to resume, a change of IDE for in-class use might be in order.

The 24/7 availability of the tools can get the students into the habit of "calling" the instructor an anytime, without thinking that there are other things to do, or classes to work with. Setting a time for "class" where you will be available on the server for direct contact, perhaps during the same time-span as class was held when it could be held. To avoid the appearance of always being available it might be worth creating a different server for each class, keeping your "office hours" on each server in turn.


Best Practices / Effective Strategies For Building Diversity In High School CS Programs What works for building programs that are accessible to "non-traditional" CS students and which help to support the students so that they enjoy the class, start seeing themselves as "CS types," and ultimately succeed in the program and go on in CS?

References to concrete evidence and past attempts to do the same thing would be appreciated so this doesn't become all speculation and opinion.

Three concrete ideas come to mind based on my experience building a CS program essentially from scratch at the high school level:

Have at least one class that has no pre-requisite. We have one intro to programming course that any student can register for, including freshmen. Students don't need any background, any strength in math, any previous AP/Honors/accelerated classes. Part of the battle -- maybe the hardest part -- is getting bodies into the seats, and then winning them over from there. Eliminating hurdles as much as possible is one logical step to take.

Trust word of mouth. I made it my goal to get in front of every possible applicant when promoting our first year of offering AP CS Principles (2016-17). A year ago, I visited math classes and spoke to probably ~700-800 students before course registration. As a result, I received nearly 150 applications. In previous years we could barely muster one full section of AP CS A. If >20 students showed interest in CS, we were doing well. I believe firmly in the Field of Dreams philosophy: "If you build it, they will come." Even 5 minutes of enthusiasm was enough to spark a massive up-tick in interest. Last year, we had one small class of CS, this year we had three full classes, and we are expanding to four next year.

Don't let traditional grading get in the way of learning. I struggled a lot with this issue this year. I tell students bluntly that programming is hard. It can be frustrating and challenging. So, when it comes time to assessing programs, I let students revise, revise, revise. Essentially, I take a standards-based approach; I don't care so much when they learn something but that they learn it. A low grade at the beginning that is difficult to recover from can be more disheartening than anything else and can sap students of the motivation needed to persist through challenging programming work. At the start there has to be a reward for grit and the desire to improve.


Demonstrating the possible dangers of SQL injection Students building websites in a high-school computer science major (using HTML, javascript, jsp and MySQL) don't seem to understand the dangers of SQL injections. I try to explain that unchecked SQL statements can really ruin their databases, but just telling them doesn't get the message through.

The students build small websites as a project, and they work on that project for one semester (they do this during the 2nd semester. In the first one they are taught HTML, css, javascript, jsp and MySQL. Rather efficient, isn't it?).

The project guidelines specify they need login and registration pages, and a users database (among other requirements). After teaching how a login\sign up page might work I explain a bit about SQL injection. However, the students simply don't see the dangers SQL injection poses. I explain that I can cause the entire users table to be deleted just by signing in, but just saying it apparently isn't enough.

So, how can I demonstrate the dangers of SQL injection?

Note: This isn't a self-learning question (details can be found in the comments).

The best way to show your students that their work is vulnerable to SQL injection is to demonstrate it. I'd suggest that you challenge the students to "hack" each others projects using SQL injection. You could then give bonus points for the students who are able to find the most vulnerabilities and for the students who didn't leave that attack vector open.

That would be a fun way for students to learn by doing. This activity could also serve as an intro to what SQL injection is. Students could discover what SQL injection is themselves, and have a fun time doing it while also getting feedback on how their own code is weak.

You could then go on to discuss the broader consequences of SQL injection with the entire class and go into real life instances of SQL injection vulnerabilities.


Usefullness of Study Guide The notion of "Study Guide" was unknown to me before moving to the US (I don't think I was ever given one during my studies in France).

I believe that the goal of a study guide is three-fold:

To list all the topic that will be on the exam,
To provide some hints to the students as to how to revise,
To help them deal with their stress.

In the case where everything that was covered so far will potentially be on the exam, I feel like students shouldn't need one: they should be able to list all the topics by going through their notes (or through my detailed syllabus), they need to learn how to revise on their own (it is difficult to have a "general recipe" that works for everyone), and they need to learn how to deal with their stress on their own (I'm talking about college students).

Of course, during class, I gave them plenty of advises, examples, problems, partial feedback, and highlighted what the key ideas and critical topics are. They had multiple short tests (quizzes) and projects, and I went over them in class. I tried to help them assess how well they know the content of the course during class, and I am open to meeting them. I know that teaching is about repetition, but listing this information once more doesn't seem so useful to me.

Am I overlooking one aspect that make study guide really critical to students? What is your personal practice?

Goal-oriented action
Part of this really depends on your goals in administering the exam.  If your goal is the traditional idea of creating a nice bell-curve to rank students, having a study guide makes very little sense. You can separate the wheat from the chaff without providing any assistance to the students prior to the test.
However, if you want to utilize the tremendous cognitive benefits of testing to actively help your students learn, then you're looking at a whole different set of priorities.  There is a lot of research on the benefits of testing in the learning process.  Unfortunately, I don't have access to my bookshelf right now, but the incredible book How People Learn summarizes the results very nicely.1
How do tests help?
Basically, tests accomplish two things that really help us to learn.  First, there is retrieval practice, which is simply giving the brain a chance to practice holding on to (and recalling) information.  The second is emotional: by giving the information heightened emotional importance, we increase our chances of actually encoding it.
So, where does a study guide fit in?  Having a list of topics isn't as useful as you might think for an examination. If I tell you that you're going to have an examination on "Operating Systems", there's not a lot to go on.  You might get to the exam and find questions about threading, or disk management, or you might find questions about how to transfer photographs between an iPhone and a Linux box.  There's little to focus your studies, and you may find that you have expended a great deal of effort studying things that your teacher does not consider to be the core, central ideas of the course.
My example is over-the-top, but this is done purposefully to illustrate the problem.  Your subtopics may not seem as broad as "Operating Systems", but in a field of effectively infinite knowledge, you are presuming that students have gleaned what the important core ideas are for your class from readings and from listening to you during your lectures.  For some kids this will work.
But what about the kid who missed something?  Perhaps they didn't understand something really fundamental about one of the sub-topics.  Or perhaps they got sick and missed a class.  Or perhaps they've just forgotten some things thoroughly enough that they really can't recall what the important ideas were.
Creating a good guide
A study guide is your chance to give some very gentle guidance.  Take your syllabus, and write a sentence or two for each topic that starts with, "Make sure you understand ..." or "You should be able to ..." or "The most important idea here is ...".
This is a relatively easy task, but even this small amount of guidance will help your students to focus their studies on the most important ideas of your course.
You can actually go a lot further with this effort if you want to, and there are good reasons to consider putting a lot of effort into the guide.  Your efforts here can have an outsized impact on your students.  This is what they will study, so what you put here is what your students are likely to remember when they leave your classroom for good.

1 - All I could find online were a few articles about single studies here and there.  This is probably the best I can do for now.


Methods for engaging students when teaching unpopular or unfashionable topics The world is full of computing technologies that have been put to productive use but may be unpopular or unfashionable with students today due to their complexity, their lack of support, limited takeup within industry, or simply because they are perceived to be "old" or "out of date".

In many cases, it isn't an option to simply stop supplying educational materials that cover these topics due to the critical nature of the technology. In the case of COBOL, for example, it is often claimed that there are over 250 billion lines of the stuff out there and that the world needs engineers to maintain it. Such arguments seem to encourage engineers to be to adopt the technology for altruistic reasons - but does that approach really work?

In summary, what methods do educators use to engage students when teaching unpopular, yet important, computer science technologies?

There two important facts here:

  Complexity is in every programming language
  Popularity is due to a marketing monster talking on every opportunity (for example on the Youtube adds about what is trending
  and what not)

For the first point.

We need to translate programming teaching about new fields; for example in many cases teachers spend a lot of time talking about theory, origins and giving more importance to math exercises

For the second one We need to know more about other technologies, for example if an student asks to me, hey teacher why I do need to learn Java, existing Python or Ruby?

Things yo shouldn't do it

dear student Java is ugly but neccesary to get a job

Things you probably should do it

  Java is a complex language
  Java around the world is the key to get a job in a easy way
  (Showing proves) Java has the most high salaries
  I f you get fluent in Java is very secure you can move yourself to many other languages

Many times the key factor is "What I can do if I learn this technology"?

And the answer for this question is not easy for many IT Teachers, for example I know a lot of them whose only make simple math exercises about calculate pows, substracts and stuff like those.

As technology moves, Teacher needs to do in the same way; for example:

PROPOSALS

  We're going to learn Java, for building an app
  We.'re going to learn Java for building a chatbot using the Facebook API
  Maybe we're going to learn Java for building a Instagram clone
  We're going to use Java but combined with Angular for example for building an API

I mean programming languages are cool but is better what can we do if we understand them

At the end We as IT Teachers need to move, re learn and interpretate how this world is changing in every oportunnity

example

Fr this course I need to build an app with my students:

the good

apps are very popular
they are expecting discover something amazing
I choose to use Angular 6

the bad

They have not computer in many cases
They don't know how to use simple tasks: email, word .....

I choose Angular for building an PWA, is a good alternative, I will show them differences and similarities

Advantages

They will discover with me how to program
in spite of not use Java, We're going to understand how to build a product
Students will be free to choose the content of this PWA
PWA is part of some requisites for web development jobs

So I will be give them another option, itself they can change after if they have the ooportunity to learn Java or any other thing


What are the advantages and disadvantages of cumulative vs percentage grading? There are many ways to grade students. One is to provide a fixed body of student work and then give a percentage grade for assignments, with the overall grade representing the percentage achieved of some ideal. 90% = A, etc. The student is expected to work on each assignment. This is Grading by Percentages.

Another way (Grading by Points, Cumulative Grading) is to provide a body of assignments with a point total assigned to each part, preferably with small granularity but totaling, say 1000 points. The grading is done cumulatively with, say, 900 or more points required for an A grade. The instructor evaluates each assignment and gives points based on quality, etc. perhaps giving 40 points on an assignment that is "worth" 50. Here the student can work until they have enough points to achieve a grade that is acceptable to them. After that, they no longer need to do anything and can focus on other courses or commitments. It is, of course, good to warn students who are intending to go on that learning is still required to meet their greater goals and not to be too complacent.

In either case, the instructor may permit re-work on assignments. If Grading by Points the rework earns additional points, but perhaps not up to the full marks for the work, but some positive increment.

The writer used Grading by Points in the latter part of his career. What advantages and disadvantages are there of each scheme. What improvements can you make to either or both of these?

For clarity, the real difference is that in Cumulative Grading, the rubric tells the student how many points are needed for each grade and they can choose to get them any way that they like, spread over the assignments, whose totals are also known. In percentage grading, especially with different things worth different "weights" it is (a bit) harder for the student to know where they are likely to wind up. They know their "average" perhaps, but every assignment affects the average. Therefore with Cumulative Grading, the student always increases their points, where with percentage grading, each assignment can get you closer or farther away from your goal.

I have done both percentages and points in my career, the latter being the most recent and preferred.

Percentages:  The only advantage I can see is that, especially in high school, this seems to be the dominant way of grading, so students and teachers are accustomed to it.  Disadvantages are that students can have a difficult time tracking their progress, or knowing, for example, how well they must do on a test to keep their grade above a certain percentage.  In my experience, it also takes more time as a teacher - determining how many questions to put on a test or quiz so that percentages can be more easily calculated, for example.

As relates to programming specifically, I always struggled with the fact that I wanted programming exercises to count heavily but had a hard time making that happen with percentages.  Students, parents, and administrators expect tests to be worth more than anything else, so if I gave tests the normal 40% weight, then that left programming exercises, quizzes, and classwork (study guides or worksheets) to split the remaining 60%, and I could just never get it "right", meaning feeling comfortable with the distribution.

Points:  The major advantage of points the OP has already noted - students, parents, and teachers alike can instantly look at assignments and ascertain which assignments are worth more (I'm assuming all are using electronic gradebook of some kind), and students who want to remain at a minimum certain level find that easier to do.

Going to points solved the problem for me of knowing how much to weight each type of assignment - all assignments are weighted the same, and if I feel the assignment is worth more, I give it more points.  So I can look at how many programming exercises I assign in one semester (depending on the course, 80 to 100), determine points for those (say 10 points each), and base the points for everything else on that total.  If I determine a certain test is going to be worth 112 points because it has 56 questions, then the students see it as a large chunk, so they don't blow it off, but it is also not going to sink them if they fail it.

Rework: By extension, rework is made easier with a grading by points system.  I've also found that "extra credit" makes much more sense for students in the points system, and they are more motivated to attempt it, because they can more readily see how the extra points are going to impact their grade.


Justification for an objects-early approach to introductory programming I'm familiar with two schools of thinking for approaching an introductory level class in an object oriented language: objects-late, and objects-early.  In objects-late, you teach various procedural aspects (variables, loops, boolean manipulations, etc) before you delve into objects at all, and then use objects as a way to organize larger chunks of code.
In objects-early, you begin with the object-oriented paradigm, and then delve into method construction, and finally into the procedural aspects of coding that way.
I truly don't understand this second approach or its merits.  What are potential benefits of beginning with objects, and how can you structure the early parts of a course in order to even permit this?
Important note
I know that Buffy's answer (the one that I accepted) is quite long, but it is also one of the most comprehensive and insightful things I have ever read on StackExchange.  If you are interested in this question, his answer, while long, is worth the time to read and absorb. Sometimes, life brings us unexpectedly beautiful things, and the best we can do is appreciate them and be grateful.

tl;dr: When you teach with the OO paradigm, you get to control the flow of ideas and the level of complexity at any moment.
Here we examine the first course in computing, no matter the educational level. Presumably this is for a formal course, though it can be adapted to self-study. Presumably the students have mixed ability and backgrounds, neither all superstars nor laggers.
In my view, the purpose of the first course is to teach students how to program. It is not to teach them a particular language, and not to teach them the esoterica of that language. How you proceed in practice depends on your own background (the teacher or learner) and on the language you choose. Actually the dependency is not on the language itself, but on the paradigm that the chosen language embodies.
In order to learn how to program, you must first have a concept of the nature of a program within a paradigm. But we are burdened by our history: the history of programming languages and the history of how the instructor learned how to program. So we first consider the question What Is A Program. The answer depends on the paradigm. Leaving out assembly language, in which the program is a sequence of simple statements and branches, we have several possibilities.
Fundamental Nature of Procedural Programming
Languages like C and Pascal were designed in an era in which it was discovered that go-to (branch) programming led naturally to unreadable and unmaintainable programs. Dijkstra, Hoare, and others came to the realization that Structured Programming was superior and sufficient. In Structured Programming the fundamental program structures are sequences of statements, selection of alternatives, and repetition. These can be represented explicitly in languages without reference to branching. They can be explained as branching, but it is not essential to think of them in that way. Combining this concept with the idea of (procedural) abstraction (naming coherent parts of a program and invoking them by name) produces the following way to think about the nature of a program:
Envision a problem, for which you do not yet have a solution, as a set of sub-problems. If they all had solutions a known synthesis would let you combine them into a solution of the whole. Note the two requirements: (1) the set of sub problems must be complete and cover the whole, and (2) a synthesis of solutions is known that would combine them into a solution of the whole. The sub problems themselves may have no known solution, but they must be solvable.
For each sub problem does not have a known solution, recursively decompose it just as above. A solution should be a simple program (procedure) that satisfies all of the requirements of that (sub) problem. If you cannot provide the solution, then recurse until you can solve all of the smaller problems.
Once you have solutions to all the small problems build up a solution to the whole from the lower level syntheses, which were known, and which drove the decomposition in the first place.
Thus the nature of a program is a tree of solutions, with each leaf a (hopefully) simple procedure/function. Each procedure/function solves some part of the original problem. The larger problem is now envisioned as a tree of problems and associated sub problems.
If you teach in C or a similar procedural language in the first course then the most important task is to give students practice with this process. Never mind all of the intricacies of int values and mutation, and pointers, etc. They must learn to understand the nature of a program. Everything else is in fulfillment of this goal. If they learn that, but not the whole language, they can fill in those details later, or on their own. Without that structure they will write terrible programs with long and unwieldy structure, and impossible-to-decipher functions.
Fundamental Nature of Functional Programming
The first Functional Language was Lisp (List Processing). It was developed based on Church's ideas on the Lambda Calculus. Functional languages are provably as powerful as those based on Turing Machines - a famous result. Lisp was originally thought to be inefficient since it incorporated an inefficient garbage collector, and that unfortunate judgment has stuck, though modern functional programs can be as efficient (or even more so) as those of other paradigms. Lisp has many modern successors, especially Scheme and Clojure. While Lisp traditionally uses only an abstract syntax (parenthesized lists), other successors have a concrete syntax that appeals to many (including this author). Languages like Standard ML and Haskell fit in that category.
A functional program is best thought of as an expression, which, if evaluated, produces a value. Since functional languages tend to be incredibly regular, the "value" returned by evaluating an expression might, itself, be another expression. I will used Scheme to explain ideas as we continue. In functional languages with syntax, things will look different, but reduce to the same ideas.
In Scheme, a program and its data are represented by lists: (a b c d). If the list is evaluated it is a program in which the first element is a function (expression) and the rest are the arguments (also expressions) to that function. However, the list need not be evaluated, in which case you can think of it as data (or as an expression to be evaluated later).
Different functional languages differ in when the arguments to a function are evaluated. Originally they were evaluated eagerly, before the function itself is invoked. However, it is also possible to design a language so that evaluation of expressions is delayed until they are actually used. Each has advantages and disadvantages, so functional languages usually compromise (using special forms and macros) so that some expressions use their own distinct rules.
Another feature of an expression only language is that you do not have side effects, only values. Output to a printer and graphics construction are not functional concepts, so special forms can again come to the rescue to provide the possibility of side effects, though most programs work to minimize and localize them.
A pure functional language (or the pure core of a more complete language) will be without special forms and side-effects. In a pure functional program the programmer constructs an expression which will produce the required solution to the problem if evaluated. Smaller scale problems are represented as the arguments to that initial expression and they can also be (recursively) arbitrarily complex expressions themselves. Evaluation of the original (top level) expression implies that the arguments are also evaluated in some order dependent on the language.
Since people do not like to write arbitrarily complex expressions, it is also possible to name expressions (abstraction) and invoke them by name. These names are usually called variables but normally they do not (cannot) actually vary. Once a name is bound to an expression (creating a variable) that variable cannot be bound to another, though the name can be reused - a confusing distinction, of course, until you understand scope. Data in most functional programming languages is immutable. One constructs new lists from old, rather than modifying a given list.
So, beginning functional programmers need to understand the expression, subexpression concept and practice it. They also need to learn at least a few special forms and how they behave differently though they actually look the same. For example, an if-then-else selection structure is normally a special form since eager evaluation of the "then" and "else" expressions is usually not desirable (especially if either has side-effects). As their experience with the language grows they need to learn more about the special forms and their individual rules.
There is an additional task for the beginning functional programmer. Normally repetitions (while, for) are not used in functional languages. They are replaced by recursion, especially tail-recursion. So the beginning programmers need to learn how to pose complex problems recursively with a special focus on tail-recursion. This results in some beautiful idioms that can be mind-blowing when first encountered. For example, reversing a list in Scheme can be done in linear time if you know how, but a naive program will likely be quadratic. The programmers do not need to learn more of the language to do this - there is very little "language" to learn - but must learn more of how to use the language, often by thinking recursively in powerful ways.
Fundamental Nature of Object-Oriented Programming
The first object-oriented language (OO) was Simula, which was developed to facilitate the creation of complex simulations, say of industrial equipment or governmental systems. This may be a key to how to teach the paradigm to novices. See this answer to a different question, for example. C++ was conceptually based on Simula. The next OO language was Smalltalk and most object-oriented languages derive from it. The most direct successor to Smalltalk is Squeak, which is a beautiful choice for teaching, but seldom used outside a small circle.
Imagine a problem that you can conceive of as being solvable by some set of things, each of which has the ability to act on request and to return some information based on those actions. Think of how you would design those things. Each of the things itself has a problem, its piece of the original, and that smaller problem is solvable by additional things with the same sort of capabilities. The things are heterogeneous (many kinds), some simple and some complex. Simple objects can be coded in a language, but complex ones need to be further decomposed.
An object-oriented program is envisioned as a web of objects (things), perhaps just one, that cooperate in the solution of a problem. An object itself is a bundle of behavior that provides services normally for other objects. The web arises from the fact that any object can hold a reference to other objects with which it can communicate - eliciting behavior. Each object takes responsibility for some part of the solution. An object is a value that can be queried for information to solve its own piece. Additionally, it can be directed to act in creation of the final result. Communication with an object is called a message. Both the queries and the actions often (usually) cause additional messages to be sent to other objects, which aid it in fulfillment of the query or action.
Additionally, and this is the important point, objects are themselves constructed, mainly out of other objects (recursively): their parts. They communicate with their parts in the same way (messages) that they would communicate with an "external" object. Thus, the structure of an OO program is a web/graph of communicating objects that are themselves (recursively) webs of objects at a lower level. The execution of such a program is a flow of messages that cause actions and return results from queries.
To create such a program, from scratch, you define one or more objects (using classes in Java or prototypes in JavaScript, etc.) and send a message to an object to start the computation.
OO languages have many features, usually including inheritance, which is often thought to be the biggest idea in the paradigm. In fact, it is not. The big idea is that OO enables the programmer to consistently build complex objects out of simpler parts by composition, keeping the parts essentially invisible to the clients of the object (encapsulation). Variables, other than references at the top level, are used to refer to the parts of an object so that it can maintain a consistent internal state and provide the public services.
In effect, an object provides an abstraction layer, above that of the language itself, in which the programmers building the system can think and extend, without reference to lower-level constructs, even those of the base language itself. Thus a set of objects provides a world that is self-consistent and complete enough to solve the question at hand. Once such a world exists, even novices can program within its framework and can think at that new virtual level. Thus, once a world with, say wombats, food, predators, etc has been provided, perhaps by the instructor, students can extend it, and can solve complex problems within it by creating objects and their web of interactions.
A beautiful OO program is one in which the objects themselves are simple, with simple methods. The complexity is not in the objects themselves, but in the interactions. When I am writing an OO program, I start to get "itchy" when any method has more than about three statements. Any structure nesting (if, while, ..) beyond two is cause for concern. McCabe's cyclomatic complexity metric should give you really small numbers. An implication, of course, is that there are lots of objects, and often, lots of classes. Fortunately, modern IDEs make these easy to create and manage.
Teaching the first course
You can teach the first course in just about any language and within its associated paradigm. If, however, you confuse your students about the nature of a program in that language you have failed.
The students should also write beautiful programs that their mothers would be proud of. The techniques you teach them should scale to larger programs than what they write in the first course. It should never be necessary for any student to unlearn bad habits and bad practices. If they can only program by writing two-page functions/methods filled with deeply nested selection and looping structures they are failing. The parts they build in whatever language/paradigm need to be small and understandable.
Consequences for teaching the first course (focus on OO)
If you need to teach a course and intend to do so without any preparation, the procedural paradigm is likely the easiest for you. You need a suitable language, a compiler, and an editor. The language provides the "stuff" of programming in its few data types and program structures. To be a success here, giving students the essential idea of procedural programming, you will need to find interesting problems. This is difficult since your tools are so primitive. You will also need to guide them into the problem decomposition and program composition to build up the two trees (problem - solution). They often tend to do too much in a given function. Make them factor out every difficult bit and apply intention revealing names to the parts factored. Require then to use short functions, limited nesting of program structures, etc.
If you want to teach OO programming, on the other hand you need to prepare before the students begin. You need to have in hand one or more virtual worlds found, or constructed by yourself, in which they can do interesting things. Making it interesting is easier, since the structure of the world is up to you. Students programming in one of your worlds can start out with nothing more than sequences of messages to one or more objects to get some desired effect. If your world is graphical, all the better, since the students can see the effect of their program, and hopefully where they go wrong when they do.
Next, in the OO world, students can extend one of your (say class) structures to add some additional behavior. They can do this by inheritance if the language permits or not. I would strongly suggest that you not overemphasize inheritance. Certainly avoid deep inheritance hierarchies. Ignore the concept of "reuse" and instead just extend the made-to-order world with interesting behaviors and/or objects. Since you have built the virtual world, you can control the order in which ideas are presented to the students and can control the complexity of what they must deal with at any moment. You can introduce deep concepts in a simple way in order to achieve some local small/scale effect as well. Not every program needs to be math-like as you have richer things than integers, etc.
If you want to teach them OO programming, do not think that you first have to teach them procedural programming. Some of the ideas of procedural programming naturally occur in writing methods of OO programs, only in a smaller scale. It is easier to move from OO to procedural than the other way, actually, since the methods written are a lot like the procedures/functions of the procedural paradigm. It is also not quite as likely that the students will write monster methods, though you need to guard against the SEE-ALL-DO-ALL class, just as you need to guard against the ONE-TRUE-FUNCTION in procedural programming.
The beauty of the OO paradigm for teaching is this. While any language defines a virtual layer in which to program, the objectives of the language designer were not pedagogical. When you define a higher level virtual world atop the language level, you, in fact can use pedagogical principles to construct it and provide a world in which the key concepts are easier to learn. If that world is also Turing Complete, all the better, but it is not essential - especially if you intend to use several smaller worlds rather than a single framework.

Note that a few additional paradigms have been omitted here - concurrent programming, in particular.
A paradigm is a way of thinking. Adopting a new paradigm may require a radical change in how the students think. This is much like the change in warfare from aristocratic knights on horseback to a peasant army of longbow archers that was first recognized at Agincourt in 1415. However the change did not become complete for about 100 years, Henry V to Henry VIII. After Henry VIII, English kings were no longer trained as knights.
Paradigms are by nature distinct. They are not ordered. A longbow-man did not need to have any of the knight's training to be successful. The computing paradigms are also distinct and self-consistent, not ordered. It is not necessary to learn one before any other. Nor is it necessary to mix them. In fact, the second paradigm learned is always difficult, as you already know how to do things, so the new structures seem superfluous to you. That is not a reason for not learning several, but it needs to be kept in mind to help explain the difficulties. The first course, however should be pretty pure to avoid confusing students.

It is a fundamental principle of modern computer languages that they define an internally consistent, Turing complete, view of programming that needs no appeal to lower level constructs to be understood. While it is true that such languages are in fact compiled to lower level constructs it is inherent in the concept that understanding does not flow from compilation, but the other way about. In fact, most of us (non-compiler-builders) would have a hard time understanding the intricacies of what really goes on in an optimizing compiler. The basics are easy to get, and the details are very complex. If you had to understand all of that to write a C program you would never know where to begin. You make assumptions, but they may be wildly wrong in light of modern systems with multi-level cache, co-processors, etc. That understanding is not needed if the language itself is complete and consistent.
Many languages are designed around a particular paradigm, sometimes just due to the time of creation. C is procedural. Java is Object-Oriented. Haskell is Functional. Some, however are multi-paradigm; C++, for example, is neither duck, nor dog.


How should I handle over-demanding assignment providers? Due to the coronavirus crisis, internships became hard to come by, due to companies not being able to house any students. So local colleges/companies made an arrangement in which one company would set up a organization (where I am part of) that pools projects from several companies and redistributes them to the students who work in a location provided by the schools.
Now the company that is doing the redistribution is actually getting paid for the assignments the students are doing and have strict deadlines. And we are nearing the final weeks of the first round of this system and he has become rather critical of the outcome of the projects.
He thinks the projects could have been done better, comparing the results of the students (the youngest student is 17, and the eldest is 24 with the majority being between 18/20. Who just completed their first year (just below bachelor level) which was poked full with holes due to coronavirus) with professionally-made similar sites from major companies (that most likely had more time, resources and knowledge going in).
I argued that when doing the projects we should keep the educational level of the student in mind, and can't expect high end stuff from them seeing they just got started (especially seeing that on paper they don't have any time to learn, but have to be "productive"). I have tried teaching them, but there are several wildly different projects and in the limited time I got with them I am not able to go by every project to give a proper in-depth course on how to best do it.
How could I convince my employer to ease up on the students, because in my opinion it was unwise to take on paid projects when you only got a bunch of first year college students to it in a rather limited time? And how could I advise him to simply say not take on so much work or such high demanding work when he knows that the skill level and time frame of the "employees" are so limited (because the next group is scheduled to start in February).
Background:
My employer has a small IT company, and the students are sort of his interns. My current job (three days a week at least) is to manage the students (although I have contact with the school/teachers, I am on the commercial side of the story). My job includes giving them their projects, and guide, advise, and supply them. But due to the coronavirus crisis they missed a lot of classes, so I spend most of my time (especially in the first weeks) tutoring them than anything else.

We run projects with real-world clients from within our school building.
I would add to Buffy's beautiful answer one idea that we've communicated to the clients that our students will be working with:

As gifted and wonderful as our students are, recognize that they are still students, and the primary purpose here is educational.  The work that your group does should not be mission-critical.  An ideal project is in the nice-to-have category.
If you have discussed doing something more significant with your group, and they understand the challenges and are willing to undertake the project, then we will not stand in the way.  Such projects can be valuable learning experiences!  While we do provide support and oversight to the project groups, our ultimate target is learning.  Please be prepared to provide extra support as needed if you are relying on the outcome.

I think this nicely captures an important aspect of internship projects.  They can be useful.  Heck, ideally, they should be useful.  That's part of what makes a good internship so motivating!  But students are still developing their skills, and the results can be uneven.  I wouldn't rely on it for mission-critical pieces of my work.


What "process instruction" should instructors give students when assigning a team project? Team projects seem to run in to difficulties fairly often. One complaint is that some member doesn't actually do anything, causing dissension or the failure of the project altogether.

Too often, left to their own devices, teams simply "divide up the work", ignoring that separate threads need to be integrated and that this can be the major part of the effort.

My joke example is five people writing a 5000 line program with one person writing the first thousand lines, the next person writes the next thousand, etc. All in parallel. But imagine also a team project in which a Limerick is to be written with each member writing one line, all in parallel.

The opposite effect is when one student simply does everything, ignoring everyone else on the team. And often, then, complains that they got no help.

How much prior instruction about team process is required before such assignments are given? More important, what should that instruction include? It might also be useful to comment on how much the evaluation should correspond to the process and not just the product produced.

There are a number of smaller issues within this question, of course, such as what does it mean to "contribute equally". How can we convey good team practice in light of such issues?

Before you assign students their first team project some instruction is needed. You can't assume that they will understand teamwork any more than that they will understand recursion without instruction.

But first, you should decide on how you want their teams to behave. In this answer, I'll consider only a team structure that requires a team leader who will assign tasks and be responsible for the overall project, including the integration of the pieces done by the various team mates. This is only one of many possible team structures but here I'll stick to just this.

If this is the team structure you assume will be used, don't assume that it will just happen and coalesce without your efforts at the start and throughout. Among other things they are too likely to spend far too much time at the start on organization, leaving too little for the actual work.

The first consideration is to decide on both the teams and on how the leader is to be chosen. You can force it a bit by choosing the leaders yourself, assuming that the scale of things permits it and you know something about the students. One way that I had success with in such a situation is to use a round-robin sandlot baseball method. I would choose the leaders/captains and the captains would alternately choose team members until everyone was chosen. This assumes that the students know one another generally.

Teams can choose their own leaders, also, perhaps via an election. But make sure that the choice is made immediately and that you learn who the leaders are.

Alternatively you can choose the teams yourself, either randomly or using some knowledge you have of their abilities. It is probably a mistake to let teams just coalesce into groups of friends as things are likely to be too lopsided in many ways. You want the better students distributed around the teams as well as the strugglers.

This structure is asymmetric, with a few students, the captains, having a special role. Let them know that "equal participation" isn't the same thing as saying everyone does the same thing. People can contribute differently to a successful programming project, with some doing most of the programming, others writing user manuals, others doing research or testing. But they will need some instruction on the kinds of roles and the leaders will need some instruction about how to assign roles (or take volunteers) for the various tasks.

Let the leaders know that their job is primarily coordination and communication (with you). Encourage them to have frequent meetings with their teams, and constant feedback if there are any problems. Let the leaders know that flexibility is needed and that some members who take on a task will need help in completing it. Make sure that the leader make allowance for such things.

One way to communicate all of this to a team is to give them a few descriptions of projects that succeeded and a few that failed, with an explanation of why. Horror stories to help them avoid the most common pitfalls. And one of the big pitfalls is not having adequate time for integration of individual efforts. It isn't going to all fall together in the last few hours. Emphasize that.

And, since the team members will play different roles in the project, give them a "role book" that describes how to carry out one's own role and interact with others. But everyone should know not only their own role but that of others as well.

One of the big lessons that some of them, at least, won't have understood, is that it is a learning experience, not product development. Students can learn even if a project doesn't really build much. Put the emphasis on learning, not getting over a finish line on an arbitrary (and possibly too short) time scale.

Another thing to communicate to the captains is that if trouble arises you need to learn of it immediately. Perhaps the project needs refocusing or rescaling. Perhaps the captain will need help in dealing with a non-participant. And if you have frequent meetings with the captains (perhaps in a group) you can feed them "management" hints for the teams.

One way to have meaningful meetings with the captains is to do it with the entire class present. You and the captains discuss issues while the others listen and take notes. These can be quite short meetings if the scale is small enough, say five or so teams.

Part of the instruction of the teams, perhaps through the leaders, is to encourage team members to help one another whenever needed. A team project isn't just the sum of a bunch of individual projects thrown together.

If you intend to use peer evaluation at the end of the project, make sure that they understand that at the start. In fact, it is best to give them details, such as what precise form it will take. My own preference is to have people say positive things about the most productive members rather than to rate or grade everyone. I also require a self evaluation along with any peer evaluation: "What was your chief contribution?".

Note that this style of project is not my favorite, but it is for many.


How to effectively teach strings and string literal constants? I am teaching a general introductory CS course to 18-19 year olds, with Python3 as a support language, and I am not satisfied with how some students respond to strings and string literals. That is some of them struggle to understand when you should use quotes and when not.

For example, when trying to open a file, they will write open(/the/path/to/the/file) instead of open("/the/path/to/the/file") and fail to correct themselves. This is just an example ; the question is not about file/filename confusion.

Conversely, some students, when asked to write a function a parameter of which is a string, will write

def example("s") :
   #etc

There seem to be an underlying poor understanding of what a variable (or identifier) is. However these students are generally coping with programs that do not manipulate strings.

A related question (maybe I should post this one separately) is about the pros and cons of introducing strings before arrays/lists or the converse.

Some background

This takes place in France, in the CPGE (Classes préparatoires aux Grandes Écoles), a two-year curriculum that students may enroll in at the beginning of higher education (post-baccalauréat or post-A level or equivalent) but is physically located in high schools (lycées) and prepare students for national competitive exams (concours).

As a result, the global content of the course is mandated nationwide (including the use of Python3 as an example language) ; I can only choose the order and the manner in which I teach things. The course is mandatory for students but is not the main field of the curriculum (I have 1hr/week of blackboard course and 1hr/week lab session, compared to 10 to 12 hr/week of math and 8 to 10 hr/week of physics).

Computer science is not taught in France before university/higher education. There is only some algorithmics, taught by math teachers as well as they can, using pseudo-language and calculators languages, and not dealing with any data structure (only numbers) and no functions. So I start from zero.

Even in CPGE, the idea of teaching CS as a field in itself is quite new and not universally accepted. As a result, the nationwide CS curriculum for CPGE mandates that problems and examples should be taken from math and physics situations, which leads to string being scarcely used except for file names and data input from files (csv). Yet any concours may ask a problem about strings, since they are mentioned in the nationwide curriculum.

Perhaps the place to start is with a discussion of variables and making the distinction between a "thing" and a "name for the thing."

A pretty good place to start that conversation is with the a poem from Through The Looking Glass, the sequel to Lewis Carroll's Alice in Wonderland.

The song's name is called Haddocks' Eyes
The song's name is The Aged Aged Man
The song is called Ways and Means
The song is A-sitting on a Gate

See wikipedia for a discussion and background as well as the poem itself.

In programming we don't normally use the first of these four distinctions, but the others are important. The second is how we think of a variable - a name for a thing. The fourth is the thing itself. The third can be an alias or alternate name for the thing, though that analogy isn't perfect.

But once the distinction between the name and the thing is made, you have a better chance of winning. But you still need to be clear.

"foo" is a thing (a String thing)
s = "foo" establishes s as a name for that thing.

"s" is a different (String) thing.

But "/the/path/to/the/file" is simultaneously a thing (String) but also a complicated name for another thing (a File). The open method needs a name for the file to be opened.

Note that much of the above was copied from an essay I wrote in meta.


How can I improve other programming languages while having command on one language As in computer science field we have to learn several programming languages like C++, Java, C#, python, php etc to complete our tasks and home assignments. However you are good in only one language. As I know all languages are related to each other at some extent, but it's difficult for me to remember syntax for all languages and doing different tasks for these to become familiar to these.

How can I improve and learn other languages easily so that I can perform my assignments easily and in less time?
If anyone can guide me.
Thanks in advance

Looking at Buffy's answer it's clear to me that I've understood the question quite differently, so I will set some context before I get to the point.

  However you are good in only one language.

I think that this is too strong: it's possible to be good in several languages if you use them all frequently. However, I do know the feeling. The main language used in my undergrad course was Java, and that was virtually the only language I used in the 7.5 years after graduating. But for the past 9 years the primary language in most of the projects I've worked on has been C#. Now when I revisit Java I keep typing string and getting compile-time errors until I correct it to String.

On the other hand, the key word there is primary. One project was written in C# but used a code generation tool whose templates were in some weird Visual BASIC variant for which I never found documentation, and in addition had large and complex SQL stored procedures. Real world projects often contain an unholy mess of different languages, chosen for good or bad reasons, and the ability to handle that is a useful skill to develop.

  As I know all languages are related to each other at some extent, but it's difficult for me to remember syntax for all languages

Supplement your memory. Write revision notes as though you were preparing for an exam on the differences between the language: one side of paper (A4 or letter) where you list the most important mappings from your strongest language to the target language. E.g. if your strongest language is Java then your notes for C# might include:

import is using
Method names begin with upper case
Map is IDictionary and HashMap is Dictionary
Generic types are reified, so if you have a static field Foo in a class Bar<T> then Bar<string>.Foo is a different field to Bar<int>.Foo.

Also, use IDEs where possible. It's much quicker to fix compile-time errors as soon as you type them than to wait until you've finished a unit and can attempt to compile. Auto-completion for syntax is also getting quite advanced now.