31
$\begingroup$

There are some students who are very good at coding. They can crack any logic problem at their level. But they aren't very good at CS theory. They can code better than their classmates, but they're indifferent about the theory, displaying an attitude of "I don't care".

In this case, theory means there are various theory papers are presented in the syllabus such as "Theory of Computation" which talks about NFA, DFA, Turing machines, etc. Another example is Artificial Intelligence, which talks about ES, Fuzzy logic, etc.

How can I handle such students?

They are at a 17-19 age group.

$\endgroup$
  • 2
    $\begingroup$ Are you sure they're between 17 and 19? In our college(VNIT), those courses are taught at the UG level to third year CS students, which means the students learning those are between 20 and 22. $\endgroup$ – cst1992 Jun 25 '17 at 3:55
  • 2
    $\begingroup$ What is the educational context of this? $\endgroup$ – Thorbjørn Ravn Andersen Jun 26 '17 at 13:05
  • 1
    $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$ – thesecretmaster Aug 29 '17 at 11:12

11 Answers 11

19
$\begingroup$

I suggest 2 possibilities:

  1. Talk to them. Explain that at some point, they won't be able to rely on just being able to code well. For AI theory, at some point the algorithms are dependent on so many parameters, making it impossible to write working code without knowing what each parameter does. (A simple example for this is neural networks. The simple ones have ~5 or more parameters which need to be fine tuned). If they know the theory, then they'll be able to write good code much faster, with fewer bugs and mistakes.
  2. Throw them in the water. If the other approach doesn't work then you can just give them an assignment, an assignment to show them that they simply can't go too far without learning the theory. I personally like examples from machine learning theories (Also, it's one of the fields I'm more familiar with). If you ask them to write a genetic algorithm, they'd quickly find out that they need to learn the various methods in the field. They'll be lost without learning those. The same is true for anything in the field of Deep Learning. If you give them such an assignment, and let them work on it for a while, they might produce results that are not too bad. However, if they were to read and learn the theory, they would produce far better results. As pointed out, it's important to give them an assignment that is authentic, and preferably something that is used in "real life" (like advanced search algorithms, which require heuristic functions, which in turn require1 knowing some theories)

The main idea is stressing the necessity of knowing the theory, and making it clear that as the project becomes more complicated (and as the project they make are at higher levels), the need to know the theory grows exponentially.

Another nice example is heuristic functions. Most students find these very difficult to learn and use, without in-depth learning of the theory behind it.

PS: I used to be a student like the ones you described, and I went through 1 (self-reflection-ish) and 2 and I fully understood that theory is necessary.


1Well, maybe not require, but sure makes it easier and faster to write and debug.

$\endgroup$
  • 6
    $\begingroup$ #2 definitely. I'm a practical coder and will only learn theory once I've given it a stab myself and failed. I also remember it better because I understand why my method failed and theirs worked. $\endgroup$ – user1331 Jun 25 '17 at 7:57
  • 10
    $\begingroup$ #2. Tasking them to "code" a tiny (programming language) tokenizer/parser or an evaluator for expressions encoded in strings ("-1+2/3") is a nice problem with quite simple solution when knowing the tools of the trade (a.k.a "theory")... but excruciating and bug-prone when skipping it. "There's nothing more practical than a good theory" ;) $\endgroup$ – jvb Jun 25 '17 at 8:13
  • 1
    $\begingroup$ Depending on their level of skill, other good exercises might be Tower of Hanoi, playing a game (nim, tic-tac-toe, checkers, wumpus world...), solving/pathfinding through a maze, a (basic) regular expression evaluator, verifying a CFG, and perhaps as a "fun challenge" write some code that detects infinite loops (first to complete the assignment gets a prize!). $\endgroup$ – Ethan Jun 26 '17 at 19:15
13
$\begingroup$

It sounds like these students may be perfectly suited to a wide range of roles in a professional environment, just not the most glamorous or 'obvious' jobs. Ultimately, everyone finds their level and a good team often has a mix. Given that these students are close enough to employment they should already have started thinking about what sort of jobs they are expecting to be looking for.

They need to decide if the theoretical stuff is something they need to be able to handle (and get a good mark in the course), or if they need to start widening their skills elsewhere, or focusing on something more narrow.

Obvious as it seems, you need to explain to them (and their peers) that in 5 years time, the state of the art will have moved on. More coding tasks will be automated, and new fields will be emerging. Not all of them will be architecting the next big thing, but they might be working on a part of it, or testing it, or rolling it out, selling it or supporting it. Theory will help in all of these areas, so they shouldn't write it off as irrelevant.

To expand on how this is different from say maths as a subject at the same level, most of the maths being learnt at that level is (a) likely to have a practical application for many careers (as complimentary knowledge most of the time) and (b) form useful practice in the art. Maths (even at engineering degree level) remains a completely practical subject, whereas CS has a slightly tricky mix - consider the paths to degrees in theoretical physics and practical (discrete component) electronic engineering.

$\endgroup$
12
$\begingroup$

Just like any field, the theoretical aspects of it can be inaccessible and a bit dry, I would say especially to kids this age. AI, automata, and computational theory are often college masters level courses, indicating that not only do you need some years of background in the mechanics in order to appreciate the theory, but you just need to be older and more mature. I didn't get into AI until my 4th year of a BS in CS.

While I think kids should come out of classes with more than just coding skills, I don't think they should be expected to necessarily know a whole lot of theory. If you do introduce theory, I think it should be something that they can more easily relate to. For example rather than starting with the high level theory of NFA and DFA you could start with regular expressions, which are an embodiment of NFA's. Once they grasp regular expressions, you can give them a peek behind the curtain and show how they are implemented.

Similarly you could start with encryption and cryptography which can serve as an intro to that kind of theory. I think the most applied type of AI these days is machine learning, and that can be introduced by starting with "big data" technologies.

Many software engineers go a long way in their careers, or perhaps their entire careers, without an understanding or appreciation for theory. Everyone must at some point grasp architecture, design, and larger concepts than coding but theory doesn't always come into play.

$\endgroup$
  • 3
    $\begingroup$ I wouldn't say Master's degree level. Though some variation between schools can be expected, I got a decent introduction to CS theory (NFA, DFA, regular languages, Turing completeness, and I forget what else) at the third-year undergraduate level. And that was at a school that's known for agriculture, not computer science. Likewise with AI - you can often find at least introductory courses on the subject at the undergrad level. $\endgroup$ – Sebastian Lenartowicz Jun 24 '17 at 22:19
  • $\begingroup$ In my BS CS, I needed 1 year (two classes) of discrete math. Regular languahes, grammars, etc. had one semester. The textbook had pumping lemmings on the cover. At the time, Computer Science meant science — theory. There was only a little programming. $\endgroup$ – JDługosz Jun 25 '17 at 4:29
  • $\begingroup$ Automata and theory of computation were first-year courses at my university, so it's certainly not universally agreed that they need years of background. $\endgroup$ – Peter Taylor Jun 26 '17 at 13:36
  • $\begingroup$ I like the idea of introducing regular expression first, before nfa/dfa. But i feel sad reading your last sentence. $\endgroup$ – kate Mar 7 at 4:57
10
$\begingroup$

Don't try to handle them. Give them exceedingly hard problem that you think cannot be solved without understanding the theory. When they come back to you, unable to solve the problem, then explain how theory can make it easy to solve. On the other hand, if they come back, able to solve it without having to understand the theory then you would've learned something new.

$\endgroup$
  • 3
    $\begingroup$ Welcome to Computer Science Educators! We're glad to have you here. Could you give an example of such a project in your answer? $\endgroup$ – Ben I. Jun 25 '17 at 2:10
  • $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$ – thesecretmaster Aug 29 '17 at 11:17
  • 1
    $\begingroup$ I cannot find the chat though.. $\endgroup$ – kate Mar 7 at 4:58
8
$\begingroup$

Performance is definitely a good angle, in addition to some of the great answers here discussing e.g. regular expressions as a way to deal with automata. It's a way of relating the more practical programming to the theory.

For example, you could start by presenting the pseudo-code for a naive approach to solving something the assignment problem (you can do it naively in $O(n!)$ by checking every possible combination and their costs if I recall correctly), or sorting (Bogosort!). It might be sufficient to just graph the running times for various inputs if you'd like to avoid difficult complexity analysis.

Then, introduce some better algorithms. The Hungarian method is a particular favorite of mine. Don't just explain the theory behind it, show some example applications and have the students implement it. Have them realize how much faster a solution can be found. This is a great way to demonstrate the importance of some of the more theoretical study to those who enjoy the practical programming work more.

$\endgroup$
8
$\begingroup$

Does a good car mechanic have the ability and talent to forge a good wrench? Does a good doctor have the ability to build an X-ray machine?

Computer coding is like any other discipline. There are objects you are going to need for a project that make use of an advanced theory (such as sorting theory) and you are going to know right off that you could spend 3 years creating just that module, or spend a little money and buy a module already made by someone who's got multiple doctorates in the field and did it better than you ever could.

If your students are just shrugging when presented with the theory it is most likely because they intrinsically understand that their skill level is not anywhere near high enough to be any good at writing something that would address that theory, let alone understanding it. So they have no interest in it.

Giving them an assignment designed to make them fall on their face in my experience is going to do either 1 of 2 things. First they will give up and fail and be even more convinced that they shouldn't be interested in theory. Second, they will figure out you are trying to out-fox them and do what I did when I got those kinds of assignments - read the textbooks that were like 3 levels higher than the class which contained the answers, then come back with an answer that not only answered the original question but then proceeded to dissect it and explain why it was a terribly poor question to begin with because it did a lot of hand-waving and made a lot of assumptions that might not hold true in any situation. Then be reinforced that they don't need to bother with the theory since they made the teacher look bad.

What you might try is appealing to their competitive instincts. Divide them into 2 teams with the top coders split up on different teams mixed in with the slower and worse coders who might be better at the theory and setup a contest to see who could write a better app. Once the top coders see that their teammates who are actually paying attention to learning the theory have something to contribute, they might start to feel differently. You can pick an app that is sufficiently broad that it encompasses all the theories you want them to learn.

$\endgroup$
  • $\begingroup$ I can't say I agree with you here, but your comment is well written and thoughtful. Welcome to Computer Science Educators. I hope we hear more from you in the future! $\endgroup$ – Ben I. Jun 25 '17 at 13:35
7
$\begingroup$

One approach that seems to work relatively well with a course I helped TA was to have students work on several homework assignments that put the theory they were learning to practical use.

For example...

  1. Have students implement their own regular expressions engine and make a simplified version of grep at the end of your unit on finite automata. (Depending on how challenging you want to make it, you could have them implement their own parser, a grammar for regexes, and an NFA to DFA converter, or some subset of the above).
  2. If you cover things like modular arithmetic, have them implement RSA (perhaps on top of a bignum library they also build, to up the challenge).
  3. If you're covering propositional logic, perhaps try having them encode complex problems/puzzles into logical constraints, and have them use an SMT solver like z3 to solve them, and point out that attempting to code up solutions to the same problems directly would either be much more inefficient or would be much harder to implement correctly. (You could have them write a generalized solver for sudoku or battleship or any number of other puzzles...). Assignments like these also sidestep the "why do we need theory when we can just use a library or whatever" objection, since the interface to these tools requires understanding theory!
  4. This is more suitable for a data structures and algorithms course, but if you're going to cover graphs (and relations?), maybe have them implement a simplified version of git or something. That said, if your students are unfamiliar with how to use version control, this probably isn't a great idea.

You can calibrate the difficulty of these assignments to an appropriate level for your students by implementing pieces of the assignment for them. (For example, for the z3 thing, I'd probably host your own instance of z3 on a server somewhere and provide students with some pre-written code that calls out to it, since actually installing z3 is a bit of a PITA.)

Giving these sorts of assignments seemed to have the effect of:

  1. Partially satisfying the students who are more interested in programming over theory.
  2. Showing that theory can be applied to actual, concrete, real-world programs.
  3. Helping humble some of the students who are a bit too over-confident and think being merely good at coding is enough to help them get by.

That said, I wouldn't try and "throw them in the deep end", as some of the other answers are suggesting. You want these assignments to be fun, not an exercise in frustration -- after all, the last thing you want to do is to make your students associate theory with frustration!

Within our course, we also tried to emphasize the point that theory isn't some abstract, distant thing that's irrelevant for most programming applications, but can be deeply intertwined with practice and is in fact often necessary if you want to work many interesting problems within computer science.

You can even adjust many traditional assignments to make them connect more strongly with CS. For example, if you cover structural induction, have students use structural induction to prove the correctness of (extremely simplified) Haskell or ML-ish programs. Or, perhaps try and have them use program verification tools like Dafny to prove the correctness of basic programs (though TBH, asking them to work with Dafny or other formal verification tools might have the net effect of scaring them away from theory even more...).

(Disclaimer: I didn't come up with most of these project ideas -- I stole most of them from this course at my university.)

$\endgroup$
4
$\begingroup$

Point of view from someone like them

I'm someone who's similar to the students you're describing, so I'd like to share my views on this topic. I'm slightly older, so I have more experience bruteforcing problems that could be solved more quickly with a faster algorithm.

Through my years of education, I got very bored with learning things that I thought were meaningless and I liked to have a very deep understanding. I realized I just can't remember everything at the level I wanted to if I didn't practice them in my everyday projects, so I only practiced what I thought would be useful.

I got myself a job as a software ENGINEER (eventually architect later), I am no expert in searching algorithms, so I left the theory and complex algorithm to the searchers/very specialized developers:

  • Tree/Stacks/... algorithm (node rotating, ...) ? I don't remember them, however I remember that they're common structure to solve common problems I might face and their implementation exists in pretty much every language.
  • Regular Expression/Compilation : I know they exists and are tools for solving specifics problems, I am very unlikely to need an advanced usage enough to need the theory.
  • Data Mining ? I wouldn't be able to code again a Kernel SVM machine, however I do remember how to built around an application that need that: Normalization of data, learning/validation/test data with randomness, lambda-regression for correlation analysis.

Your students may have have set themselves the same kind of goal than me, leave the theory to searchers. However if they don't bother with theory, they must at least remember than what you present exists and there is no need to reinvent the wheel when it has already being done thoroughly tons of times.

To summarize : you need to aim for different levels of what you want them to remember, because most of them won't go for a career that requires huge theorical knowledge.

About developers that redo the wheel instead of using libraries/framework

On my side, the first time I saw Hibernate (ORM), I trashed it and did all the request myself. Because I wanted to do well, I wrote up all the unit test for that. In the end, it took me a very long time testing that every fields was being inserted/updated correctly. So when I saw Hibernate come back to me, I definitively took the time to learn about it because doing it again would be :

  1. a waste of time writing everything + tests
  2. a very boring thing to do.

So here is something you might try : make them write something and make write and tests like a real system. Everything they coded by themselves must be tested. Then make them use a library/Framework, of course everything the library /framework do, you don't test it. They will understand the huge earn of time and most of all : using a tools to do a job you will do many times over your career saves you from doing a lot of boredom and not interesting things.

$\endgroup$
3
$\begingroup$

First off, I would like to touch base upon the mention of the Question's Comments

Are you trying to produce good programmers or good theoreticians? Making one ruins the other. ~Kevin Krumwiede

As an avid Programmer and Theoretician (both in my spare time), I can clearly state, that, with my Logical Mind, it is very difficult to grasp at new theories without first ripping them apart and reconstructing them myself, figuring out WHY they work, HOW they work, and WHAT is broken that requires the modification of my Mathematical Formula which I've Constructed and Applied to the Simulation. It makes things very difficult to explain to me, because I simply can not for the life of me figure out why it is broken.

As far as a way to explain Theoretical Application to Coding, perhaps it might be easiest to go Old School on them using Variable Arrays and ForEach Loops.

If you have 500 Items to Sort through, and pair up, you could do it Logically, writing out a single line of Code for each and every available option, but if I'm not mistaken, that would be 500 to the 500th power number of lines of code.

It's not Impossible, by a long shot, but is takes much longer than explicitly stating the 500 items within a few simple Groups, and running a ForEach Loop on the Array you have created, which if my estimates aren't too far off, might be around 2,500 lines of code depending upon the Grouping layout.

The sheer workload difference might jog them out of their lack of interest, but your real challenge is yet to come, You will also want to provide some type of applicable example to keep their attention.

If they are Logical like I am, they will have one major Deal Breaker for whether or not they should actually attempt to learn it, it is simple in practice, very optimal in application, and created for efficiency of Brainpower (as ironic as that might sound to you, I'll get back to that in a sec):

How can I use this to improve my Build?

Try asking them for an example of what they are working on in their spare time, see if you can get the Class involved in improving their Program, similar to what everyone does here on StackOverflow, or to put it into more familiar terms: Brainstorm and Think Tank their Projects in order to display Practical Application of the Theories, they will absorb it like a Sponge once they find out it is useful to their interests.

Back to the Brainpower Optimization comment, I realize you find it odd that their lack of interest in such things would be a Mechanism to actually improve Brain Performance, but if you pay really close attention, you might notice that some of the more optimized students seem to be more forgetful, absentminded, or simply focus on whatever interests them (sound familiar?).

There have been a few studies done on this subject already, I forget if the Larger Scale Studies are already ongoing or if they are still gathering Funding, but initial results have shown extremely promising results, along with studies of behaviors of some of the most notable scientific minds in our distant past.

Einstein for example was noted as stating that he never Memorized how to get Home from Work, he never saw the need for it as someone would always Drive him Home, so why would he need to learn their Job? The Logic behind why is that he had better things to think about, such as his work, which we've come to reference long after he has died. The Theory behind the Logic is that he had more Brain available to apply to his Active field, because he didn't fill it up with things he never used, such as the path Home, that is what the Study is trying to figure out specifically.

If I have anything that needs Editing/Correcting in this Answer, let me know in the Comments and I'll edit accordingly should you not feel up for suggesting the Edit yourself.

$\endgroup$
2
$\begingroup$

Make the theory relevant to coding.

For instance, discuss the theory of sorting, and show them a proof of asymptotic optimality, to drive home the message that some problems are provably unsolvable (given certain constraints), and that recognizing such situations is essential if one does not want to waste one's time.

If the syllabus constrains you to teach more abstract theory, I'd cover the various models of computation only as far as necessary to discuss the interesting theorems. For instance, the halting problem can be stated and proven to be undecidable in a model of computation your students are already familiar with, rather than a model of computation that is only ever used in theory.

$\endgroup$
2
$\begingroup$

Tell them they need to prove the correctness of the programs they submit, for it would be irresponsible for you or for their clients to execute code that they do not know for sure that it will not go havoc (a demo might come handy to demonstrate this).

These students probably think it is boring to prove the correctness, or even the termination, of their programs, too. So, since they are good coders, ask them to code a function that given the source of a program, computes whether this program halts for all relevant inputs.

And to prove that this function itself is correct, of course.

$\endgroup$
  • $\begingroup$ What if one of them does it? $\endgroup$ – user737 Aug 29 '17 at 19:20
  • $\begingroup$ ;-) I was talking about a function that can deal with any program. $\endgroup$ – ysalmon Aug 29 '17 at 20:11
  • $\begingroup$ I meant that too. $\endgroup$ – user737 Aug 30 '17 at 13:40
  • $\begingroup$ So they cannot do it : the uniform halting problem is not decidable. And that's the point : learning a bit of "theory" can avoid searching for things that do not exist, which should be of interest to them as they are learning CS and not theology. $\endgroup$ – ysalmon Aug 30 '17 at 13:43
  • $\begingroup$ But searching for things that do not exist is usually what leads us to find or invent those that do. Where would we be without Theology? We certainly don't want students to feel that all the interesting problems have been solved. Have you seen Bret Victor's video, The Future of Programming? At the end he says, "The most dangerous thought that you can have as a creative person is to think that you know what you are doing." The video points out that our attitudes about what a program is and does hardened over about 40 years ago. Now, that self-modifying program to see if it itself will halt... $\endgroup$ – user737 Aug 30 '17 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.