David France
Introduction – Self-Assessment
When I first enrolled at SNHU, I thought I would cruise to a degree while learning a few cool things along the way. It has proven to be much more challenging than just showing up, with a near non-stop flow of reading, learning, communication, design, writing, and coding, all while working in a remote environment. Along the way, I have developed a variety of skills in computer science, as well as expanded my knowledge of communication and collaboration.
In respect to computer science, I have learned both theoretical and practical skills, as well as seeing how they blend. I have learned about the software development lifecycle, particularly as it applies to Agile methodology, both in theory and in practice. Each week is like a new sprint. Other notable lessons include object-oriented programming, the importance of clean data, and the ongoing concern of security. When it comes to developing code, I’ve gained experience with both common and custom data structures and a variety of common algorithms which have allowed me to effectively develop my own when necessary. While my following project is in Python, I have gained a solid grounding in C++ and Java; and I would be comfortable learning any new language. I have also had the opportunity to work in a variety of SQL and NoSQL databases.
In terms of collaborating in a team environment and communicating with stakeholders, I’ve worked the past 20 years in the casino and restaurant industries, including the last ten at a Forbes Five Star resort in Las Vegas. Not only have I had to work as a team in a wide variety of circumstances, including supervising games where millions of dollars won and lost in a matter of minutes, I have had the chance to develop communication skills across language and cultural barriers. I have given presentations to top company executives and had to coach employees who have been in the business decades longer than me. During Covid, I had the rare opportunity to tell guests with hundreds of thousands of dollars in play to please pull their mask up. This is all led to me understanding the importance of clear communication while taking the audience into consideration.
The following is my final project for the CS-499 capstone project. I will summarize the project in the overview, provide a code review, then go over each section in turn.
Contents
Overview
For this project we had to do three enhancements on previous work, covering the following categories:
- Software design and engineering
- Algorithms and data structure
- Databases
I chose to do all three enhancements on the same artifact – a dashboard for the fictional company Grazioso Salvare that allows their team members to interact with a database from the Austin Animal Shelter, which holds information on the animals in their system. The dashboard was created with a model-view-controller design pattern using MongoDB as the model, a custom Python class -animalshelter - as the controller, and a Jupyter Notebook file as the view.
I chose to use this artifact because it only had read functionality, so I had the opportunity to add create, update, and delete functions. There was also room for improving the view by adding custom filters and the speed by manipulating the database and adding an algorithm to automatically sort animals on create or update. Overall, it gave me the opportunity to incorporate security, input control, data structure, and code design into a polished final product.
In the next section, you will see the code files pre- and post-enhancements. This is followed by a code review conducted prior to starting the work, including details for each enhancement. For each of the three categories, I will go over what changes I made and how those changes helped me meet the following course outcomes:
- Employ strategies for building collaborative environments that enable diverse audiences to support organizational decision making in the field of computer science
- Design, develop, and deliver professional-quality oral, written, and visual communications that are coherent, technically sound, and appropriately adapted to specific audiences and contexts
- Design and evaluate computing solutions that solve a given problem using algorithmic principles and computer science practices and standards appropriate to its solution, while managing the trade-offs involved in design choices (data structures and algorithms)
- Demonstrate an ability to use well-founded and innovative techniques, skills, and tools in computing practices for the purpose of implementing computer solutions that deliver value and accomplish industry-specific goals (software engineering/design/database)
- Develop a security mindset that anticipates adversarial exploits in software architecture and designs to expose potential vulnerabilities, mitigate design flaws, and ensure privacy and enhanced security of data and resources
Following that, I have a video showcasing the changes in the dashboard, along with a quick review of the code. Closing out each section will be a short reflection on what I learned and what challenges I faced in completing the enhancement.
The following videos detail the Grazioso Salvare Dashboard when I first completed it for the previous class (3:00) and after all enhancements were completed (5:13):
Files
Each enhancement was performed on the same artifact. Here are the original code files, followed by the files after all enhancements. Each section goes over what I specifically changed for that enhancement.
Orginal files:
animalshelter.py
Grazioso Salvare Dashboard
Files after enhancement:
animalshelter.py
dash_css.py
Grazioso Salvare Dashboard
Code Review
Video covering my code review prior to making any changes, finishing with a review of the planned enhancements:
Enhancement overview PowerPoint
Software Engineering and Design
For this enhancement, I added a login/logout section, dropdown filters for refining the data in the view, and an ‘Advanced Options’ section with a ‘Delete Animal’ button. This all works towards improving the use and functionality of the dashboard for the Grazioso Salvare team.
This involved creating a MongoDB collection for users and a separate database for salt values, then inserting qualified users and their associated read/write permissions by first salting, then hashing the strings. The login and advanced options also included creating check_user() and check_permission() methods in animalshelter.py for security checks. Finally, a backup database was created to hold deleted animal documents to save inattentive users from their mistakes. This enhancement helped me to meet the following course outcomes:
Use well-founded techniques, skills, and tools for implementing computing solutions that deliver value and accomplish industry-specific goals
- Added login/logout buttons to the dashboard.
- Added login and logout callbacks in grazioso_salvare_dashboard.ipynb.
- Added check_user() method to animalshelter.py to check if user has permission to login.
- Created ‘Users’ collection in database.
- Used hashlib library to add in username/password pairs and their associated read/write permissions. Strings were salted, then hashed using hashlib’s SHA-256 algorithm.
- Added check_permission() method to animalshelter.py to check a user’s read/write permission to access ‘Advanced Options’.
- Provided dropdowns for filtering to limit user input.
Develop a security mindset to mitigate design flaws and ensure privacy and enhanced security of data and resources
- Salting and hashing username/password pairs protects the stored values even if they are accessed.
- Principle of least privilege means only users with read/write access can make changes to the database.
- Creating methods for checking users and permissions prevents unauthorized access.
- Limiting user input on the filters guards against injection attacks.
Build collaborative environments that enable diverse audiences to support organizational decision making
- Improved functionality of dashboard means Grazioso Salvare employees can better do their jobs.
- Improved comments and naming conventions in code so anyone can jump in and know what is going on.
Design, develop, and deliver professional-quality communication
- Created written and video narratives to communicate changes.
Video review of enhancements and code:
The process of enhancing/modifying the artifact was an interesting one. I felt like I was both doing things I already knew, but also learning new things the whole time. On the one hand, adding HTML elements and creating callbacks are something I’ve done, but it seems like it’s never that simple. For instance, lining up the filter dropdowns took longer than expected to find the syntax that applies to a Dash App HTML component. I also got side-tracked with the login function, as I found a few different good options, including Dash App Enterprise, dash_bootstrap_components, and dash_mantine_components. They all proved to not work the way I wanted, so I ended up just creating the whole thing from scratch. In the end, I was happy with the experience of having to figure out these solutions, particularly creating my own security for the login. I know enterprise solutions exist, but it was nice to go through the exercise for myself.
Data Structures and Algorithms
For this enhancement I focused on improving the speed of the dashboard. I accomplished this by improving the dashboard the following ways:
- Created ‘rescue_type’ category for dogs in MongoDB - this is one of the main functions of the dashboard, so was a focus for this enhancement. For the current database, this meant updating dogs that currently meet the criteria for each rescue type, accounting for the fact that some dogs are in more than one category. More importantly, it meant creating an algorithm in animalshelter.py to automatically update dogs that qualify, or are disqualified, as they are inserted or updated within the database. The previous method included searches across all animals on multiple categories for MongoDB, this simplified the search to just ‘rescue_type’ and ‘age_upon_outcome_in_weeks’.
- Improved initial load time – I updated the initial database query to find only dogs, rather than the entire set, to populate the data table. Dogs are the focus of the business, but users can then load additional animals, or the entire set, if they like.
- Created indexes in MongoDB AAC database for the filter categories – this was a database administrator task to make the most common queries more efficient.
These changes helped me to meet the following course outcomes:
Design and evaluate computing solutions to solve a problem:
- Created __check_rescue_type() private method in animalshelter.py to solve the problem of automatically updating animals as they are inserted and deleted.
- Implemented in insert() method – simple call of the __check_rescue_type() method on the animal being inserted if it is a dog.
- Implemented in update() method – designed algorithm to handle if the animal ID has changed, if only one animal is being updated using animal ID, or if many animals are being updated. __check_rescue_type() is designed to both add and remove rescue_type classifications, of updated dogs as necessary.
- Time complexity of rescue animal search went from O(n) to O(1). The speed of loading all three rescue types one by one was decreased by .47 seconds for a 10,000-animal database.
- Updated initial load of database into the dashboard to solve the problem of a long initial load time.
- Created indexes in MongoDB database to enhance efficiency of find() method.
Use well-founded techniques:
- Separated check for rescue type into its own private method.
- It doesn’t need to be accessed outside of animalshelter.py.
- Allows for use in both insert() and update() methods.
- Implemented __check_rescue_animal() in update() method to efficiently check all the update possibilities using if-elif-else clause.
Building collaborative environments:
- Increasing the responsiveness of the database to the data filtering options makes it easier for Grazioso Salvare employees to do their work.
- Focused on improving comments within animalshelter.py and grazioso_salvare_dashboard.ipynb in order to allow anyone to jump in and understand the code.
Professional communication:
- Increased quality of communication within code with the use of headers, comments, and descriptive naming conventions.
- Communication within narrative through both written and oral/screencast. Improved layout by using bullets to accentuate important points.
Video review of enhancements and code. Skip to the end for a side-by-side comparison of speed before and after enhancement:
Upon reflection, this was a successful enhancement in terms of both implementing skills I have and developing new ones. I was able to improve the controller and view classes as I said I would and the result was improved loading times, particularly for the rescue type radio buttons. I was also able to do incremental programming by creating a Jupyter Notebook for testing, allowing me to ensure that all my changes to animalshelter.py worked as intended. I developed skills in video editing and continued working on improving my code readability and screen casting/code review. I wouldn’t say I faced any major challenges that I wasn’t able to figure out, which made me feel confident in my ability to deliver on what I say I will.
Databases
For this enhancement, I completed the CRUD functionality of the dashboard by adding ‘Create Animal’ and ‘Update Animal’ buttons. While seemingly simple, this involved controlling input, adding input validation, adding in the calculated fields on insert, and properly updating calculated fields on update. Some of the methods bleed over into algorithms and data structures as well, specifically the structure of the documents in MongoDB, and adding in calculated fields to each new or updated document. This enhancement helped me to meet the following course outcomes:
Use well founded techniques, skills, and tools in computing practices for the purpose of implementing computer solutions that deliver value:
- Used data validation to ensure only quality data was being inserted/updated.
- Created dropdown menus with pre-selected values for ‘animal_type’, ‘breed’, ‘color’, ‘outome_subtype’, ‘outcome_type’, and ‘sex_upon_outcome’
- Used SingleDatePicker() and private method __check_date() to ensure user has to select a date for birthdate.
- Used Nominatim class from geopy.geocoder library to obtain ‘latitude’ and ‘longitude’ coordinates from address, with a map so the user can confirm their entry. This included properly citing OpenStreetMaps as the source in the attributes of the map.
- Created check_address() callback to allow users to confirm their address on a map.
- Created name_validation() method in animalshelter.py to ensure ‘name’ does not exceed 15 characters, and only contains letters, ‘*’, ‘-‘, or ‘ ‘ characters.
- Created __animal_dict() method in the dashboard notebook to create a dictionary based on insert/update values to be passed to AnimalShelter() class. This method is used in both create_animal() and update_animal() callbacks.
- Created private methods in animalshelter.py to fill in the fields that can be calculated.
- __age() - returns a formatted age string in the form of ‘1 day’, ‘2 weeks’, ‘3 years’, etc.
- __age_in_weeks() – returns a float representing the age in weeks calculated from the provided DOB to today.
- __next_row() – returns highest row value + 1 for newest animal.
- __next_id() – returns the highest animal_ID value + 1.
- __add_fields() – adds calculated fields to animal dictionary to be inserted. This ensures all fields are populated and are in the correct structure for the Dash App data table.
- Updated insert() method to add all calculated fields prior to checking if animal is a rescue type.
- Updated update() method to check if a DOB is being updated and doing the appropriate updates if yes.
Develop a security mindset:
- Only users with read/write permissions can access the ‘Advanced Options’ on the dashboard, showing the use of the principle of least privilege.
- Data control and validation protects against injection attacks.
Building collaborative environments:
- Creating a dashboard with complete CRUD functionality allows for all team members of Grazioso Salvare to work with the most up-to-date information available from the database.
- ‘Advanced Option’ are only shown when read/write users click on the ‘Show Advanced Option’ button. Further, only one ‘delete’, ‘insert’, or ‘update’ view is available at a time, based on the selected radio button. This declutters the view for those just using the read functionality of the dashboard.
- Ensured to comment the code and use descriptive naming to make it easier for other developers to work with my code.
Professional communication:
- Used both narrative and screencast to clearly highlight enhancement using both written and oral/visual techniques
Video covering changes to the dashboard, followed by the code changes:
In reflecting on my experience with this enhancement, I was able to continue to learn about Dash Apps and Python, while employing many of the techniques I’ve learned while at SNHU. In Dash, I learned about the SingleDatePicker() input option, which allows for picking a date from a calendar for input. In Python, I learned about the Nominatim class from geopy.geocoders, which allows for returning map-data from an address. Within that scope, I also learned how to add an attribute to a dash-leaflet map to properly cite OpenStreetMap. These Python elements helped me to ensure strong data validation on input for the MongoDB database.
My biggest challenge for the enhancement came when I thought I had finished and just had the screencast to wrap up. I thought I had sufficiently tested my dashboard, but as it turned out, I had not done as thorough job as I had thought. My code was riddled with small bugs, and I had to spend extra time playing whack-a-mole trying to get everything in order. I already knew the importance of testing, but this hammered home how critical it is to be thorough and run through all scenarios before declaring the task ‘done’.