1) Version control all assignments. I force them to make periodic commits throughout the week. If they want to copy a project wholesale, they have to do so in a way that takes a lot of time and effort.
2) Comparing bytecode. If they change the names of variables, comments, spacing, etc. these superficial differences will be lost in compilation.
3) Oral explanations. Now that everyone has guaranteed access to screen recording software, I force my students to record an explanation of their work. They go through their code line by line and explain it to me. I can tell very quickly when a student is explaining code they haven't written. If they are explaining code they haven't written to a satisfactory degree, then they've at least demonstrated they've learned something.
4) Remove incentives to cheat. Give them all the resources they need and more than enough time. Provide easily accessible venues like chatrooms and forums where they can ask questions anonymously. Provide opportunities to improve prior poor grades so they feel like failure is okay.
This doesn't eliminate cheating 100%, but from my experience it does seem to cause cheaters to fail, as their cheating does not pass for acceptable work. The students who earn an A come to see me during office hours and I know they are doing the work. I would say very rarely does someone earn an A who is not on my radar as being an obvious high-performing student. If a student is cheating and earning an F or D, I can't say I care much about that.
Notice none of these methods involve an invasive surveillance regime. I don't require cameras on at all time, 360 degree views of work areas to prove no one is helping, software to monitor tabs and processes... all this is completely futile. The students hate it and it incentivizes them to find ways to thwart it. They feel justified in doing so. I saw one post that advocated running a high speed fan to drown out typing noises, wearing reflective glasses in a dark room to foil eye tracking software, putting Vaseline on the camera... all to what end? To cheat on a psych exam? It's an arms race that's not worth fighting. The solution here is to adapt teaching methods with new technologies and testing methods.
Not everyone does projects over time, not everyone commits all the time. I don't like committing in progress work and I usually do work in big chunks with large breaks in between, especially for solo projects where I don't have to share code regularly with others.
Based on your criteria, I'd likely be considered a "possible cheater" just for having a different style.
Regardless though, my students usually are at a point where they don't have a commit style. They come to my class with no knowledge of git or version control -- I have to teach it to them.
Secondly, labeling you a possible cheater doesn't condemn you to anything, it just puts you on a shortlist of assignments to examine more closely.
Thirdly, this style of committing has helped more than a few students out when their computers die mid assignment and they need to move to another computer. It also allow me to help them with their assignments. When they come to me for questions, the first thing I ask is "have you pushed everything to your repo?" Instead of trying to debug over a virtual desktop connection, I can run their code locally and get to the cause much quicker in my own environment. It really works out well for everyone involved.
Question: if (when) a student hands in an assignment without the periodic commits, what happens? How do you measure & set expectations for sufficient frequency of commits? (i.e., 1 single commit is too few, I assume that once a day is enough, but where's the threshold?)
Thanks again for sharing - I'll be thinking about these for my own classes!
In terms of getting them to follow the commit guidelines, I give them a carrot and a stick. The carrot is, if they start N number of questions half way to the due date, they can get a penalty-free extension if they need more time to complete the assignment. This is to incentivize students to start early. I've found one of the biggest indicators of successful students is that they start assignments early. Students who start their assignment on the due date usually run into blocking issues (software not configured properly, computer not working right, network is down) that would be trivially overcome if they had started a day or two earlier. Students who have this habit quickly correct within an assignment or two.
The stick is by the midterm, I start requiring it more strictly by subtracting points for not following the guidelines. I think of it like a math assignment; if all you provide on a math exam is the solution, you'll get little to no credit for that. Showing your process is part of the work in math, and I treat it the same way in my classes.
Every semester, students fell into the same buckets. - Those I rarely saw who nailed everything (and were getting an A or a high B because they understood the material), - Those I saw constantly who were going to get an A or a B (because they sometimes didn't understand things from class, or when they did, wanted to make sure; or for a few, understood it all, but knew the importance of showing they cared about the material to the professor and TAs) - Those I saw constantly who were going to get a C or a B (they rarely understood from class, but were willing to put in the work to try to) - Those I never saw who were going to fail (they didn't show up to anything).
It was pretty much invariably this latter group that got caught cheating. That's not to say the other groups didn't, but they at least got working code, did really well on the exams (pre-COVID, proctored in person), and in conversation were able to show they understood, so I'm a lot less concerned about them.
I think it could possibly scale to larger classes as long as the grading team scales with it. I'm not sure how public universities handle their grader allocations.