Robert Talbert, one of my colleagues here at GVSU, has been using Python in teaching Discrete Mathematics for Computer Science for years; but I kept playing around with other systems (Haskell or Java) without ever really ‘tasting’ Python. Then, midway through last semester (i.e. just a few months ago), when I was about to tell my students what system they should use to do some work in this introductory course on Discrete Mathematics, I went through the Python tutorial — and I was hooked. Python provided pretty much precisely what I wanted!

I went down the hallway to Robert’s office, and I said:
“Why didn’t you tell me how wonderful Python is?”
He replied:
“I wanted you to find out for yourself.”
(Incidentally, can you tell from this reply of his that Robert is a mathematician?

Here’s what I’m doing with Python this semester:

Of course it’s necessary to start with teaching students the basics of Python since our CS curriculum here at GVSU does not yet (;-) use Python in our beginning Computer Science course. I start presenting Python during the second week of the course (after covering translation between decimal, binary, and hexadecimal numbers etc. during the first week). And teaching Python is simple, considering how easy it is to start using it: you can just start its interpreter and type expressions which get evaluated. How easy is that?! (The contrast between interpreted and compiled languages is classic.) None of my students have any trouble starting to use it. For an initial homework exercise, I ask them to try some of the actions specified in the Python tutorial, after I show them such actions myself during lecture. And actually what I show them first in lecture is how Python can do this course's entire first week's assignment, translating between decimal and binary and hexadecimal etc., by typing just a few lines of text in Python:

● An integer number is said to be a perfect number if its factors, including 1 (but not the number itself), sum to the number. For example, 6 is a perfect number, because 6 = 1 + 2 + 3, and 8 is not a perfect number, because 8 ≠ 1 + 2 + 4. Write a function perfect(n) that determines whether parameter n is a perfect number.
[Acknowledgement: this exercise is derived from Deitel & Deitel.]

(While I don't present map() or lambda with the initial material here, I do ask the students to try, for example, list(filter(perfect, range(9999)).)

The total number of points for this Homework Assignment #2 is 24, and my students' median score is 24 and their mean is 22.89. Looks like Python is easy to learn!

Next, like any general programming language, Python provides utilities for showing the numbers that correspond to characters and vice-versa: ord(x) and chr(n). I ask students to use these utilities to do Caesar ciphering and deciphering. Continuing to use the interpreter (since this course's purpose is Discrete Math, not really programming per se), managing input is a non-issue, so students can do this work much more easily than they could in Java (which I had students use in the past).

Above, I showed bin(n). Students can use it when I ask them to learn operations on binary numbers: addition, multiplication, shift left, bitwise AND, etc. Of course Python provides all the standard bitwise operators. And whereas Java's Integer.toBinaryString(n) may appear better than Python's bin(n) for negative integers (by the way it's because Python's integers aren't limited in size), well, we're Computer Science professors and Python is a programming language:

I don't use Python for this course's next topics: boolean algebra, propositional calculus, predicate logic, and introduction to writing proofs — these topics appear to me to require skills that are orthogonal to mere computation. (Actually I do use the C programming language to show students that true + true is true, etc., and that bool values are output as 0 and 1.) A few years ago I was actually the instructor of record for an undergraduate Honors College student's Senior Project which was a Python program that performed theorem proving. But I don't have my students use that Python program: to learn theorem proving for the Computer Science curriculum, I think students need to 'get their hands dirty' more, by trying to construct proofs themselves. For reference, consider learning outcomes specified in "Computer Science Curricula 2013":

Of course, it’s necessary to handle infinite sets carefully as in Haskell (with e.g. [0..]), avoiding for example any attempt to display such entirely or check a value which has already been ‘passed’ (such as a negative one for N). Nonetheless, I think this is cool.

Now, when a 'calculator' appears to be available to do students' math homework for them, a teacher might react negatively. But I think a 'calculator' actually provides opportunities for pedagogy to quickly get through relatively mundane details and reach more thorough or deeper understanding of concepts, e.g. set identities. (How good are your students’ proofs using set identities if they haven’t been able to clearly see the results of some of the operations such as union and complement?) And of course it's also possible to use a 'calculator' to verify or clarify points that students have doubts about such as what is the cardinality of {∅, {∅}}, and whether {1,2,3} may be a subset of itself.

Exercises that I assign to students on this material include simple 'calculator' exercises to figure out how to get Python to calculate a range of set expressions suchas A ∪ ~(B ∩ C), and exercises to write a function powerset(S) and a function is_partition(𝒞), where 𝒞 is a collection or set of sets. (By the way, the sets that are inside a collection or set of sets actually need to be frozensets in Python. Can you guess what Disney movie I reference in my class when this comes up? ;-) .

Following sets, the next topic in this course is Tuples and Relations. Well, guess what Python provides — even using traditional notation, if you want?

(The video clip I show to my students regarding relations may be a little risqué; sorry.)

The next topic in this course is an introduction to mathematical induction. See above regarding whether students’ learning to construct proofs may be very susceptible to processing by a programming environment.

The next topic is performance: O() etc. And look what you can do in Python:

I actually show students the values of f(n), g(n), and c*g(n). And I think demonstrations like this make O(), Ω(), etc. come more alive for students. Seeing actual values appears to clarify relative growths more than considering 'abstract' aspects of functions such as derivatives (and how memorable are the positions of different curved lines in graphs?).

What computing systems do you like to use in your introductory course on Discrete Mathematics for Computer Science? What are the strengths (and/or weaknesses) that you perceive with them?

P.S. A few days after I originally made this posting, I gave a midterm examination to this class; and here's what I asked about Python. (Did I say above that Python might not be good for boolean algebra and logic?

[8 points] What are Python's outputs if material is entered as follows?
(Write the outputs in the spaces for them below.)