A document from MCS 260 Fall 2021, instructor Emily Dumas.
You can also get the notebook file.

- Course instructor: Emily Dumas
- Prepared by: Kylash Viswanathan and Emily Dumas

- Complete the problems below, which ask you to write Python scripts.
- Upload your python code directly to gradescope, i.e. upload the
`.py`

files containing your work. (If you upload a screenshot or other file format, you won't get credit.)

This homework assignment must be submitted in Gradescope by 10am CST on Tuesday, October 19, 2021.

This homework focuses **dispatch tables**, **operators on iterables** (e.g. any(), all()), and **modules**.

**Collaboration is prohibited**, and you may only access resources (books, online, etc.) listed below.

The course materials you may refer to for this homework are:

- Worksheet 9 Solutions
- Sample programs (especially the ones in the
`modules/`

subdirectory; the project 1 solution may also be helpful) - Lecture 21 - Dispatch tables
- Lecture 22 - Operators on iterables
- Lecture 23 - Modules
- Slides from any other lecture of MCS 260, Fall 2021.
- Since
`any()`

and`all()`

are often used with list comprehensions, you may want to consult: Lecture 8 - list methods and list comprehensions

- Since
- Downey's book

This homework assignment has 2 problems, numbered 2 and 3. **Problem 2 is a bit longer than usual, so it gets 8 points this time.** Thus the grading breakdown is:

Points | Item |
---|---|

2 | Autograder |

8 | Problem 2 |

4 | Problem 3 |

14 |
Total |

Ask your instructor or TA a question by email, in office hours, or on discord.

Gradescope will show the results of the automated syntax check of all submitted files as the score for problem 1.

Write a module `digitprop`

(contained in a file `digitprop.py`

) that contains two functions. The function definitions and docstrings you should use are shown below. Write the functions to do what the docstrings describe. Include a module docstring as well.

**Restricted methods note: For full credit you must use any() or all() in an appropriate way in each function.** You may need to use

`enumerate()`

, too.The module shouldn't do anything other than define functions when it is imported.

Checklist for grading:

- Is the module in a file called
`digitprop.py`

? - Does the module have a file-level docstring that describes what it contains?
- Does it use the same function definitions and function docstrings as provided in Homework 9?
- Do the functions do what was requested?
- Does the module contain
*only*function definitions, without doing anything else when it is imported? - Does each function use either
`all()`

or`any()`

in an essential way?

**Advice:** The function bodies, excluding the docstrings, can be just one or two lines each.

The solution below is a concise example of how the all(..) function is used.

In [3]:

```
# contents of digitprop.py
"""
Tests for special properties of the decimal digits of a positive integer.
"""
def has_small_digits(n,maxdigit):
"""
Determines whether or not the digits of `n` are all between 0 and `maxdigit` (inclusive).
Returns `True` or `False` accordingly.
e.g.
has_small_digits(1021,1) returns False - third digit is larger than 1
has_small_digits(1021,2) returns True - all digits between 0 and 2
has_small_digits(1021,5) returns True - all digits between 0 and 5
has_small_digits(351622,5) returns False - fourth digits if larger than 5
has_small_digits(351622,6) returns True - all digits between 0 and 6
"""
return all([int(digitchar) <= maxdigit for digitchar in str(n)])
def is_antipalindrome(n):
"""
Takes a positive integer `n`.
Returns `True` if reversing the order of the digits in `n` gives the same
result as replacing each digit d of `n` with 9-d ("flipping" the digits).
Otherwise, returns `False`.
(A number `n` for which this function returns `True` might be called an *antipalindrome*.)
e.g.
is_antipalindrome(5128) returns False, because reversing order gives 8215 while flipping digits gives 4871.
is_antipalindrome(4815) returns True, because reversing order or flipping digits each gives 5184.
"""
return all([9-int(digitchar) == int(str(n)[-(index+1)]) for index, digitchar in enumerate(str(n))])
```

In [4]:

```
# Test cases from the docstrings
has_small_digits(1021,1)
```

Out[4]:

In [5]:

```
has_small_digits(1021,2)
```

Out[5]:

In [6]:

```
has_small_digits(1021,5)
```

Out[6]:

In [7]:

```
has_small_digits(351622,5)
```

Out[7]:

In [8]:

```
has_small_digits(351622,6)
```

Out[8]:

In [9]:

```
is_antipalindrome(5128)
```

Out[9]:

In [10]:

```
is_antipalindrome(4815)
```

Out[10]:

For the purposes of this problem, let's say that an integer is *special* if it is either an antipalindrome (in the sense of problem 2) **or** if it only uses the digits 0, 1, 2.

For example, 1012, 212000, and 4815 are all special, while 3012 and 5128 are not special.

Write a program `hwk9prob3.py`

that imports the `digitprop`

module you wrote in problem 2 and uses it to answer the following:

Question.Is

`d**k`

ever special when

`d`

is a non-special number between 100 and 350and`k`

is between 2 and 350 ?

In this problem, "between" has the inclusive meaning, so e.g. `k`

is allowed to be `2`

or `350`

.

If the program finds any of these, it should print `d`

, `k`

, and `d**k`

. After running the program, paste the results you found as comments at the bottom of `hwk9prob3.py`

.

Make sure the program has a file-level docstring.

Checklist for grading grading:

- Does the program have a docstring that describes what it does?
- Does the program use the module
`digitprop`

rather than replicating any of its features? - Does the program do what was requested?
- Are the results produced by the program (
`d`

,`k`

,`d**k`

) included in comments at the bottom of the program?

**Note:** A correct program will take a some time to run, since it will need to examine about 81,000 integer powers.

The solution below makes use of the digitprop module, as defined above. To run the code, one must save the module above in a .py file with the correct name in the same directory as the code below.

In [17]:

```
"""
Program tests whether numbers exist such that
for integral values of d between 100 and 350 inclusive are non-special and d**k is special, where k is
between 2 and 250 inclusive.
"""
import digitprop
def is_special(n,maxdigit):
"""
Determines whether a number is special if it has digits that do not exceed a given digit, or
is an antipalindrome (i.e. its digits read backwards are equal to 9 - digit, for each digit)
"""
return digitprop.has_small_digits(n,maxdigit) or digitprop.is_antipalindrome(n)
# Test Bounds as given
maxdigit = 2
min_d = 100
max_d = 350 + 1
min_k = 2
max_k = 350 + 1
# Loops through values of d and k given above, and
# determines whether numbers d,k exist where d is non-special and d**k special
# Inserts said values in a list and prints them
for d in range(min_d,max_d):
if is_special(d,maxdigit):
continue
for k in range(min_k,max_k):
n = d**k
if is_special(n,maxdigit):
print("d={}, k={}, d**k={}".format(d,k,n))
## The special d**k with non-special d are
# 149**2=22201
# 303**3=27818127
```

- 2021-10-31 Initial release