These things might be helpful while working on the problems. Remember that for worksheets, we don't strictly limit what resources you can consult, so these are only suggestions.
Project 1 is due on 4 February. To prepare for working on it, please download and extract ths starter pack, which is a ZIP file:
You don't just want to view the contents of the ZIP file in Windows explorer; it's important to actually extract the files so they exist in a directory where you can do your project work.
When you've extracted the starter pack, check that you know the location of
textsimulation.py and that you can run it in the terminal.
The point of asking you to do it during lab is to ensure the TA can help you if you run into any problems.
Download these files related to the robot simulation from the course sample code repository and put them in a directory where you'll do your work for this problem.
Then, build these new robots in
bots.py that are subclasses of
Vector(1,0), but any direction can be specified in the constructor)
Add these robots to the simulation and confirm they exhibit the expected behavior.
Build a module
encoders.py) containing classes for simple ciphers (or codes; ways of obscuring the contents of a string that can be undone later by the intended recipient).
There should be a base class
BaseEncoder that has two methods:
encode(self,text): Returns the string
textunchanged. Subclasses will alter this behavior.
decode(self,text): Returns the string
textunchanged. Subclasses will alter this behavior.
It should be the case that
obj.decode(obj.encode(s)) == s
is true for any string
s, and for any object
obj that is an instance of
BaseEncoder or subclass thereof.
Then, build subclasses of
BaseEncoder that implement encoding and decoding by different ciphers, including:
RotateEncoder : Encoding rotates letters in the alphabet forward by a certain number of steps, e.g. so rotation by 5 turns "a" into "f" and "z" into "e" (because we wrap around when we reach the end of the alphabet). No transformation is applied to characters other than capital and lower case letters. Constructor accepts an integer, specifying the number of steps to rotate.
Rot13Encoder : A subclass of
RotateEncoder that fixes the steps at 13, so that encoding and decoding are the same operation.
SubstitutionEncoder : The constructor accepts two arguments,
post. The string
pre is a list of characters to be replaced when encoding, and string
post indicates the things to replace them with. For example, using
post="1j4e" would mean that "a" is supposed to be replaced by "1", "b" by "j", "c" by "4", and so on.
post="bca"should encode "banana" to "cbnbnb", and not "ccncnc".
postcontain the same characters but in a different order. If that's not the case, then it would be impossible to ensure that decoding after encoding always gives the original text back again.
You can find some test code below. The test code assumes all of the classes are in the global scope.
E = RotateEncoder(5) s = E.encode("Hello world!") # Mjqqt btwqi! print(s) # Mjqqt btwqi! print(E.decode(s)) # Hello world! F = SubstitutionEncoder("lmno","nolm") s = F.encode("Hello everyone!") print(s) # Hennm everymle! print(F.decode(s)) # Hello everyone!
Work on these open-ended problems if you finish the exercises above. We don't plan to include solutions to these in the worksheet solutions, but we may do so if most people end up working on any of these.
Write a subclass of
dict that only lets you set the value associated with a key once. If you try to change the value associated with an existing key, it raises
ValueError. You'll need to read up on the special method
__setitem__ to make this work.
(WORM stands for Write Once, Read Many times.)
The encoders in problem 3 don't handle the problem of communicating to your message recipient the information about what code you will use for future messages.
__repr__ methods to the ciphers that give enough information so that a message recipient who is given encoded text and the return value of
str(encoder_object) would be able to instantiate an encoder and decode a message.
Design and implement another cipher as a subclass of BaseEncoder which isn't as simple as substituting letters with specified replacements. For example, you might make it so that the way a letter is handled depends on both the letter and the text that's been encoded so far. Confirm that your cipher
Make a robot class (a subclass of
DestructBot) that stands still for a specified number of steps and then self-destructs. But before it does so, this class calls a user-specified function. The function is given as an argument to the constructor. So, for example:
def bye(): """Robot says goodbye""" print("Thanks for including me in this simulation. I was glad to be written in Python. Goodbye.") R = bots.DelayedActionBot(position=Point(3,3),lifetime=10,action=bye) # ... code to run the simulation ...
should make a robot that sits at position (3,3) for 10 steps, prints a message, and then self-destructs.
action argument of the constructor should default to
None, and the class should know to not do anything if
action==None. That way, any code that works with
DestructBot will also work with