Lesson 32 - Code Generator
LEARN
Course Content
Today
- Code Cloner Design Pattern
Design Patterns
- Capture design decisions for next time
- Reuse design choices
- Custom choices and limitations
- When to apply pattern
- Say it in code
Reusable Design Patterns
- CRUD Operations
- CRUD Test
- Data Views
- Data Views Test
- Import/Export
- Code Cloner
Book Data Relationships
If you have more that four data models draw a simple diagram
Use https://www.gliffy.com/
Superhero Data Relationships
Use https://www.gliffy.com/
Problem
- Add a new data type
- Don't repeat work
- Reduce from 1 day to 1 hour
Code Cloner Design Pattern
- Why use this pattern
- When to use code cloning
- How to steps
- What to focus on
Code Cloner - Why
- Encapsulate your design patterns
- Say it in code
- Write software to write software
- Own it and change it
Code Cloner - When
- You have files capture a design idea
- You want to make mechanical/simple changes
- Instantly generate a 90% solution
Code Cloner - How
- Select the code to leverage
- Choose the files
- Convert the files
- Integrate in structure
- Test and fix
Code Cloner - What
- Understand the choices
- Start with working code
- Understand the limitation
- Make improvements to the code generator
Version Control
- Commit before cloning
- Commit after cloning
- Commit after debugging new tests
- Don't lose any work
Create a Django Command
- Build a custom command to run the cloner
coder/management/commands/cloner.py
```python from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
print("CODE CLONER")
generate_code()
```
Invoke the cloner
bash
$ python manage.py cloner
Create the Data Model
book/models.py
python
class Note(models.Model):
chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE, editable=False)
author = models.ForeignKey(Author, on_delete=models.CASCADE, editable=False)
title = models.CharField(max_length=200)
text = models.TextField()
Select the code to leverage
- Find the closest match to your new needs
- Locate URLs, views, templates
- Clone Book --> Note
book/urls_book.py
book/views_book.py
book/tests_book.py
templates/book_add.html
templates/book_delete.html
templates/book_detail.html
templates/book_edit.html
templates/book_list.html
Choose the files
- Map the old files to new files
book/urls_book.py --> book/urls_note.py
book/views_book.py --> book/views_note.py
book/tests_book.py --> book/tests_note.py
templates/book_add.html --> templates/note_add.html
templates/book_delete.html --> templates/note_delete.html
templates/book_detail.html --> templates/note_detail.html
templates/book_edit.html --> templates/note_edit.html
templates/book_list.html --> templates/note_list.html
Convert the files
- Convert each code file using replace
python
def convert_file(f1, f2, object1, object2, class1, class2):
text = open(f1).read()
text = text.replace(object1, object2)
text = text.replace(class1, class2)
open(f2, 'w').write(text)
print(f'{f1} --> {f2}')
Convert all files
- Convert all selected files
python
def clone_code(class_name, object_name, old_class, old_object):
print(f'\n\nGenerating code \nClass: {class_name}, Object: {object_name}\n')
copyfile(f'{old_object}/urls.py', f'{old_object}/urls_{old_object}.py')
for f in file_list(old_object).split('\n'):
new_file = f.replace(old_object, object_name).replace(f'{object_name}/', f'{old_object}/')
convert_file(f, new_file, old_object, object_name, old_class, class_name)
Perform Clone Operation
- Set up the config so that it can be rerun
python
def generate_code():
class_name = "Note"
object_name = "note"
old_class = 'Book'
old_object = 'book'
clone_code(class_name, object_name, old_class, old_object)
Integrate in structure
- Debug stand-alone views
- Strip out unneeded logic
- Build desired workflow
- Simplify the code
- Improve the generator logic
Test and fix
- Start with generated tests
- Comment out all code
- Add one function in at a time
- Add specific test logic
BUILD
Demo Code
- Demo Code
- Follow along with my source code
- Clone my repo and edit the code
Final Project
- Due on December 3
- Requirements for Projects 10, 11, 12, 13, 14
- Partial Credit will be given