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

MCS 260 Fall 2021 Homework 9 Solutions

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

Instructions:

  • 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.)

Deadline

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

Topic

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

Collaboration

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

Resources you may consult

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

Point distribution

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

What to do if you're stuck

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

( 1. There's no problem 1 )

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

2. Module for testing integers for digit properties

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.

Solution

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]:
False
In [5]:
has_small_digits(1021,2)
Out[5]:
True
In [6]:
has_small_digits(1021,5)
Out[6]:
True
In [7]:
has_small_digits(351622,5)
Out[7]:
False
In [8]:
has_small_digits(351622,6)
Out[8]:
True
In [9]:
is_antipalindrome(5128)
Out[9]:
False
In [10]:
is_antipalindrome(4815)
Out[10]:
True

3. Special powers

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 350 and
  • 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.

Solution

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
d=149, k=2, d**k=22201
d=303, k=3, d**k=27818127

Revision history

  • 2021-10-31 Initial release