Skip to content

Instantly share code, notes, and snippets.

@ljbelenky
Last active July 13, 2021 23:06
Show Gist options
  • Save ljbelenky/845ceb92207ab3b8b69697538575e2f6 to your computer and use it in GitHub Desktop.
Save ljbelenky/845ceb92207ab3b8b69697538575e2f6 to your computer and use it in GitHub Desktop.
OOP Exercise: Combination Locks
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# OOP Exercise\n",
"\n",
"## Combination Lock\n",
"\n",
"### Making the Lock\n",
"\n",
"In this exercise, we're going to get some exercise building and opening combination locks using OOP.\n",
"\n",
"When we build a lock, the first thing we need to know is how many digits are in the combination. Most combination locks take between 3 and 8 digit combinations.\n",
"\n",
"For now, let's assume each input digit is 0-9, although some combination locks, like the popular Master dial lock take inputs 0-39.\n",
"\n",
"To open the lock, we first need to `clear` the lock. Then, we enter the digits one at a time. At any time, we can try to open the lock and one of two things will happen: either it will open, or not. The lock will only open when the input contains the correct number of digits and they are all correct.\n",
"\n",
"Create a file `combo_lock.py` that contains a `class ComboLock` and share it with your partner. Your partner should be able to use it as follows:\n",
"\n",
"```\n",
" from combo_lock import ComboLock\n",
" \n",
" my_lock = ComboLock(digits = 4)\n",
"```\n",
"\n",
"After that, they should be able to figure out how to use the lock using `dir(my_lock)`. (No peeking at the combo!)\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Opening the Lock\n",
"\n",
"Now that you've recieved a lock from your partner, try opening it.\n",
"How many attempts does it take to open it?\n",
"Think of at least two different strategies to try opening it.\n",
"Create 1000 locks and try the two different strategies.\n",
"Would this be an efficient way to try a really large number of locks?\n",
"How many attempts would you expect it to take using different strategies?\n",
"Create plots that show the distribution of how many attempts it takes to open the locks with each strategy.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
@skylarenglish
Copy link

skylarenglish commented Aug 7, 2020

My current function for deciding to open the lock after Land has submitted some digits looks something like this:

def open_lock(input_sequence):
return input == 1234

My partner Land keeps peeking at the lock combination, I can feel it! I just can't trust Land not to inspect the object or the source .py file and look at what the key I am comparing to is! But I have a plan. I would like to make the function that unlocks the lock have only content that I don't mind Land seeing. I know I can use the hash function (a builtin) to map an object to a number. I am thinking I could implement something like the code below. My implementation of these security features should not break any of Land's testing code and vice versa.

def open_lock(input):
return hash(str(input)+"you'll never find it Land!") == -7068180340459975452

#possible test code to show unit tests
print("Here is how we figure out what our hashed number should be: " + str(hash(str(1234)+"you'll never find it Land!")))
assert open_lock(1235) == False
assert open_lock(1234) == True

@ljbelenky
Copy link
Author

Don't forget to implement a repr.

@ljbelenky
Copy link
Author

Suggestions for further improvement:

  1. As Skylar suggested, hash the combination to prevent peeking
  2. Ensure the user can only enter the code one digit at a time.
  3. Implement checking to see if the digit entered is allowable (i.e, is a number and within the correct range). Determine how to deal with incorrect input (i.e, raise an error, use a default or coerced value, reject the input without an error, display an error message, etc)
  4. Expand the number of allowable digits from 0-9 to 0-n.
  5. Make it send you a text message if someone successfully opens your lock
  6. Have it send a text message if someone attempts to open the lock X number of times and ask you to enable additional attempts.

@ljbelenky
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment