Objective: In this lab, you will learn how to define and implement classes in Python, and you will learn how to properly define the __init__ and __str__ special methods as well as write a recursive display method across two classes. You will work on a simple mind map application using two classes: MindMapLeaf and MindMapComposite. Along the way, you will organize your code into separate files and test class methods step by step.
A successful implementation of this lab will output text similar to this...
mindmap
root((mindmap))
Origins
Long history
::icon(fa fa-book)
Popularisation
British popular psychology author Tony Buzan
Research
On effectivness<br/>and features
On Automatic creation
Uses
Creative techniques
Strategic planning
Argument mapping
Tools
Pen and paper
Mermaid
...and when pasted into Mermaid.Live will generate a mindmap similar to this:
mindmap
root((mindmap))
Origins
Long history
::icon(fa fa-book)
Popularisation
British popular psychology author Tony Buzan
Research
On effectivness<br/>and features
On Automatic creation
Uses
Creative techniques
Strategic planning
Argument mapping
Tools
Pen and paper
Mermaid
- Create a new PyCharm Project named
PyLab011to organize your code. - Inside this Project, create two separate Python files:
mindmap_leaf.pymindmap_composite.py
-
Open
mindmap_leaf.pyand write the following class definition:class MindMapLeaf: # Step 1: Write the __init__ method # - Define an __init__ method that takes two parameters: name and shape. # - Assign these parameters to the instance variables self.name and self.shape. ``` **Hint**: Use `self.name = name` and `self.shape = shape` to assign attributes.
-
Write the
__str__Method:- Purpose: This method should return the name of the leaf formatted with its shape.
- Instructions:
- Define a method named
__str__that calls another methodget_shape_representation(). - Use
format()to insertself.nameinto the shape representation and return the formatted string.
- Define a method named
# Step 2: Write the __str__ method # - Define __str__ that formats the name using get_shape_representation().
Hint:
return shape_representation.format(self.name) -
Write the
displayMethod:- Purpose: This method should print the formatted name with a specified level of indentation.
- Instructions:
- Define a method named
displaythat takes anindentparameter (default value 0). - Use
" " * indentto create the indentation and print the formatted name.
- Define a method named
# Step 3: Write the display method # - Print the name with indentation using " " * indent + str(self).
-
Write the
get_shape_representationMethod:- Purpose: This method should return a string template based on the shape.
- Instructions:
- Define a dictionary named
shapesinsideget_shape_representation. - Use different symbols to represent shapes in your dictionary like
"circle": "(({}))","oval": "({})","square": "[{}]","cloud": "){}(","hexagon": "{{{{{}}}}}","bang": ")){}((" - Return the shape template using
shapes.get(self.shape, "{}").
- Define a dictionary named
# Step 4: Write the get_shape_representation method # - Create a shapes dictionary with shape templates. # - Use shapes.get to return the appropriate shape template.
-
Create a file named
test_mindmap_leaf.pyand add code to test your class:from mindmap_leaf import MindMapLeaf # Step 5: Create a MindMapLeaf object and test the __str__ and display methods. leaf = MindMapLeaf("Jean-Luc Picard", "circle") print(str(leaf)) # Should display "((Jean-Luc Picard))" leaf.display(2) # Should display " ((Jean-Luc Picard))" with two spaces print("MindMapLeaf tests completed!")
-
Run
test_mindmap_leaf.pyto check your implementation.
-
Open
mindmap_composite.pyand start defining your class:import os class MindMapComposite: # Step 1: Write the __init__ method # - Define an __init__ method that takes name and shape as parameters. # - Initialize self.name, self.shape, and an empty list self.children. ``` **Hint**: Use `self.children = []` to initialize the list.
-
Write the
addandremoveMethods:- Purpose: Manage children of the composite node.
- Instructions:
add(child): Append the child toself.children.remove(child): Remove the child fromself.children.- HINT: the
childparameter is an object of type MindMapComposite or MindMapLeaf
# Step 2: Write the add and remove methods # - Use append() to add and remove() to delete from the children list.
-
Write the
__str__Method:- Purpose: Similar to
MindMapLeaf, but returns the composite’s name formatted with its shape. - Instructions:
- Format
self.nameusingget_shape_representation()and return the string.
- Format
# Step 3: Write the __str__ method # - Format the name using get_shape_representation() and return it.
- Purpose: Similar to
-
Write the
displayMethod:- Purpose: Print the formatted name and call
displayon all children. - Instructions:
- Print the composite’s name with the specified indentation.
- Use a loop to call
child.display(indent + 2)for each child.
# Step 4: Write the display method # - Print the name with the specified indentation. # - Loop over each child and call display with increased indentation.
- Purpose: Print the formatted name and call
-
Write the
get_shape_representationMethod:- Purpose: Return the shape template from a dictionary, like in
MindMapLeaf. - Instructions:
- Define a dictionary with shape templates and return the template using
shapes.get(). - HINT: This is the SAME as MindMapLeaf!
- Define a dictionary with shape templates and return the template using
# Step 5: Write the get_shape_representation method # - Create a dictionary with shape templates. # - Use shapes.get to return the template.
- Purpose: Return the shape template from a dictionary, like in
-
Create a file named
test_mindmap_composite.pyand write code to test your class:from mindmap_leaf import MindMapLeaf from mindmap_composite import MindMapComposite # Step 6: Create MindMapComposite and MindMapLeaf objects to test root = MindMapComposite("Root", "circle") leaf1 = MindMapLeaf("Child 1", "square") leaf2 = MindMapLeaf("Child 2", "cloud") root.add(leaf1) root.add(leaf2) print(str(root)) # Should display "((Root))" root.display() # Should display root and its children print("MindMapComposite tests completed!")
-
Run
test_mindmap_composite.pyto verify your implementation.
- Create a file named
main.pyto display my mind map:
#!/usr/bin/env python3
from mindmap_leaf import MindMapLeaf
from mindmap_composite import MindMapComposite
def main():
if __name__ == "__main__":
# Root of the mindmap
root = MindMapComposite( "The Battle at Wolf 359", "circle" )
characters = MindMapComposite( "Characters", "oval" )
characters.add( MindMapLeaf( "Jean-Luc Picard / Locutus", "plain" ) )
characters.add( MindMapLeaf( "William Riker", "plain" ) )
characters.add( MindMapLeaf( "Data", "plain" ) )
characters.add( MindMapLeaf( "Worf", "plain" ) )
characters.add( MindMapLeaf( "Borg Queen (implied presence)", "plain" ) )
root.add( characters )
plot_points = MindMapComposite( "Plot Points", "square" )
plot_points.add( MindMapLeaf( "Picard is assimilated by the Borg", "plain" ) )
plot_points.add( MindMapLeaf( "Riker takes command of the Enterprise", "plain" ) )
plot_points.add( MindMapLeaf( "The Federation fleet suffers heavy losses", "plain" ) )
plot_points.add( MindMapLeaf( "Enterprise crew devises a plan to stop the Borg", "plain" ) )
root.add( plot_points )
themes = MindMapComposite( "Themes", "cloud" )
themes.add( MindMapLeaf( "Identity and loss of self", "plain" ) )
themes.add( MindMapLeaf( "Duty and leadership", "plain" ) )
themes.add( MindMapLeaf( "Humanity vs. technology", "plain" ) )
themes.add( MindMapLeaf( "Collectivism vs. individuality", "plain" ) )
root.add( themes )
setting = MindMapComposite( "Setting", "hexagon" )
setting.add( MindMapLeaf( "USS Enterprise-D", "plain" ) )
setting.add( MindMapLeaf( "Wolf 359 (space battle location)", "plain" ) )
setting.add( MindMapLeaf( "Borg Cube", "plain" ) )
setting.add( MindMapLeaf( "Starfleet Command (background communication)", "plain" ) )
root.add( setting )
conflicts = MindMapComposite( "Major Conflicts", "bang" )
conflicts.add( MindMapLeaf( "Federation vs. Borg (existential threat)", "plain" ) )
conflicts.add( MindMapLeaf( "Riker’s internal struggle as acting captain", "plain" ) )
conflicts.add( MindMapLeaf( "Enterprise's fight to save Picard from assimilation", "plain" ) )
root.add( conflicts )
dialogue = MindMapComposite( "Dialogue Highlights", "oval" )
dialogue.add( MindMapLeaf( "“I am Locutus of Borg. Resistance is futile.”", "plain" ) )
dialogue.add( MindMapLeaf( "Riker: \"Mr. Worf, fire.\"", "plain" ) )
dialogue.add( MindMapLeaf( "Guinan advising Riker on letting go of Picard", "plain" ) )
root.add( dialogue )
stage_directions = MindMapComposite( "Significant Stage Directions", "square" )
stage_directions.add( MindMapLeaf( "Close-up of Picard’s face as Locutus", "plain" ) )
stage_directions.add( MindMapLeaf( "Panoramic view of the devastated fleet at Wolf 359", "plain" ) )
stage_directions.add( MindMapLeaf( "Enterprise maneuvering to evade the Borg", "plain" ) )
stage_directions.add( MindMapLeaf( "Tense bridge scenes as the crew works together", "plain" ) )
root.add( stage_directions )
root.display()
if __name__ == "__main__":
main()- Run
main.pyto see your my mindmap. - Modify or change this code to build YOUR OWN UNIQUE MindMap, maybe about how much you value this course! =;-)
- Finally, take your mindmap output from your main.py program's console and see if you can get it to display in Mermaid Live
- Same as last week, the week before that, and the week before that.
- Upload your code to a GitHub Project
- Submit your GitHub Project link to Canvas for this assignment.