Instructions for remarkableMultiples

This task is part of project03 which is due at 23:00 EST on 2026-09-29.

You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.

You can download the starter code for this task using this link.

See how to submit this task using this link.

Put all of your work for this task into the file remarkableMultiples.py
(which is provided among the starter files)

This task gives you practice with while loops in the context of finding numbers that have a remarkable property.

Let's say that a number is remarkable if its digit sequence consists of a nonempty sequence of 7s followed by a possibly empty sequences of 0s. Examples of remarkable numbers are 7, 70, 77, 700, 770, 777, and 777700.

It is a surprising fact that every positive integer has a multiple that is remarkable. You don't have to understand why this is true but believe it for now. (You will understand why later this semester when we study a more efficient way to find such numbers.) Here are the smallest remarkable multiples for all integers from 1 up to 16:

1 * 7 = 7
2 * 35 = 70
3 * 259 = 777
4 * 175 = 700
5 * 14 = 70
6 * 1295 = 7770
7 * 1 = 7
8 * 875 = 7000
9 * 86419753 = 777777777
10 * 7 = 70
11 * 7 = 77
12 * 6475 = 77700
13 * 59829 = 777777
14 * 5 = 70
15 * 518 = 7770
16 * 4375 = 70000

The smallest remarkable multiple for 9 (777777777) seems rather large, but it turns out it can be calculated in a reasonable amount of time by the brute force algorithm that you will use. However, here are just a few examples of smallest remarkable multiples that are way too large to be calculated by the brute force algorithm:

17 * 457516339869281 = 7777777777777777
76 * 1023391812865497075 = 77777777777777777700
83 * 937081659973226238286479250334672021419 = 77777777777777777777777777777777777777777
92 * 8454106280193236714975 = 777777777777777777777700
94 * 827423167848699763593380614657210401891252955 = 77777777777777777777777777777777777777777777770
97 * 8018327605956471935853379152348224513172966781214203894616265750286368843069873997709049255441
   = 777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777

Teaser: Intriguingly, all of the above can be calculated almost immediately by a more efficient algorithm we'll study later in the semester.

The goal of this task is for any positive integer n to find the smallest multiple of n that is remarkable, using a brute force approach of trying all possible multiples in increasing order until a remarkable one is found.

Your task is to define the following two functions in the provided file remarkableMultiples.py:

  1. isRemarkable: Takes a single argument that you may assume is a positive integer. It returns True if this integer is remarkable (i.e., has the form of a nonempty sequence of 7s followed by a possibly empty sequence of 0s), and False otherwise. The sample output gives examples of how isRemarkable should work.

    As discussed in lecture, there are two strategies for implementing isRemarkable, and you may use either one.

    • Convert the integer to a string, and then process the digits of the string from left-to-right or right-to-left to check if it satisfies the definition of a remarkable number.
    • Iteratively find the digits of the integer from right-to-left by taking the remainder of the integer with respect to 10 and making the integer smaller by taking its integer quotient by 10. Check if these digits satisfy the definition of a remarkable number.

    Regardless of which strategy you choose, you should use one or more while loops in your definition and no for loops.

  2. findSmallestRemarkableMultiple: Takes a single argument that you may assume is a positive integer. It returns the smallest multiple of this integer that is remarkable. The sample output gives examples of how findSmallestRemarkableMultiple should work.

    You must use the following simple "brute force" algorithm to find the smallest remarkable multiple: iteratively consider all possible multiples by multiplying the integer by all integers in the the sequence 1, 2, 3, etc. until the first multiple that is remarkable (as determined by calling isRemarkable) is found.

Notes

  • In the file remarkableMultiples.py, define your functions in the specific areas that comments indicate that you should define them.
  • The file remarkableMultiples.py has some code for testing at the bottom that you are not required to understand and should not edit!.
  • You are not allowed to define or use any additional helper functions.
  • You should strive to make your code as understandable as possible, using comments to explain any aspects of your code that are not obvious.
  • There are two ways to test your code. You should use both!
    1. Execute the function call testRemarkables(). This will test your findSmallestRemarkableMultiple function on all inputs between 1 and 100 that are expected to complete in a reasonable amount of time using the brute force algorithm.
    2. Save your remarkableMultiples.py file and then in Thonny run the file test_remarkableMultiples.py. This will test your isRemarkable and findSmallestRemarkableMultiple function on many inputs, reporting any inputs for which they the wrong result. It will also perform some tests that verify that your function definitions satisfies certain structural requirements and prohibitions. It's a good sign if your code passes all tests in test_remarkableMultiples.py, but this does not guarantee that your definition is completely correct or that it stylistically elegant.
  • Some other information related to remarkable multiples:
    • There are more efficient algorithms for finding remarkable multiples that we will study later in the semester that will very quickly handle much larger remarkable multiples than the brute force algorithm. And one of these more efficient algorithms will explain why every positive integer has a remarkable multiple!
    • In this problem, the notion of "remarkable" depends on the special digit 7. But it turns out that the digit repeated before the 0s can be any digit in the range 1 to 9, inclusive.

Examples

isRemarkable Examples

The following are some examples that show how isRemarkable should work:

In []:
isRemarkable(7)
Out[]:
True
In []:
isRemarkable(70)
Out[]:
True
In []:
isRemarkable(77)
Out[]:
True
In []:
isRemarkable(7777)
Out[]:
True
In []:
isRemarkable(7770)
Out[]:
True
In []:
isRemarkable(7700)
Out[]:
True
In []:
isRemarkable(7000)
Out[]:
True
In []:
isRemarkable(0)
Out[]:
False
In []:
isRemarkable(789)
Out[]:
False
In []:
isRemarkable(7707)
Out[]:
False
In []:
isRemarkable(17700)
Out[]:
False

findSmallestRemarkableMultiple Examples

The following are some examples that show how findSmallestRemarkableMultiple should work:

    In []:
findSmallestRemarkableMultiple(1)
Out[]:
7
In []:
findSmallestRemarkableMultiple(2)
Out[]:
70
In []:
findSmallestRemarkableMultiple(3)
Out[]:
777
In []:
findSmallestRemarkableMultiple(4)
Out[]:
700
In []:
findSmallestRemarkableMultiple(5)
Out[]:
70
In []:
findSmallestRemarkableMultiple(6)
Out[]:
7770
In []:
findSmallestRemarkableMultiple(7)
Out[]:
7
In []:
findSmallestRemarkableMultiple(12)
Out[]:
77700
In []:
findSmallestRemarkableMultiple(13)
Out[]:
777777
In []:
findSmallestRemarkableMultiple(64)
Out[]:
7000000
In []:
findSmallestRemarkableMultiple(48)
Out[]:
7770000
In []:
findSmallestRemarkableMultiple(26)
Out[]:
7777770
In []:
findSmallestRemarkableMultiple(96)
Out[]:
77700000
In []:
findSmallestRemarkableMultiple(52)
Out[]:
77777700
In []:
findSmallestRemarkableMultiple(73)
Out[]:
77777777
In []:
findSmallestRemarkableMultiple(9)
Out[]:
777777777

Rubric

This task does not have an explicit list of rubric items. But here are some things to focus on:
  • Your isRemarkable function definition should be correct: it should return the correct boolean for all nonnegative integers.
  • Your findSmallestRemarkableMultiple function definition should be correct: it should return the correct remarkable multipled for nonnegative integer inputs for which the brute force algorithm is able to find an answer in a "reasonable" amount of time (no longer than a minute or so, typically much quicker). Note that the testing mechanisms described above "know" which inputs can be solved in a reasonable amount of time and will only test inputs that satisfy this property.
  • For iteration, your definitions should use only while loops and not for loops, and the iterations should be organized in a way that they they clearly acheive their intended purpose.
  • Your definitions should be easy to understand. Use comments and parameters/variables with well-chosen, meaningful names to make it clear why the function calculates the correct result.
  • Your definitions should follow the do not repeat yourself (DRY) principle to avoid unnecessary repetition of code patterns.
  • Your definitions should satisfy any implementation constraints mentioned in the function specification.