├── .editorconfig ├── .github └── pull_request_template.md ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── general │ └── clean-code.md ├── git │ ├── branch-naming-convention.md │ ├── branching-strategy.md │ ├── code-review-checklist.md │ ├── pull-request-best-pratices.md │ ├── pull-request-guidelines.md │ ├── pull-request-template.md │ ├── smart-commit.md │ └── tagging.md ├── introduction.md ├── java │ ├── classes.md │ ├── effective-java.md │ ├── functions.md │ ├── interfaces.md │ ├── logging.md │ ├── packages.md │ ├── tools.md │ └── variables.md ├── javascript │ ├── classes.md │ ├── functions.md │ ├── js-general-guidelines.md │ └── variables.md ├── nosql │ └── documentdb │ │ ├── many-to-many-relationship.md │ │ ├── naming-conventions.md │ │ ├── one-to-many-relationship.md │ │ └── one-to-one-relationship.md ├── python │ ├── classes.md │ ├── docstrings.md │ ├── environment-and-dependency.md │ ├── exceptions.md │ ├── files.md │ ├── functions.md │ ├── general.md │ ├── logging.md │ ├── project-structure.md │ ├── testing.md │ ├── tools.md │ └── variables.md ├── rdbms │ └── naming-convention.md └── rest-api │ ├── delete.md │ ├── get.md │ ├── headers.md │ ├── naming-convention.md │ ├── patch.md │ ├── post.md │ ├── put.md │ ├── security.md │ ├── status-code.md │ └── versioning.md ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src ├── css │ └── custom.css └── pages │ ├── index.js │ └── index.module.css ├── static ├── clean-code │ ├── page-1.png │ ├── page-2.png │ ├── page-3.png │ └── page-4.png ├── img │ ├── icon.png │ ├── icons │ │ ├── icon-128x128.png │ │ ├── icon-144x144.png │ │ ├── icon-152x152.png │ │ ├── icon-192x192.png │ │ ├── icon-384x384.png │ │ ├── icon-48x48.png │ │ ├── icon-512x512.png │ │ ├── icon-72x72.png │ │ └── icon-96x96.png │ └── lf_logo.svg ├── index.html └── manifest.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | quote_type = single 12 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Provide a general summary of your changes in the Title above. 2 | 3 | ## Description 4 | 5 | Describe your changes in detail. 6 | 7 | ## Motivation, Context and link to the ticket 8 | 9 | - Why is this change required? What does it do? 10 | - If it fixes an open issue, please link to the issue here. 11 | 12 | ## Related PRs 13 | 14 | Link to related pull requests. 15 | 16 | ## How Has This Been Tested? 17 | 18 | - Please describe in detail how you tested your changes. 19 | - Include details of your testing environment, and the tests you ran to 20 | - see how your change affects other areas of the code, etc. 21 | 22 | ## Screenshots (if appropriate): 23 | 24 | ## Type of change 25 | 26 | What types of changes does your code introduce? Put an `x` in all the boxes that apply: 27 | 28 | - [ ] Update to existing guideline(s) 29 | - [ ] New guideline(s) 30 | - [ ] Miscellaneous change 31 | - [ ] Docusaurus updates (new plugins, bug fix, etc.) 32 | 33 | ## Checklist: 34 | 35 | Go over all the following points, and put an `x` in all the boxes that apply. 36 | If you're unsure about any of these, don't hesitate to ask. Your team members are there to help! 37 | 38 | - [ ] My code follows the code style of this project. 39 | - [ ] My change requires a change to the documentation. 40 | - [ ] I have updated the documentation accordingly. 41 | - [ ] I have read the **CONTRIBUTING** document (if applicable) 42 | - [ ] I have added tests to cover my changes. 43 | - [ ] OR no tests update required. 44 | - [ ] One or more required reviews requested. 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # production 5 | /build 6 | 7 | # generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | .vscode/* 23 | 24 | package-lock.json 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 - present Leapfrog Technology 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Leapfrog Technology Coding Guidelines 2 | 3 | https://coding-guidelines.lftechnology.com 4 | 5 | Coding guidelines commonly followed at [Leapfrog Technology](https://www.lftechnology.com/). 6 | 7 | ## Contributing 8 | 9 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 10 | 11 | ### Installation 12 | 13 | ``` 14 | $ yarn 15 | ``` 16 | 17 | ### Development 18 | 19 | ``` 20 | $ yarn start 21 | ``` 22 | 23 | This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. 24 | 25 | ### Build 26 | 27 | ``` 28 | $ yarn build 29 | ``` 30 | 31 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 32 | -------------------------------------------------------------------------------- /docs/general/clean-code.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: clean-code 3 | title: Clean Code Cheat Sheet 4 | --- 5 | 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | 8 | #### [Original Source](https://www.planetgeek.ch/wp-content/uploads/2014/11/Clean-Code-V2.4.pdf) 9 | 10 | Docusaurus with Keytar 11 | 12 | Docusaurus with Keytar 13 | 14 | Docusaurus with Keytar 15 | 16 | Docusaurus with Keytar 17 | -------------------------------------------------------------------------------- /docs/git/branch-naming-convention.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: branch-naming-convention 3 | title: Branch Naming Convention 4 | sidebar_label: Branch Naming Convention 5 | --- 6 | 7 | #### The following convention should be followed: 8 | 9 | * Branch name should exactly match with the corresponding JIRA ticket that you will be working on. `-` 10 | * FHF-100 11 | * DEL-200 12 | 13 | * If there's no JIRA or project management tool in use, the branch naming strategy should be feature specific. 14 | * upgrade-php 15 | * add-button-tooltip 16 | -------------------------------------------------------------------------------- /docs/git/branching-strategy.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: branching-strategy 3 | title: Branching Strategy 4 | sidebar_label: Branching Strategy 5 | --- 6 | 7 | #### Main Branches: 8 | 9 | * master (Production) 10 | * dev (Development) 11 | * qa (QA) 12 | * uat (UAT) 13 | * staging (Staging) 14 | 15 | #### Supporting Branches: 16 | 17 | * Feature branches 18 | * Release branches 19 | * Hotfix branches 20 | 21 | #### The following convention should be followed: 22 | 23 | * Every feature branch should be a branch of `dev` and should be merged to `dev` after PR is reviewed. 24 | * The main branches should be created as required and should follow the hierarchy should be `master`<-`uat`<-`qa`<-`dev`. 25 | * Every feature, task is done in a separate branch named according to the JIRA issue name. 26 | * Any critical bug after production release is done via hotfix branches. It is branched off from `master` and merged back to master and dev after it’s done. 27 | -------------------------------------------------------------------------------- /docs/git/code-review-checklist.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: code-review-checklist 3 | title: Code Review Checklist 4 | sidebar_label: Code Review Checklist 5 | --- 6 | 7 | #### List: 8 | 9 | * Description Confirmed? 10 | * The code meets the business requirements 11 | * Comments are comprehensible and add something to the maintainability of the code 12 | * Comments are neither too numerous nor verbose 13 | * Types have been generalized where possible 14 | * Parameterized types have been used appropriately 15 | * Exceptions have been used appropriately 16 | * Repetitive code has been factored out 17 | * Frameworks have been used appropriately – methods have all been defined appropriately 18 | * Command classes have been designed to undertake one task only 19 | * Unit tests are present and correct 20 | * Common errors have been checked for 21 | * Potential threading issues have been eliminated where possible 22 | * Any security concerns have been addressed 23 | * Performance was considered 24 | * The functionality fits the current design/architecture 25 | * The code is unit testable 26 | * The code does not use unjustifiable static methods/blocks 27 | * The code complies to coding standards 28 | * Logging used appropriately (proper logging level and details) 29 | * The code does not reinvent the wheel 30 | * The code does not have any side effect on existing functionality 31 | 32 | 33 | ##### References: 34 | 35 | Code Review Checklist -------------------------------------------------------------------------------- /docs/git/pull-request-best-pratices.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: pull-request-best-pratices 3 | title: Pull Request Best Practices 4 | sidebar_label: Pull Request Best Practices 5 | --- 6 | 7 | #### Best Practices: 8 | 9 | * Pull Request should atleast be reviewed by 1 person before merging it to the base branch. 10 | * Only comment author can resolve comment – if code was corrected or after discussion author decides to fix it. 11 | * Don’t mention the same problem many times. Don’t bloat the code, say it once and ask to fix everywhere. 12 | * If there are pending, not resolved comments, the assignee is a code author who should fix or comment back. 13 | * If there are discussions commented by the code author, the assignee is reviewer, who should continue a discussion or resolve comments and approve. 14 | * Use labels to mark what actions should be next – e.g. `needs review`, `Reviewed By... ` etc. 15 | * Provide details/screenshots about what has been changed. 16 | -------------------------------------------------------------------------------- /docs/git/pull-request-guidelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: pull-request-guidelines 3 | title: Pull Request Guidelines 4 | --- 5 | 6 | # Generic Pull Request Guidelines 7 | 8 | ## Consider the following points while submitting and reviewing a pull request. 9 | 10 | **1. Small and focused changes:** Break down the code into small and manageable units. 11 | This allows for focused work and thorough analysis, making it easier to identify issues and provide constructive feedback. 12 | 13 | **2. Review for Functionality:** Verify that the code accomplishes its intended purpose and that it follows the requirements and specifications. Ensure that the code is efficient, maintainable, and scalable. 14 | 15 | **3. Check Coding Standards:** Evaluate the code against established coding standards and style guidelines. Look for consistency in naming conventions, code formatting, documentation, and error handling practices. 16 | 17 | **4. Test Coverage:** Assess the presence and quality of unit tests. Verify that the code is adequately covered by tests and that the tests provide meaningful assertions and cover edge cases. 18 | 19 | **5. Performance and Efficiency:** Evaluate the code for performance bottlenecks, resource consumption, and potential scalability issues. Focus on optimizations and improvements if necessary. 20 | 21 | **6. Security Considerations:** Review the code for potential security vulnerabilities such as injection attacks, data exposure, or authentication/authorization flaws. Encourage best practices like input validation, proper encryption, and handling of sensitive information. 22 | 23 | **7. Follow PR standard practices:** Use clear and descriptive titles. Provide detailed description of the changes and include screenshots and documentations. 24 | 25 | ## Reviewers Guideline 26 | 27 | * Open Mindset 28 | * Acceptive 29 | * Open to enhancements/improvements 30 | * Go over the ticket description to understand what the PR is for 31 | * Solution-driven comments over criticisms 32 | * Knowledgeable comments 33 | * Suggestive commenting 34 | * Be polite and respectful 35 | * Don’t just comment for the sake of it 36 | 37 | ## Additional Role of Team Leads and Code Owners 38 | 39 | **1. Performance and Scalability:** Consider the performance implications of the code changes. Assess whether the code might introduce bottlenecks or negatively impact system performance. Ensure that scalability concerns are addressed if applicable. 40 | 41 | **2. Feature Breakdown:** Make sure the features and PR are broken into meaningful chunks during sprint planning. 42 | 43 | **3. Architecture and Design:** Check if the code changes align with the overall system architecture and design. Ensure that the proposed changes fit into the existing structure and don't introduce architectural conflicts. 44 | 45 | **4. Ownership:** Ultimately, the code owner or a team lead may need to make a decision on whether to approve, request changes, or reject the PR. This decision should be based on the code's quality, alignment with project goals, and any necessary improvements. 46 | 47 | 48 | ## Things to Keep in Mind 49 | 50 | 1. Granularization of tasks 51 | 1. Small biteable size of code 52 | 1. Easy portability - Cherry-pick 53 | 2. Incremental effect analysis - Easy recovery 54 | 3. Easy comprehension 55 | 2. Learning process for the reviewer and reviewee 56 | 3. Alignment to git strategy 57 | * [Git flow](https://danielkummer.github.io/git-flow-cheatsheet/) 58 | 5. [Clean Code](https://github.com/SaikrishnaReddy1919/MyBooks/blob/master/%5BPROGRAMMING%5D%5BClean%20Code%20by%20Robert%20C%20Martin%5D.pdf) 59 | 6. Strictly follow design principles. 60 | * DRY 61 | * KISS 62 | * YAGNI 63 | * SOLID 64 | 7. Conventions 65 | * [Naming conventions](https://github.com/kettanaito/naming-cheatsheet) 66 | 8. Proper Use of inbuilt functions 67 | * Only wrap exceptional logic in try catch 68 | * Avoid unnecessary else statements 69 | * Consistent return 70 | 9. Use of Packages 71 | * Consult your team to decide if a package is feasible for the project 72 | * Freeze package names for major versions 73 | 10. Keep an eye out for functional and object-oriented concepts. 74 | 11. Component-based development 75 | * Use of non unique ids. Component composition rule violation. 76 | * Keep reusability in mind 77 | * Avoid side effects 78 | * Schema driven development 79 | 80 | ## Pull Request Description 81 | 82 | Please note a few things while opening your PRs. Add the following things to your PR's description. 83 | 84 | * Description - A short description of the feature for which the PR is opened. 85 | * Summary of changes - Changes in the source code which the PR comprises. 86 | * Route - The route from where we can view the feature being added in this PR. 87 | * Screenshot - A screenshot of the added feature. 88 | * Deployment notes - Any environment-specific changes need to be made in terms of infrastructure. Eg: Seeding of tables, the addition of secrets to the secrets manager, migration of tables, etc. 89 | 90 | Also, make sure to add some reviewers and assign yourself as an Assignee. 91 | 92 | ### Best Practices: 93 | 94 | * Pull Request should atleast be reviewed by 1 person before merging it to the base branch. 95 | * Only comment author can resolve comment – if code was corrected or after discussion author decides to fix it. 96 | * Don’t mention the same problem many times. Don’t bloat the code, say it once and ask to fix everywhere. 97 | * If there are pending, not resolved comments, the assignee is a code author who should fix or comment back. 98 | * If there are discussions commented by the code author, the assignee is reviewer, who should continue a discussion or resolve comments and approve. 99 | * Use labels to mark what actions should be next – e.g. `needs review`, `Reviewed By... ` etc. 100 | * Provide details/screenshots about what has been changed. 101 | 102 | ### References 103 | 104 | * [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) 105 | -------------------------------------------------------------------------------- /docs/git/pull-request-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: pull-request-template 3 | title: Pull Request Template 4 | --- 5 | 6 | # Generic Pull Request Template 7 | 8 | Add a file called `pull_request_template.md` to the root directory of your repository. Take a look at number of ways you can do this in GitHub. https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository 9 | 10 | ## Title 11 | 12 | ‍‍‍Provide a general summary of your changes in the title. 13 | 14 | ## Description 15 | 16 | Describe your changes in detail. Link to the related issue ticket. 17 | 18 | ## Context 19 | 20 | Why is this change required? What problem does it solve? 21 | 22 | ## Related PRs 23 | 24 | Link to related pull requests 25 | 26 | ## How has this been tested? 27 | 28 | Please describe in detail how you tested your changes. Include details of your testing environment, and the tests you ran. 29 | 30 | ## Screenshots 31 | 32 | Add screenshots or video if applicable. 33 | 34 | ## Type of Change 35 | 36 | What types of changes does your code introduce? Put an x in all the boxes that apply: 37 | 38 | - [ ] Bug fix (non-breaking change which fixes an issue) 39 | - [ ] New feature (non-breaking change which adds functionality) 40 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 41 | - [ ] Documentation 42 | - [ ] Tests 43 | 44 | ## Sanity Checklist 45 | 46 | Go over all the following points, and put an x in all the boxes that apply. If you're unsure about any of these, don't hesitate to ask. Your team members are there to help! 47 | 48 | - [ ] My code follows the code style of this project. 49 | - [ ] I have updated the documentation accordingly. 50 | - [ ] I have added tests to cover my changes. 51 | - [ ] One or more required reviews requested. 52 | - [ ] Any dependent changes have been merged and published in upstream modules. 53 | - [ ] I have updated and verified the changes end-to-end and related documentation have been updated. 54 | -------------------------------------------------------------------------------- /docs/git/smart-commit.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: smart-commit 3 | title: Smart Commit 4 | sidebar_label: Smart Commit 5 | --- 6 | 7 | Smart commits allows a team to perform actions on JIRA issues from a single commit. Users can enter the issue key and the desired action such as time tracking or closing an issue. 8 | 9 | #### Commands used in Smart Commit messages: 10 | 11 | * `#comment`: Adds a comment to a JIRA issue. `ISSUE_KEY #comment ` 12 | * `#time`: Records time tracking information against a JIRA issue. 13 | * `#`: Moves the JIRA issue to a particular workflow state. 14 | 15 | #### Examples: 16 | 17 | - git commit -m "FHF-34 #time 30m Update modal design" 18 | - git commit -m "DEL-101 #time 4h 30m Fix null pointers #comment Fixed code #resolve" 19 | 20 | 21 | Learn more about smart commits from the [official docs](https://support.atlassian.com/bitbucket-cloud/docs/use-smart-commits/). 22 | 23 | 24 | :::tip 25 | Want to add the branch name to your commit automatically? Check out [smart-commit](https://github.com/sbimochan/smart-commit)! 26 | ::: 27 | -------------------------------------------------------------------------------- /docs/git/tagging.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: tagging 3 | title: Tagging 4 | sidebar_label: Tagging 5 | --- 6 | 7 | Semantic Versioning is all about releases, not builds. This means that the version only increases after you release. 8 | 9 | Following are the standards that should be followed while tagging releases: 10 | 11 | * Every release should have a tag. 12 | * You can tag from any long running branch ( dev, qa, staging, master). However, we strictly follow tagging from master branch. 13 | * Tag name should follow the *major.minor.patch_* naming conventions as suggested by Semantic Versioning 14 | * The tag for a version is in "X.Y.Z" format where, 15 | * Z is hot-fixes and patch release. If the release includes hot-fixes and patches, we increment this value by 1. Example : "2.7.1", "2.7.2" 16 | * Y includes major feature releases. If the release includes a major feature which is going to production for the first time we increase this value by 1. Example: "2.8.0", "2.9.0" 17 | * X is increased when there is a major change in the system which affects the entire application flow or UI/UX(flow) of a system. Example: "3.0.0", "4.0.0" . -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: introduction 3 | title: General Coding Guidelines 4 | --- 5 | 6 | * Firstly, it's recommended to use a static code analysis tools to analyze the code before it's pushed to the version control. For eg: eslint, tslint, pylint, codeclimate, sonar etc. Development Team should identify corresponding tool for their tech stack and use it to follow community wide general coding standards and avoid general bad practice. 7 | 8 | * No hard coding, use constants/configuration values instead of hard-coding literal values. 9 | 10 | * Do not store config as constants in the code. Use separate config files for storing application credentials such as passwords, access key etc. Make sure you add this file in .gitignore file. 11 | 12 | * Group similar values under enums, constant groups or similar data structures depending on what the language allows. 13 | 14 | * Avoid code duplication (DRY). If the same code needs to be reused in multiple places, create a extract a common function instead. 15 | 16 | * While writing code make sure it doesn't violate SRP (Single Responsibility Principle). To be more specific take care of the following: 17 | 18 | * A function/method should do only one task. 19 | 20 | * A class should have only one concern or should take care of only one aspect. 21 | 22 | * Avoid having more than 3 parameters in a function/method. 23 | 24 | * Avoid creating God classes or utils that is capable of doing every thing from string manipulation to checking if user is authored. This is a big NO. 25 | 26 | * Follow separation of concerns principles properly, and identify what type of code should go in which layer or tier eg: What type of code should be written in Model, View, Service and Controller etc. 27 | 28 | * Write pure functions where ever possible. It keeps the code more understandable and deterministic, plus it helps to avoid unexpected run time issues due to mutation. 29 | 30 | * If your project is following OOP approach, follow it precisely depending upon the language specific best practices. If the project is following a FP (Functional Programming) approach, use it's best practices. Don't try to mix multiple paradigm, which results in more chaos and confusion in the code. 31 | 32 | * Avoid unnecessary else blocks as much as possible for better readability and cleanliness. 33 | 34 | ```js 35 | // Bad practice 36 | function nullIfEmpty(value: any) { 37 | if (typeof value === 'string') { 38 | return value.trim() === '' ? null : value; 39 | } else { 40 | return value; 41 | } 42 | } 43 | 44 | // Good practice 45 | function nullIfEmpty(value: any) { 46 | if (typeof value !== 'string') { 47 | return value; 48 | } 49 | return value.trim() === '' ? null : value; 50 | } 51 | ``` 52 | 53 | * Avoid nested if blocks, multiple if blocks. No pyramid of doom. 54 | 55 | * Break down or refactor code with complexity into multiple smaller chunks i.e functions/methods. 56 | 57 | * DocBlocks / Doc comments – Add doc blocks for each and every function, class, interface, etc to clearly mention what they do. Docblocks also should mention the parameter types or return types clearly. 58 | 59 | * Class level documentation, document public functions and interface. Follow language specific documentation standard. 60 | 61 | * Also, make sure you write doc blocks, comments etc in proper english. Re-check your sentences, to ensure they're typo free. 62 | 63 | * Different languages have different standards for doc blocks. Follow the language specific standard for doc blocks. For examples: 64 | 65 | ```js 66 | /** 67 | * Hit the twilio API to send notifications. 68 | * 69 | * @param {NotificationPayload} payload 70 | * @returns {Promise} 71 | */ 72 | function sendNotification(payload: NotificationPayload): Promise { 73 | return twilioClient.sendMessage(payload); 74 | } 75 | ``` 76 | 77 | ```py 78 | def rollback(id=None): 79 | ''' 80 | Deployment rollback to the previous build, or 81 | the build identified by the given id. 82 | ''' 83 | 84 | (_, current_path) = setup_remote() 85 | history = load_history() 86 | 87 | # If the current build in the history is not set yet or 88 | # there aren't any previous builds on the history 89 | # rollback is not possible. 90 | if not history['current'] or not history['builds']: 91 | remote_info('Could not get the previous build to rollback.') 92 | 93 | return 94 | ... 95 | ``` 96 | 97 | * Avoid re-inventing the wheel. Use framework features, or utilities provided by libraries wherever possible instead of writing custom code. 98 | 99 | * Don't hard-code text data/content in the code itself, instead put text content/messages in the internationalization files and use the content identifiers instead. 100 | 101 | * Each Components, Classes, or Interfaces should be written in their own file. And the filename should be named same as it's identifier name. (This could be an exception for python). 102 | 103 | * Follow language specific naming convention. 104 | 105 | * Use PascalCase naming convention for Components, Classes, or interfaces, enums, or other custom types. 106 | 107 | * Use camelCase for naming functions, variables etc. 108 | 109 | * Use snake_case for naming database columns, table names etc. 110 | 111 | * Use **CAPITAL_CASE_WITH_UNDERSCORES** for defining constants eg: const **PAGINATION_MAX_ROWS = 15**. 112 | 113 | * Classes/Interfaces/Components/Services should be **named as a noun (singular)** as they represent a real world entity. 114 | 115 | * For instance: **Person, PersonList, User, ArrayAggregator, PerformanceEvaluator, SourceAnalyzer, Inspector, TaskService, UserServiceTest** etc. 116 | Avoid prefixing them with verbs or naming them as plural entities. For example bad class names could be: **GetUser, Users, Todos, Listeners, GetUserById** etc. 117 | Functions or methods should be named as verbs or actions as they represent actions. So, function name should clearly say what that function does. 118 | Good function names: **getPersonList, fetchUsers, getCurrentUser, removeTodoItems, initialize, clear, flush, activate, isActive(), shouldNotify()** 119 | Bad function names are those that isn't meaningful to the task it does. 120 | 121 | * A function should do one thing and should be named accordingly. **SRP(Single Responsibility Principle)** also applies here. If you have broken down the function following SRP then there won't be a function such as: **getUserByIdAndActivateItAndLogin**, **checkPeopleAndArchiveThem** (bad practice). 122 | 123 | * All the releases should be properly tagged in git. 124 | 125 | * Follow Major, Minor and Patch format. and include information about Production and Dev release. 126 | 127 | * Patch - Bug fixes 128 | 129 | * Minor - Feature additions/enhancements 130 | 131 | * Major - Change in business logic. 132 | 133 | * All the releases should be identified as pre-release in git if they are not released for production. 134 | 135 | * Follow Gitflow. 136 | 137 | * Sanity checklist document should be present. 138 | 139 | * Consistent Relational Operators: 140 | 141 | * Use relational operators either `>=` / `<=` or `>` / `<` consistently in the entire codebase. 142 | 143 | * Example: In some places, there is `>=256 && <=512` and in other place there is `>255 && <511`. 144 | 145 | * Why? Lesser cognitive burden, enforce consistency and avoid confusion. 146 | -------------------------------------------------------------------------------- /docs/java/classes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: classes 3 | title: Classes 4 | sidebar_label: Classes 5 | --- 6 | 7 | #### The following convention should be followed for `class` naming: 8 | 9 | * Class names are generally nouns or nouns phrases, in title-case with the first letter of each separate word capitalized or **UpperCamelCase**. e.g. 10 | - **LeaveController** 11 | - **EmployeeRepository** 12 | - **AttendanceRecord** 13 | 14 | * Test classes are named starting with the name of the class they are testing, and ending with Test. For example, 15 | - **LeaveControllerTest** 16 | - **AttendanceRecordTest** 17 | 18 | * Class name should be designed with single responsibility principle, self descriptive and self documenting. 19 | 20 | * Classes on various application layers should be suffixed with terms as given below 21 | - Controller 22 | - LeaveController 23 | - ReportController 24 | - Service 25 | - EmployeeService 26 | - LeaveCalculator 27 | - ReportManager 28 | - Models 29 | - Leave 30 | - Employee 31 | - Balance 32 | - Report 33 | - Utils 34 | - ExceptionUtils 35 | - ReportBuilder (*follows builder pattern while generating report*) 36 | - HTMLParser (*cases which includes acronyms, should be written as it is.*) 37 | - Repository/DAO 38 | - EmployeeDao 39 | - LeaveRepository 40 | -------------------------------------------------------------------------------- /docs/java/effective-java.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: effective-java 3 | title: Effective Java 4 | sidebar_label: Effective Java 5 | --- 6 | 7 | #### Effective Java 8 | 9 | * [Get the book](https://www.oreilly.com/library/view/effective-java/9780134686097/) 10 | * [Get the source code](https://github.com/jbloch/effective-java-3e-source-code) 11 | -------------------------------------------------------------------------------- /docs/java/functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: functions 3 | title: Functions 4 | sidebar_label: Functions 5 | --- 6 | 7 | #### The following convention should be followed for `function` naming: 8 | 9 | * Method names should contain a verb, as they are used to make an object take action. They should be mixed case, beginning with a lowercase letter, and the first letter of each subsequent word should be capitalized. Adjectives and nouns may be included in method names: 10 | 11 | ### verb 12 | 13 | ```java 14 | public int calculateRemainingLeaves() { 15 | 16 | //implementation 17 | 18 | } 19 | ``` 20 | 21 | ### verb and noun 22 | 23 | ```java 24 | public String getFullName() { 25 | 26 | //implementation 27 | } 28 | ```` 29 | -------------------------------------------------------------------------------- /docs/java/interfaces.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: interfaces 3 | title: Interfaces 4 | sidebar_label: Interfaces 5 | --- 6 | 7 | #### The following convention should be followed for interface naming: 8 | 9 | * Interface names should be capitalized like class names. 10 | * Generally, should be **adjectives** or **nouns** 11 | - *LeaveService* 12 | - *Approvable* 13 | 14 | * Interface represents type or contract on what the public methods and properties have to support. While naming interface, make sure its implementating classes demonstrate a subset behavior. 15 | e.g 16 | - **HealthCheckService** interface can have implementing classes like **DBHealthCheckService** , **StorageHealthCheckService**, **NotificationHealthCheckService** 17 | - Try not to includes Prefix like **I** or suffix like **impl** -------------------------------------------------------------------------------- /docs/java/logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: logging 3 | title: Logging 4 | sidebar_label: Logging 5 | --- 6 | 7 | Logging runtime information in your Java application is critically useful for understanding the behavior of any app, especially in cases when you encounter unexpected scenarios, errors or just need to track certain application events. 8 | 9 | In a real-world production environment, you usually don’t have the luxury of debugging. And so, logging files can be the only thing you have to go off of when attempting to diagnose an issue that’s not easy to reproduce. 10 | 11 | ### Logging Conventions 12 | 13 | * For consistency, declare your logger as the first field (top of code) in your class and declare it as follows: 14 | * private static final Logger logger = Logger.getLogger(MyClassName.class.getName()); 15 | The variable name should be "logger". The term "logger" makes for cleaner code while not reducing any developer's ability to understand the code. 16 | 17 | * Never log private or sensitive information such as **user credentials** or **financial data**. The data which should remain private must not be logged. 18 | * Never log too much information. This can happen in an attempt to capture all potentially relevant data. Too many log messages can also lead to difficulty in reading a log file and identifying the relevant information when a problem does occur. Always use cross-cutting concerns, an _Aspect_, to log the entry and exit of a method. 19 | * Sufficient information must be provided in the logged message. 20 | An example of a log message lacking specificity: 21 | - Error! Operation Failed 22 | Always add more specific and identifiable message: 23 | - Error! File upload profile_picture.jpg failed for unitId: 2 24 | * Add context in the log message by including the **timestamp**, **log level**, **thread name**, **fully qualified class name** and the **method name** of the event. This information can be hardwired in the configuration for the logging-framework used. 25 | * Use appropriate **LOG Levels** 26 | * **FATAL** 27 | FATAL should be reserved for errors that cause the application to crash or fail to start (ex: JVM out of memory) 28 | * **ERROR** 29 | ERROR should contain technical issues that need to be resolved for proper functioning of the system (ex: couldn’t connect to database) 30 | * **WARN** 31 | WARN is best used for temporary problems or unexpected behavior that does not significantly hamper the functioning of the application (ex: failed user login) 32 | * **INFO** 33 | Use INFO to report results to Administrators and Users. INFO should contain messages that describe what is happening in the application (ex: user registered, order placed) 34 | * **DEBUG** 35 | Use DEBUG to report results to yourself and other developers. DEBUG is intended for messages that could be useful in debugging an issue 36 | **TRACE** 37 | Use TRACE only for tracing the execution flow. In general, trace-level logging should be used only for tracing the flow of execution through a program and for flagging particular positions in a program. 38 | 39 | ### Logging Libraries 40 | 41 | * Apache Log4j2 (recommended) 42 | 43 | * Logback 44 | -------------------------------------------------------------------------------- /docs/java/packages.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: packages 3 | title: Packages 4 | sidebar_label: Packages 5 | --- 6 | 7 | #### The following convention should be followed for package naming: 8 | 9 | The prefix of a unique package name is always written in **all-lowercase ASCII letters** and should be one of the top-level domain names, currently **com**, **org**,**edu**, **gov**, **mil**, **net**, or one of the English two-letter codes identifying countries as specified in ISO Standard 3166, 1981. 10 | 11 | - Packages are all lower case to avoid conflict with the names of classes or interfaces. 12 | - Special characters are not allowed while naming packages, only alphanumeric. 13 | - Avoid reserve keywords 14 | 15 | Subsequent components of the package name vary according to an organization's own internal naming conventions. Such conventions might specify on technical aspect or a feature aspect e.g employee, leave, department, project etc: 16 | 17 | #### packaging by feature 18 | 19 | - com.projectname.employee 20 | - com.projectname.leave 21 | - com.projectname.department 22 | - com.projectname.project 23 | - com.projectname.utils 24 | - com.projectname.common 25 | 26 | #### packaging by patterns 27 | 28 | - com.projectname.controller 29 | - com.projectname.service 30 | - com.projectname.models 31 | - com.projectname.factories 32 | - com.projectname.utils 33 | - com.projectname.repository 34 | 35 | In some cases, the internet domain name may not be a valid package name. 36 | This can occur if the domain name contains a hyphen or other special character, 37 | if the package name begins with a digit or other character that is illegal to 38 | use as the beginning of a Java name, or if the package name contains a reserved Java keyword, such as "int". In this event, the suggested convention is to add an underscore. For example: 39 | 40 | | Domain Name | Package Name Prefix | 41 | |--- | ---| 42 | |hyphenated-name.example.org | org.example.hyphenated_name | 43 | |example.int |int_.example | 44 | | 123name.example.com |com.example._123name | 45 | 46 | -------------------------------------------------------------------------------- /docs/java/tools.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: tools 3 | title: Tools and Libraries 4 | sidebar_label: Tools and Libraries 5 | --- 6 | 7 | ### Formatters 8 | 9 | * [Google java Style](https://github.com/google/google-java-format) 10 | 11 | ### Dependency Management 12 | 13 | * [Gradle](https://gradle.org) (*recommended*) 14 | * [Maven](https://maven.apache.org) 15 | 16 | ### Testing 17 | 18 | * [JUnit 5](https://junit.org/junit5/) 19 | * [Mock Tool](https://github.com/mockito/mockito) 20 | * [Code Coverage](https://github.com/jacoco/jacoco) 21 | -------------------------------------------------------------------------------- /docs/java/variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: variables 3 | title: Variables 4 | sidebar_label: Variables 5 | --- 6 | 7 | #### The following convention should be followed for variable naming 8 | 9 | * Variable names should be **noun** or **adjectives** and should be **camelCase**. e.g age, balance, employeeReport etc 10 | 11 | * Variable names should not start with underscore _ or dollar sign $ characters, even though both are allowed. 12 | 13 | * Variable names should be short yet meaningful. The choice of a variable name should be mnemonic, self descriptive and semantical 14 | designed to indicate its intention. 15 | 16 | * One-character variable names should be avoided like i, j, k, m etc 17 | 18 | * Variable name should be plural if that is a collections. for e.g **employees**, **leaves** represents a list. 19 | 20 | * Variables names should be declared as per their types 21 | * Map/KeyValue pair should be declared as *keyToValue* and *valueByKey*. For e.g **ageByName** or **nameToAge**. 22 | * Set can be prefixed as *unique* before variable names. For e.g **uniqueNames** 23 | * Boolean can be prefixed as **is/are/has** e.g. **isVisible**, **isEligible**, **hasMaximumAmount** 24 | 25 | * Instance variable should be camelCase of their class names. 26 | * employeeService is an instance of EmployeeService. 27 | * reportDao is an instance of ReportDao. 28 | 29 | ## Constants 30 | 31 | * Constants names holds same conventions as variable except it should be **UPPER_CASE** separated by **(_)** underscore. 32 | * **AGE_BY_NAME**, **EMPLOYEE_REPORT** 33 | -------------------------------------------------------------------------------- /docs/javascript/classes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: classes 3 | title: Classes 4 | sidebar_label: Classes 5 | --- 6 | 7 | #### The following convention should be followed for `class` naming: 8 | 9 | ### Classes 10 | 11 | * Avoid inbuilt names. 12 | * Classes/Components/Interfaces names should always be `PascalCase` and `noun`. i.e. `TaskService`, `Interceptor`, `Evaluation` 13 | * Describe the class resposibility in name. 14 | * Custom Exceptions should always be named ending with `Error` or `Exception` i.e. `ValidationError` , `ValidationException` 15 | 16 | ```js 17 | class SoftwareDeveloper { 18 | constructor(firstName, lastName) { 19 | this.firstName = firstName; 20 | this.lastName = lastName; 21 | } 22 | } 23 | 24 | const me = new SoftwareDeveloper('John', 'Doe'); 25 | ``` 26 | 27 | ### Components 28 | 29 | * Components are commonly found in frontend frameworks like React/Polymer/Vue. Since a component is kinda instantiated -- but appended to the DOM instead -- like a JavaScript class, they are widely declared with `PascalCase` and `noun` too. 30 | 31 | ```js 32 | // bad 33 | function userProfile(user) { 34 | return ( 35 |
36 | First Name: {user.firstName} 37 | Last Name: {user.lastName} 38 |
39 | ); 40 | } 41 | 42 | // good 43 | function UserProfile(user) { 44 | return ( 45 |
46 | First Name: {user.firstName} 47 | Last Name: {user.lastName} 48 |
49 | ); 50 | } 51 | ``` 52 | 53 | When a component gets used, it distinguishes itself from native HTML and web components, because its first letter is always written in uppercase. 54 | 55 | ```jsx 56 | 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/javascript/functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: functions 3 | title: Functions 4 | sidebar_label: Functions 5 | --- 6 | 7 | #### Functions 8 | 9 | JavaScript functions are usually written in camelcase. In addition, it's a best practice to actually tell what the function is doing by giving the function name a verb as prefix. 10 | 11 | ```js 12 | // good 13 | function getName(firstName, lastName) { 14 | return `${firstName} ${lastName}`; 15 | } 16 | 17 | // bad 18 | function name(firstName, lastName) { 19 | return `${firstName} ${lastName}`; 20 | } 21 | ``` 22 | 23 | This verb as prefix can be anything (e.g. get, fetch, push, apply, calculate, compute, post). It's yet another soft rule to consider for having more self-descriptive JavaScript functions. 24 | -------------------------------------------------------------------------------- /docs/javascript/js-general-guidelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: js-general-guidelines 3 | title: JS General Coding Guidelines 4 | sidebar_label: JavaScript 5 | --- 6 | 7 | ### Code Quality 8 | 9 | #### Linter Validation 10 | 11 | [ESLint](https://eslint.org) is a recommended linting tool for the JavaScript codebases and it is configured to enforce the recommended coding standards rules for best practices and consistency in the code itself before the code is committed to GitHub even. 12 | This statically analyzes the code and ensures the code is consistent, readable, maintainable and properly formatted before it's pushed to the version control. 13 | 14 | **So, first of all, the code must comply with these eslint rules used in the project and must not leave any errors.** 15 | 16 | #### Other Guidelines 17 | 18 | Apart from the eslint validation. Following should be taken care of: 19 | 20 | - No hard coding, use constants/configuration values instead of hard-coding literal values. 21 | 22 | - Group similar values under a enumerated constants. 23 | 24 | - Avoid code duplication. If the same code needs to be reused in multiple places, create a extract a common function instead. 25 | 26 | - Write pure functions where ever possible. It keeps the code more understandable and deterministic, plus it helps to avoid unexpected run time issues due to mutation. 27 | 28 | - Don't mutate the parameters received in functions. 29 | 30 | ```js 31 | // DO NOT MUTATE function parameters. 32 | function getName(person) { 33 | person.name = person.firstName + ' ' + person.lastName; 34 | 35 | return person.name; 36 | } 37 | 38 | // Try to make the function a pure function where ever possible and avoid unnecessary side-effects. 39 | function getName(person) { 40 | let fullName = person.firstName + ' ' + person.lastName; 41 | 42 | return fullName; 43 | } 44 | ``` 45 | 46 | - Avoid unnecessary else blocks as much as possible. 47 | 48 | ```js 49 | // Avoid unnecessary else block if possible. 50 | function nullIfEmpty(value) { 51 | if (typeof value === 'string') { 52 | return value.trim() === '' ? null : value; 53 | } else { 54 | return value; 55 | } 56 | } 57 | 58 | // Like this 59 | function nullIfEmpty(value) { 60 | if (typeof value !== 'string') { 61 | return value; 62 | } 63 | 64 | return value.trim() === '' ? null : value; 65 | } 66 | ``` 67 | 68 | - Avoid nested if blocks, multiple if blocks. 69 | 70 | - While writing code make sure it doesn't violate SRP (Single Responsibility Principle). To be more specific take care of the following: 71 | 72 | - A function should do only one task. 73 | 74 | - Avoid having more than 3 parameters in a function. 75 | 76 | If your function requires many parameters, send all the parameters as a single object instead. 77 | 78 | ```js 79 | // Bad 80 | function setInfo(userName, firstName, lastName, email, website, dob) { 81 | ... 82 | } 83 | 84 | // Good 85 | function setInfo({ userName, firstName, lastName, email, website, dob }) { 86 | ... 87 | } 88 | 89 | // Good 90 | function setInfo(info) { 91 | const { userName, firstName, lastName, email, website, dob } = info; 92 | ... 93 | } 94 | ``` 95 | 96 | - Break down or refactor code with complexity into multiple smaller functions. 97 | 98 | - Use **async/await** or Promises for async operation and avoid callback hells. 99 | 100 | - Use Promise.all, Promise.allSettled instead of sequential asynchronous calls wherever applicable. 101 | 102 | ```js 103 | // Bad 104 | await getUsers(); 105 | await getProducts(); 106 | await getLocations(); 107 | 108 | // Good 109 | await Promise.all([getUsers, getProducts, getLocations]); 110 | 111 | ``` 112 | 113 | - Always catch errors for asynchronous calls such as API calls. Either **try/catch** or **.catch** should be used to catch errors. 114 | 115 | ```js 116 | // Bad 117 | const items = await getItems(); 118 | this.filteredItems = items.filter(filterItems); 119 | 120 | // Good 121 | try { 122 | const items = await getItems(); 123 | this.filteredItems = items.filter(filterItems); 124 | } catch (error) { 125 | this.handleError(error); 126 | } 127 | ``` 128 | 129 | - DocBlocks – Add doc blocks for each and every function, to clearly mention what it does. Docblocks also should mention the parameter types or return types. 130 | 131 | ```js 132 | /** 133 | * Call twilio API to send notifications. 134 | * 135 | * @param {object} payload 136 | * @returns {Promise} 137 | */ 138 | function sendNotification(payload) { 139 | return twilioClient.sendMessage(payload); 140 | } 141 | ``` 142 | 143 | - Make use of higher order functions for array and list manipulation and transformation eg: map, reduce, filter etc instead of plain old for loops. 144 | 145 | ```js 146 | // Avoid using loops for list/array transformation like this 147 | function submitForm(users) { 148 | let promises = []; 149 | for (let user of users) { 150 | if (isNotSaved(user)) { 151 | promises.push(saveUser(user)); 152 | } 153 | } 154 | 155 | return Promise.all(promises); 156 | } 157 | 158 | // Prefer a more functional approach for 159 | // transformation using higher order function. 160 | function submitForm(users) { 161 | let promises = users.filter(isNotSaved).map(saveUser); 162 | 163 | return Promise.all(promises); 164 | } 165 | ``` 166 | 167 | - Use framework features, or util functions provided by libraries wherever possible instead of writing custom code. 168 | - Don't hard-code text data in the code itself, instead put text content/messages in the internationalization files and use the content identifiers instead. 169 | - Each Components, Classes, or Interfaces should be written in their own file. And the filename should be named same as it's identifier. They must be exported as **default export**. 170 | - Use **PascalCase** naming convention for Components, Classes, or interfaces. 171 | - Use **camelCase** for naming functions and variables. 172 | - Use **CAPITAL_CASE_WITH_UNDERSCORES** for defining constants eg: const **PAGINATION_MAX_ROWS** = 15. 173 | -------------------------------------------------------------------------------- /docs/javascript/variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: variables 3 | title: Variables 4 | sidebar_label: Variables 5 | --- 6 | 7 | #### The following convention should be followed for variable naming 8 | 9 | * Variable names should be **noun** or **adjectives** and should be **camelCase**. e.g age, balance, employeeReport etc 10 | 11 | ```js 12 | // good 13 | const firstName = 'John'; 14 | 15 | // bad 16 | const firstname = 'John'; 17 | 18 | // bad 19 | const first_name = 'John'; 20 | 21 | // bad 22 | const FIRSTNAME = 'John'; 23 | 24 | // bad 25 | const FIRST_NAME = 'John'; 26 | ``` 27 | 28 | * **JavaScript variables are case sensitive**. Therefore, JavaScript variables with lowercase and uppercase characters are different 29 | 30 | ```js 31 | const name = 'John'; 32 | 33 | const Name = 'William'; 34 | 35 | const NAME = 'Tech'; 36 | 37 | console.log(name); 38 | // "John" 39 | 40 | console.log(Name); 41 | // "William" 42 | 43 | console.log(NAME); 44 | // "Tech" 45 | ``` 46 | 47 | * Variable names should be short yet meaningful. The choice of a variable name should be mnemonic, self descriptive and semantical 48 | designed to indicate its intention. 49 | 50 | * One-character variable names must be avoided like i, j, k, m etc 51 | 52 | * Variables names should be declared as per their types: 53 | * Map/KeyValue pair should be declared as *keyToValue* and *valueByKey*. For e.g **ageByName** or **nameToAge**. 54 | * Set can be prefixed as *unique* before variable names. For e.g **uniqueNames** 55 | * Boolean can be prefixed as **is/are/has** e.g. **isVisible**, **isEligible**, **hasMaximumAmount** 56 | 57 | ### Constants 58 | 59 | Constants intended to be non-changing variables are UPPER_CASE separated by underscore. e.g **HOURS_IN_DAY**, **PAGINATION_MAX_ROWS** 60 | -------------------------------------------------------------------------------- /docs/nosql/documentdb/many-to-many-relationship.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: many-to-many-relationship 3 | title: Many to Many Relationship 4 | sidebar_label: Many to Many Relationship 5 | --- 6 | 7 | ### Many To Many Relationship 8 | 9 | An M:N relationship is an example of a relationship between two entities where they both might have many relationships between each other. 10 | An example might be a `Book` that was written by many `Authors`. At the same time an `Author` might have written many `Books`. 11 | This leads to an N:M relationship between authors of books. Let’s look at how this can be modeled. 12 | 13 | ### Two Way Embedding 14 | 15 | Embedding Book foreign keys under Author document. 16 | 17 | ```json 18 | { 19 | _id: 1, 20 | name: "Peter Standford", 21 | books: [1, 2] 22 | } 23 | { 24 | _id: 2, 25 | name: "Georg Peterson", 26 | books: [2] 27 | } 28 | ``` 29 | 30 | Similarly, embedding Author foreign keys under Book document. 31 | 32 | ```json 33 | { 34 | _id: 1, 35 | title: "A tale of two people", 36 | categories: ["drama"], 37 | authors: [1, 2] 38 | } 39 | { 40 | _id: 2, 41 | title: "A tale of two space ships", 42 | categories: ["scifi"], 43 | authors: [1] 44 | } 45 | ``` 46 | 47 | :::note 48 | **Uneven n:m relationships** 49 | 50 | Let’s take the category drama that might have thousands of books in it and with many new books consistently being added and removed. This makes it impracticable to embed all the books in a category document. Each book, however, can easily have categories embedded within it, as the rate of change of categories for a specific book might be very low. 51 | 52 | In this case we should consider One way embedding as a strategy. 53 | ::: 54 | 55 | ### One Way Embedding 56 | 57 | The One Way Embedding strategy chooses to optimize the read performance of a N:M relationship by embedding the references in one side of the relationship. 58 | An example might be where several books belong to a few categories but a couple categories have many books. 59 | 60 | Let’s look at an example, pulling the categories out into a separate document. 61 | 62 | **Category document** 63 | 64 | ```json 65 | { 66 | _id: 1, 67 | name: "drama" 68 | } 69 | ``` 70 | 71 | **Book document with foreign keys to categories** 72 | 73 | ```json 74 | { 75 | _id: 1, 76 | title: "A tale of two people", 77 | categories: [1], 78 | authors: [1, 2] 79 | } 80 | ``` 81 | 82 | :::info 83 | **Establish Relationship Balance** 84 | 85 | Establish the maximum size of N and the size of M. 86 | For example if N is a maximum of 3 categories for a book and M is a maximum of 500000 books in a category you should pick **One Way Embedding**. 87 | If N is a maximum of 3 and M is a maximum of 5 then Two Way Embedding might work well. 88 | ::: 89 | -------------------------------------------------------------------------------- /docs/nosql/documentdb/naming-conventions.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: document-db-naming-convention 3 | title: Document DB Naming Convention 4 | sidebar_label: Document DB Naming Convention 5 | --- 6 | 7 | #### The following convention should be followed for naming Document Based DB: 8 | 9 | ## Database name 10 | 11 | - Use `lowerCamelCase` for naming the database and should always be **singular form**. 12 | It is recommended to add **`Db`** suffix at the end. 13 | Usually represents the application name as a whole. 14 | Examples **imageDb**, **employeeManagementDb** etc. 15 | 16 | ## Collections 17 | 18 | - Use `lowerCamelCase` for naming the collections and should always be **plural form**. 19 | Examples, **events**, **userProfiles**, **payments** etc. 20 | - Do not use special characters or numbers for collections name. 21 | 22 | ## Field names 23 | 24 | - Use `lowerCamelCase` for naming the field name and should be **singular form**. 25 | Examples **accountName**, **firstName**, **address** etc. 26 | In case, the field represents an array or collection of element, the field name should be **plural form** 27 | e.g. **accounts**, **phoneNumbers** etc. 28 | 29 | Usually, Document based DB object representations are similar to JavaScript objects, so utilise JS naming conventions for various cases. 30 | -------------------------------------------------------------------------------- /docs/nosql/documentdb/one-to-many-relationship.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: one-to-many-relationship 3 | title: One to Many Relationship 4 | sidebar_label: One to Many Relationship 5 | --- 6 | 7 | ### One to many relationship (1:N) 8 | 9 | The 1:N relationship describes a relationship where one side can have more than one relationship 10 | while the reverse relationship can only be single sided. 11 | An example is a `Post` where a blog might have many `Comments` but a `Comment` is only related to a single `Post`. 12 | 13 | ### Embedded document pattern 14 | 15 | Embedding connected data in a single document can reduce the number of read operations required to obtain data. In general, you should structure your schema so your application receives all of its required information in a single read operation. If the number of embedded document(s)(child documents) are limited to fewer numbers then this can be better options. 16 | 17 | For example, `User To Accounts`, `User To Addresses`, `Post To Comments`, can be modeled to embedded document pattern in one to many relationship. 18 | 19 | ```json 20 | { 21 | "id": "1", 22 | "name": "John Doe", 23 | "accounts": [ 24 | { 25 | "bank": "123 fake bank", 26 | "accountNumber": "1231308239", 27 | "accountType": "saving", 28 | "address":"123 fake street", 29 | "createdDate":"2020-06-06", 30 | "valid" :true, 31 | "balance": "100.00" 32 | }, 33 | { 34 | "bank": "abc fake bank", 35 | "accountNumber": "1231308239", 36 | "accountType": "saving", 37 | "address":"123 fake street", 38 | "createdDate":"2020-07-06", 39 | "valid" :true, 40 | "balance": "100.00" 41 | } 42 | ] 43 | } 44 | ``` 45 | 46 | However, there are 3 potential problems associated with this approach that one should be aware of. 47 | 48 | :::caution 49 | * The embedded documents might grow larger and consequently growing main document size. NoSql DBs have limit on document size for example 16MB in case of Mongodb, 1 MB in case of google fire store. 50 | * This could result in slow write performance as the embedded documents grows significantly larger in number. 51 | * The third problem is exposed when one tries to perform pagination on the embedded documents 52 | ::: 53 | 54 | ### Subset Pattern 55 | 56 | - In case, we don't need whole data of embedded documents, we can store only the required part of the document which is frequently fetched. 57 | For example, we might only need `bank name` and `account number` while fetching `user details`. 58 | In this case `Accounts` can be a separate collections with all the account related details and `Users` collection can have subset of `accounts` inside each user details. 59 | 60 | ```json 61 | { 62 | "id":"1", 63 | "name":"John Doe", 64 | "accounts": [ 65 | { 66 | "bank":"123 fake bank", 67 | "accountNumber":"1231308239" 68 | }, 69 | { 70 | "bank":"abc fake bank", 71 | "accountNumber":"1231308239" 72 | } 73 | ] 74 | } 75 | ``` 76 | 77 | :::info 78 | **When to use subset pattern** 79 | 80 | Some cases when properties rarely changes, for example **name** , **dateOfBirth** etc , we can denormalize these properties across multiple collections. 81 | In the above given example, **bank name** and **account number** will rarely changes and we can duplicate these properties across multiple collections to avoid 82 | joins and faster fetch. 83 | ::: 84 | 85 | ### Document references 86 | 87 | * This is normalised case of structuring data by adding reference or id of the required document inside other document as a foreign key. 88 | **This is recommended only when the document being referenced is highly changing.** 89 | This will impact read performance. 90 | 91 | ```json 92 | { 93 | "id": "1", 94 | "name": "John Doe", 95 | "accounts": [1234,345334,785124132] 96 | } 97 | ``` 98 | 99 | ### Linking 100 | 101 | The another approach is to link `Accounts` to the `User` using a more traditional foreign key. 102 | 103 | ```json 104 | { 105 | "id": "1", 106 | "name": "John Doe", 107 | "address":"fake street 123" 108 | } 109 | ``` 110 | 111 | ```json 112 | { 113 | "id": "1", 114 | "userId: "1", 115 | "bank": "123 fake bank", 116 | "accountNumber": "1231308239" 117 | }, 118 | { 119 | "id": "2", 120 | "userId: "1", 121 | "bank": "abc fake bank", 122 | "accountNumber": "1231308239" 123 | } 124 | ``` 125 | 126 | An advantage this model has is that additional `Accounts` will not grow the original `User` document, making it less likely that the applications will run in the maximum document size limit. 127 | It’s also much easier to return paginated documents as the application can slice and dice the documents more easily. 128 | 129 | On the downside if we have 1000 accounts on a user, we would need to retrieve all 1000 documents causing a lot of reads from the database. 130 | 131 | ### Bucketing 132 | 133 | The third approach is a hybrid of the two above. Basically, it tries to balance the rigidity of the embedding strategy with the flexibility of the linking strategy. 134 | Lets take example of `Post` and `Comments`. We will split the comments into buckets with a maximum of 50 comments in each bucket. 135 | 136 | ```json 137 | { 138 | _id: 1, 139 | title: "An awesome blog", 140 | url: "http://awesomeblog.com", 141 | text: "This is an awesome blog we have just started" 142 | } 143 | 144 | ``` 145 | 146 | ```json 147 | { 148 | blog_entry_id: 1, 149 | page: 1, 150 | count: 50, 151 | comments: [{ 152 | name: "Peter Critic", 153 | created_on: ISODate("2014-01-01T10:01:22Z"), 154 | comment: "Awesome blog post" 155 | }, ...] 156 | } 157 | { 158 | blog_entry_id: 1, 159 | page: 2, 160 | count: 1, 161 | comments: [{ 162 | name: "John Page", 163 | created_on: ISODate("2014-01-01T11:01:22Z"), 164 | comment: "Not so awesome blog" 165 | }] 166 | } 167 | 168 | ``` 169 | 170 | The main benefit of using buckets in this case is that we can perform a single read to fetch 50 comments at a time, allowing for efficient pagination. 171 | :::info 172 | **When to use bucketing** 173 | 174 | When you have the possibility of splitting up your documents into discrete batches, it makes sense to consider bucketing to speed up document retrieval. 175 | 176 | Typical cases where bucketing is appropriate are ones such as bucketing data by hours, days or number of entries on a page (like comments pagination). 177 | ::: 178 | -------------------------------------------------------------------------------- /docs/nosql/documentdb/one-to-one-relationship.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: one-to-one-relationship 3 | title: Document DB Best Practices 4 | sidebar_label: One to One Relationship 5 | --- 6 | 7 | ### Defining a schema 8 | 9 | It is generally good practice to use a schema to validate the entity or contents of a document, although document DB is a schema-less database, which allows maximum flexibility in structuring data. 10 | This will reduce writing defensive code and confirm the structure of your data in the database. 11 | There are various libraries that can validate json object against the predefined schema like 12 | [simpl-schema](https://www.npmjs.com/package/simpl-schema), [ajv](https://ajv.js.org/). 13 | 14 | For some Databases like MongoDb, there are rich ORM libraries like [mongoose](https://mongoosejs.com/docs/) that support schema validation out of the box. 15 | 16 | ### Structuring the document 17 | 18 | The key decision in designing the data models for document DB depends upon the relationship between data, whether data should be embedded with in a document or 19 | create separate collection. 20 | 21 | ### One to one relationship (1:1) 22 | 23 | - When the relationship between two entities is one to one, then we can do for embedded document (keeping the child document inside the parent document) or Linking document 24 | to main document via unique identifier. 25 | 26 | ### Embedded pattern 27 | 28 | Let's consider an example between `employee` and `address`. The `address` belongs to `employee` and is frequently retrieved along with the employee information. 29 | 30 | ```json 31 | { 32 | "id":"1", 33 | "name":"John Doe", 34 | "address": { 35 | "street":"123 Fake Street", 36 | "city":"Faketon", 37 | "state":"MA", 38 | "zip":"12345" 39 | } 40 | } 41 | ``` 42 | 43 | - In case the embedded document has a large contents, good practice is to only retrieve the subset of a document,only the required fields, commonly called as [subset pattern](https://docs.mongodb.com/manual/tutorial/model-embedded-one-to-many-relationships-between-documents/#subset-pattern). 44 | 45 | ### Linking 46 | 47 | The second approach is to link two documents using a foreign key. 48 | 49 | **User document** 50 | 51 | ```json 52 | { 53 | id: "1", 54 | name: "John Doe", 55 | contact : 123446 56 | } 57 | ``` 58 | 59 | **Address document** 60 | 61 | ```json 62 | { 63 | id: "1", 64 | userId : "1", 65 | street: "123 Fake Street", 66 | city: "Faketon", 67 | state: "MA", 68 | zip: "12345" 69 | } 70 | ``` 71 | 72 | This is similar to how traditional relational databases would store the data. 73 | It is important to note that most of the document db no sql does not enforce any foreign key constraints so the relation only exists as part of the application level schema. 74 | 75 | :::note 76 | In the one to one relationship, Embedding is the preferred way to model the relationship as it’s more efficient to retrieve the document. 77 | ::: 78 | -------------------------------------------------------------------------------- /docs/python/classes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: classes 3 | title: Classes 4 | sidebar_label: Classes 5 | --- 6 | 7 | #### The following convention should be followed for `class` naming: 8 | 9 | * Avoid inbuilt names. 10 | * Classes names should always be `PascalCase`. i.e. `MyClass` 11 | * **Abstract Classes and Mixins** 12 | * Use [abstract containers](https://docs.python.org/3/library/collections.abc.html#module-collections.abc) if need to override datatypes. 13 | * If you **must build datatypes** based on inbuilt class use PascalCase. i.e. `MyDict(dict):`. Although this is not recommended and you should use `collections`. 14 | * Use [`abc`](https://docs.python.org/3/library/abc.html) if you need pure OOP style abstract classes. Use `NotImplementedError` exceptions with overrides. 15 | * Mixin should be named with `Mixin` suffix such as `class LoginRequiredMixin` which can be used in multiple inheritance. 16 | * Describe the class responsibility in name clearly when possible. 17 | * Custom Exceptions should always be named ending with `Error` i.e. `MyCustomError` 18 | 19 | ##### Example 20 | 21 | ```python 22 | class HelloWorld: 23 | pass 24 | 25 | class HelloWorldError(Exception): 26 | pass 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/python/docstrings.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: docstrings 3 | title: Convention for docstrings 4 | sidebar_label: Docstrings 5 | --- 6 | 7 | ## Introduction 8 | 9 | > Code is more often read than written - Guido Van Rossum 10 | 11 | A few lines of description written on top of a function can save 12 | the coder or a future developer hours or time reading the code. 13 | 14 | **Docstrings** are documentation that is written along with the code. 15 | There are different typs of docstrings in Python: 16 | 17 | - Class 18 | - Class methods 19 | - Package 20 | - Modules 21 | - Functions 22 | - Script 23 | 24 | ### Comments are not docstrings 25 | 26 | While comments are also written alongside code, docstrings are different 27 | from comments. While comments start with a '#' symbol, docstrings are 28 | also enclosed withing triple double quotes """This is a docstring""". 29 | The placement of docstrings is also crucial. Docstrings placed arbitrarily 30 | may simply be construed as a comment 31 | 32 | To illustrate this try the following in the python console 33 | 34 | ```python 35 | class Test: 36 | """This is a class docstring""" 37 | 38 | def example_method(): 39 | """This is a method docstring 40 | """ 41 | pass 42 | 43 | def example_method_2(): 44 | # This is a comment 45 | pass 46 | ``` 47 | 48 | ```python 49 | > print(Test.__doc___) 50 | This is a class docstring 51 | > 52 | > print(Test.example_method.__doc__) 53 | This is a method docstring 54 | > 55 | > print(Test.example_method_2.__doc__) 56 | None 57 | ``` 58 | 59 | As you can see from the examples above, docstrings get 60 | attached to the `__doc__` property of the code itself whereas, 61 | the comments do not. 62 | 63 | ### Usage of docstrings 64 | 65 | From the console, you can use docstrings to an overview of 66 | code as follows: 67 | 68 | ```python 69 | > help(Test) 70 | Help on class Test in module __main__: 71 | 72 | class Test(builtins.object) 73 | | This is a class docstring 74 | | 75 | | Methods defined here: 76 | | 77 | | example_method() 78 | | This is a method docstring 79 | | 80 | | example_method_2() 81 | 82 | 83 | ``` 84 | 85 | If a docstring is provided, you can get more readable 86 | information about python code. 87 | 88 | ** They are also used by your IDE to give you information while developing.** 89 | 90 | Furthermore, there are tools that can take this to the 91 | next level by creating a static website of documentation 92 | for your code: 93 | 94 | - [Sphinx](http://www.sphinx-doc.org/en/stable/) 95 | - [Epydoc](http://epydoc.sourceforge.net/) 96 | - [Read the docs](https://readthedocs.org/) 97 | - [Doxygen](https://www.doxygen.nl/manual/docblocks.html#pythonblocks) 98 | - [MkDocs](https://www.mkdocs.org/) 99 | - [Pycco](https://pycco-docs.github.io/pycco/) 100 | 101 | 102 | ## Conventions 103 | 104 | The following sections describe the conventions that are recommended by Leapfrog 105 | 106 | ### Python's official standard 107 | 108 | The PEPs are considered to be the official standard for Python. The following sections 109 | talk specifically about docstring and we recommend that you read them 110 | 111 | - [PEP-256 -- Docstring Conventions](https://www.python.org/dev/peps/pep-0257/#specification) (**Must Read**) 112 | - [PEP-8 Comments Section](https://www.python.org/dev/peps/pep-0008/#comments) 113 | - [PEP 287 reStructedText Docstring Format](https://www.python.org/dev/peps/pep-0287/) 114 | 115 | ### Docstring template selection 116 | 117 | While you can write anything between the triple quotes(""") to 118 | write your docstring, it is generally recommended to follow a 119 | template for consistency and also for libraries to be able to 120 | parse your docstring easily. 121 | 122 | The official documentation standard for Python is ReStructed Text docstrings ([PEP 287](https://www.python.org/dev/peps/pep-0287/)). 123 | However, Google docstrings have been widely accepted by the community as such we recommend it as we find it more readable and pythonic. 124 | If you're using using Numpy related libraries, you should be using Numpy Docstrings 125 | 126 | - [Google docstrings](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings) (**Recommended**) 127 | - [reStructured Text Docstrings](http://docutils.sourceforge.net/rst.html) (Seen in many inbuilt python libraries.) 128 | - [Numpy Docstrings](https://numpydoc.readthedocs.io/en/latest/format.html) (**Recommended for AI projects**) 129 | 130 | ### Where to add docstrings 131 | 132 | The developers should add docstrings in the following locations 133 | 134 | - At the start of every Python file 135 | - At the beginning of every class 136 | - After each function declaration 137 | - At the beginning of the `__init__.py` file for Module/Package documentation 138 | - In their tests to describe what they are testing. 139 | 140 | ### What to not miss 141 | 142 | Use the documentation template of your choice and try not to miss the following 143 | in the docstrings 144 | 145 | - A brief description of the entity that is being documented (**Mandatory**) 146 | - Follow the above by above by examples and implementation details (**Recommended**) 147 | - Add typing information where things can get confusing (**Recommended**). As python is a 148 | dynamically typed language, adding some type definition to the documentation can save 149 | the developers a lot of debugging time 150 | - Autodeploy the documentation site using a static deployment tool 151 | to check that your docstrings render correctly 152 | 153 | ### Checking Docstring coverage 154 | 155 | - Use [pydocstyle](https://pydocstyle.pycqa.org/en/latest/) for linting your code against docstrings. When using `flake8`, [this](https://gitlab.com/pycqa/flake8-docstrings) plugin can be used. 156 | - [interrogate](https://interrogate.readthedocs.io/en/latest/) (example below) is **recommended** to use for docstring coverage in the code. 157 | 158 | ``` 159 | ================== Coverage for /Users/lynn/dev/interrogate/ ==================== 160 | ------------------------------------ Summary ------------------------------------ 161 | | Name | Total | Miss | Cover | Cover% | 162 | |---------------------------------------|---------|--------|---------|----------| 163 | | src/interrogate/__init__.py | 1 | 0 | 1 | 100% | 164 | | src/interrogate/__main__.py | 1 | 0 | 1 | 100% | 165 | | src/interrogate/badge_gen.py | 5 | 0 | 5 | 100% | 166 | | src/interrogate/cli.py | 2 | 0 | 2 | 100% | 167 | | src/interrogate/config.py | 6 | 0 | 6 | 100% | 168 | | src/interrogate/coverage.py | 25 | 0 | 25 | 100% | 169 | | src/interrogate/utils.py | 10 | 0 | 10 | 100% | 170 | | src/interrogate/visit.py | 15 | 0 | 15 | 100% | 171 | | tests/functional/__init__.py | 1 | 0 | 1 | 100% | 172 | | tests/functional/test_cli.py | 7 | 0 | 7 | 100% | 173 | | tests/functional/test_coverage.py | 6 | 0 | 6 | 100% | 174 | | tests/unit/__init__.py | 1 | 0 | 1 | 100% | 175 | | tests/unit/test_badge_gen.py | 6 | 0 | 6 | 100% | 176 | | tests/unit/test_config.py | 7 | 0 | 7 | 100% | 177 | | tests/unit/test_utils.py | 13 | 0 | 13 | 100% | 178 | |---------------------------------------|---------|--------|---------|----------| 179 | | TOTAL | 106 | 0 | 106 | 100.0% | 180 | ---------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ---------------- 181 | 182 | ``` 183 | 184 | ### Examples 185 | 186 | #### Google Docstrings (recommended) 187 | 188 | ```python 189 | 190 | """Example Google style docstrings. 191 | 192 | This module demonstrates documentation as specified by the `Google Python 193 | Style Guide`_. Docstrings may extend over multiple lines. Sections are created 194 | with a section header and a colon followed by a block of indented text. 195 | 196 | Example: 197 | Examples can be given using either the ``Example`` or ``Examples`` 198 | sections. Sections support any reStructuredText formatting, including 199 | literal blocks:: 200 | 201 | $ python example_google.py 202 | 203 | Section breaks are created by resuming unindented text. Section breaks 204 | are also implicitly created anytime a new section starts. 205 | 206 | Attributes: 207 | module_level_variable1 (int): Module level variables may be documented in 208 | either the ``Attributes`` section of the module docstring, or in an 209 | inline docstring immediately following the variable. 210 | 211 | Either form is acceptable, but the two should not be mixed. Choose 212 | one convention to document module level variables and be consistent 213 | with it. 214 | 215 | Todo: 216 | * For module TODOs 217 | * You have to also use ``sphinx.ext.todo`` extension 218 | 219 | .. _Google Python Style Guide: 220 | https://google.github.io/styleguide/pyguide.html 221 | 222 | """ 223 | 224 | module_level_variable1 = 12345 225 | 226 | module_level_variable2 = 98765 227 | """int: Module level variable documented inline. 228 | 229 | The docstring may span multiple lines. The type may optionally be specified 230 | on the first line, separated by a colon. 231 | """ 232 | 233 | 234 | def function_with_types_in_docstring(param1, param2): 235 | """Example function with types documented in the docstring. 236 | 237 | `PEP 484`_ type annotations are supported. If attribute, parameter, and 238 | return types are annotated according to `PEP 484`_, they do not need to be 239 | included in the docstring: 240 | 241 | Args: 242 | param1 (int): The first parameter. 243 | param2 (str): The second parameter. 244 | 245 | Returns: 246 | bool: The return value. True for success, False otherwise. 247 | 248 | .. _PEP 484: 249 | https://www.python.org/dev/peps/pep-0484/ 250 | 251 | """ 252 | 253 | 254 | def function_with_pep484_type_annotations(param1: int, param2: str) -> bool: 255 | """Example function with PEP 484 type annotations. 256 | 257 | Args: 258 | param1: The first parameter. 259 | param2: The second parameter. 260 | 261 | Returns: 262 | The return value. True for success, False otherwise. 263 | 264 | """ 265 | 266 | 267 | def module_level_function(param1, param2=None, *args, **kwargs): 268 | """This is an example of a module level function. 269 | 270 | Function parameters should be documented in the ``Args`` section. The name 271 | of each parameter is required. The type and description of each parameter 272 | is optional, but should be included if not obvious. 273 | 274 | If ``*args`` or ``**kwargs`` are accepted, 275 | they should be listed as ``*args`` and ``**kwargs``. 276 | 277 | The format for a parameter is:: 278 | 279 | name (type): description 280 | The description may span multiple lines. Following 281 | lines should be indented. The "(type)" is optional. 282 | 283 | Multiple paragraphs are supported in parameter 284 | descriptions. 285 | 286 | Args: 287 | param1 (int): The first parameter. 288 | param2 (:obj:`str`, optional): The second parameter. Defaults to None. 289 | Second line of description should be indented. 290 | *args: Variable length argument list. 291 | **kwargs: Arbitrary keyword arguments. 292 | 293 | Returns: 294 | bool: True if successful, False otherwise. 295 | 296 | The return type is optional and may be specified at the beginning of 297 | the ``Returns`` section followed by a colon. 298 | 299 | The ``Returns`` section may span multiple lines and paragraphs. 300 | Following lines should be indented to match the first line. 301 | 302 | The ``Returns`` section supports any reStructuredText formatting, 303 | including literal blocks:: 304 | 305 | { 306 | 'param1': param1, 307 | 'param2': param2 308 | } 309 | 310 | Raises: 311 | AttributeError: The ``Raises`` section is a list of all exceptions 312 | that are relevant to the interface. 313 | ValueError: If `param2` is equal to `param1`. 314 | 315 | """ 316 | if param1 == param2: 317 | raise ValueError('param1 may not be equal to param2') 318 | return True 319 | 320 | 321 | def example_generator(n): 322 | """Generators have a ``Yields`` section instead of a ``Returns`` section. 323 | 324 | Args: 325 | n (int): The upper limit of the range to generate, from 0 to `n` - 1. 326 | 327 | Yields: 328 | int: The next number in the range of 0 to `n` - 1. 329 | 330 | Examples: 331 | Examples should be written in doctest format, and should illustrate how 332 | to use the function. 333 | 334 | >>> print([i for i in example_generator(4)]) 335 | [0, 1, 2, 3] 336 | 337 | """ 338 | for i in range(n): 339 | yield i 340 | 341 | 342 | class ExampleError(Exception): 343 | """Exceptions are documented in the same way as classes. 344 | 345 | The __init__ method may be documented in either the class level 346 | docstring, or as a docstring on the __init__ method itself. 347 | 348 | Either form is acceptable, but the two should not be mixed. Choose one 349 | convention to document the __init__ method and be consistent with it. 350 | 351 | Note: 352 | Do not include the `self` parameter in the ``Args`` section. 353 | 354 | Args: 355 | msg (str): Human readable string describing the exception. 356 | code (:obj:`int`, optional): Error code. 357 | 358 | Attributes: 359 | msg (str): Human readable string describing the exception. 360 | code (int): Exception error code. 361 | 362 | """ 363 | 364 | def __init__(self, msg, code): 365 | self.msg = msg 366 | self.code = code 367 | 368 | 369 | class ExampleClass: 370 | """The summary line for a class docstring should fit on one line. 371 | 372 | If the class has public attributes, they may be documented here 373 | in an ``Attributes`` section and follow the same formatting as a 374 | function's ``Args`` section. Alternatively, attributes may be documented 375 | inline with the attribute's declaration (see __init__ method below). 376 | 377 | Properties created with the ``@property`` decorator should be documented 378 | in the property's getter method. 379 | 380 | Attributes: 381 | attr1 (str): Description of `attr1`. 382 | attr2 (:obj:`int`, optional): Description of `attr2`. 383 | 384 | """ 385 | 386 | def __init__(self, param1, param2, param3): 387 | """Example of docstring on the __init__ method. 388 | 389 | The __init__ method may be documented in either the class level 390 | docstring, or as a docstring on the __init__ method itself. 391 | 392 | Either form is acceptable, but the two should not be mixed. Choose one 393 | convention to document the __init__ method and be consistent with it. 394 | 395 | Note: 396 | Do not include the `self` parameter in the ``Args`` section. 397 | 398 | Args: 399 | param1 (str): Description of `param1`. 400 | param2 (:obj:`int`, optional): Description of `param2`. Multiple 401 | lines are supported. 402 | param3 (list(str)): Description of `param3`. 403 | 404 | """ 405 | self.attr1 = param1 406 | self.attr2 = param2 407 | self.attr3 = param3 #: Doc comment *inline* with attribute 408 | 409 | #: list(str): Doc comment *before* attribute, with type specified 410 | self.attr4 = ['attr4'] 411 | 412 | self.attr5 = None 413 | """str: Docstring *after* attribute, with type specified.""" 414 | 415 | @property 416 | def readonly_property(self): 417 | """str: Properties should be documented in their getter method.""" 418 | return 'readonly_property' 419 | 420 | @property 421 | def readwrite_property(self): 422 | """list(str): Properties with both a getter and setter 423 | should only be documented in their getter method. 424 | 425 | If the setter method contains notable behavior, it should be 426 | mentioned here. 427 | """ 428 | return ['readwrite_property'] 429 | 430 | @readwrite_property.setter 431 | def readwrite_property(self, value): 432 | value 433 | 434 | def example_method(self, param1, param2): 435 | """Class methods are similar to regular functions. 436 | 437 | Note: 438 | Do not include the `self` parameter in the ``Args`` section. 439 | 440 | Args: 441 | param1: The first parameter. 442 | param2: The second parameter. 443 | 444 | Returns: 445 | True if successful, False otherwise. 446 | 447 | """ 448 | return True 449 | 450 | def __special__(self): 451 | """By default special members with docstrings are not included. 452 | 453 | Special members are any methods or attributes that start with and 454 | end with a double underscore. Any special member with a docstring 455 | will be included in the output, if 456 | ``napoleon_include_special_with_doc`` is set to True. 457 | 458 | This behavior can be enabled by changing the following setting in 459 | Sphinx's conf.py:: 460 | 461 | napoleon_include_special_with_doc = True 462 | 463 | """ 464 | pass 465 | 466 | def __special_without_docstring__(self): 467 | pass 468 | 469 | def _private(self): 470 | """By default private members are not included. 471 | 472 | Private members are any methods or attributes that start with an 473 | underscore and are *not* special. By default they are not included 474 | in the output. 475 | 476 | This behavior can be changed such that private members *are* included 477 | by changing the following setting in Sphinx's conf.py:: 478 | 479 | napoleon_include_private_with_doc = True 480 | 481 | """ 482 | pass 483 | 484 | def _private_without_docstring(self): 485 | pass 486 | 487 | ``` 488 | 489 | #### ReStructured Text Doc strings 490 | 491 | You can see this kind of docstring especially in python libraries. 492 | Please use **Google** style as they are more readable. 493 | 494 | ```python 495 | """The method below prints a given string twice 496 | 497 | The print method has been called twice for 498 | implementing this method 499 | 500 | :param param1: String that is to be printed 501 | :type param1: str 502 | :return: Length of the input string 503 | :rtype: int 504 | """ 505 | def print_twice(param1): 506 | print(param1) 507 | print(param1) 508 | 509 | return len(param1) 510 | 511 | """The method below prints a given string twice. This is for type annotation. 512 | 513 | The print method has been called twice for 514 | implementing this method 515 | 516 | :param str param1: String that is to be printed 517 | :return: Length of the input string 518 | :rtype: int 519 | """ 520 | def print_twice(param1: str) -> int: 521 | print(param1) 522 | print(param1) 523 | 524 | return len(param1) 525 | ``` 526 | 527 | ## Doctests 528 | 529 | :::caution 530 | While this should not be used for all checks and [testing](testing.md) should be followed. They can be used for simple parameter checking. i.e. some default case like module level doctest in example below. 531 | 532 | They can be used with [pytest](https://docs.pytest.org/en/latest/doctest.html) as well. 533 | ::: 534 | 535 | Python provides tests through docstrings which can be leveraged by [doctests](https://docs.python.org/3/library/doctest.html). 536 | 537 | Example 538 | 539 | ```python 540 | """ 541 | This is the "example" module. 542 | 543 | The example module supplies one function, factorial(). For example, 544 | 545 | >>> factorial(5) 546 | 120 547 | """ 548 | 549 | def factorial(n): 550 | """Return the factorial of n, an exact integer >= 0. 551 | 552 | >>> [factorial(n) for n in range(6)] 553 | [1, 1, 2, 6, 24, 120] 554 | >>> factorial(30) 555 | 265252859812191058636308480000000 556 | >>> factorial(-1) 557 | Traceback (most recent call last): 558 | ... 559 | ValueError: n must be >= 0 560 | 561 | Factorials of floats are OK, but the float must be an exact integer: 562 | >>> factorial(30.1) 563 | Traceback (most recent call last): 564 | ... 565 | ValueError: n must be exact integer 566 | >>> factorial(30.0) 567 | 265252859812191058636308480000000 568 | 569 | It must also not be ridiculously large: 570 | >>> factorial(1e100) 571 | Traceback (most recent call last): 572 | ... 573 | OverflowError: n too large 574 | """ 575 | 576 | import math 577 | if not n >= 0: 578 | raise ValueError("n must be >= 0") 579 | if math.floor(n) != n: 580 | raise ValueError("n must be exact integer") 581 | if n+1 == n: # catch a value like 1e300 582 | raise OverflowError("n too large") 583 | result = 1 584 | factor = 2 585 | while factor <= n: 586 | result *= factor 587 | factor += 1 588 | return result 589 | 590 | 591 | if __name__ == "__main__": 592 | import doctest 593 | doctest.testmod() 594 | ``` 595 | 596 | This can be tested with: 597 | 598 | ```bash 599 | $ python example.py -v 600 | ``` 601 | 602 | ### References 603 | 604 | - [Pycharm Documentation on Docstrings](https://www.jetbrains.com/help/pycharm/using-docstrings-to-specify-types.html) 605 | - [Documenting Python Code by RealPython](https://realpython.com/documenting-python-code/#documenting-your-python-projects) 606 | - [PEP-256 -- Docstring Conventions](https://www.python.org/dev/peps/pep-0257/#specification) 607 | - [PEP-8 Comments Section](https://www.python.org/dev/peps/pep-0008/#comments) 608 | - [Documentation - Python Guide](https://docs.python-guide.org/writing/documentation/) 609 | - [Documenting in Python - DevGuide](https://devguide.python.org/documenting/) 610 | - [daouzli - stackoverflow](https://stackoverflow.com/questions/3898572/what-is-the-standard-python-docstring-format) 611 | - [interrogate](https://interrogate.readthedocs.io/en/latest/) 612 | -------------------------------------------------------------------------------- /docs/python/environment-and-dependency.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: environment-and-dependency 3 | title: Environment Isolation and Dependency Management 4 | sidebar_label: Environment Isolation and Dependency Management 5 | --- 6 | 7 | #### Information on development environment and dependency: 8 | 9 | ### Environment Isolation: 10 | 11 | * System installed `python` should never be used for development. Isolate your development. 12 | * Any of the following can be used for python isolation: 13 | - [pyenv](https://github.com/pyenv/pyenv). **Recommended** as this supports local python install and multiple python versions. 14 | - [virtualenv](https://virtualenv.pypa.io/en/latest/). _Third Party_ 15 | - [venv](https://docs.python.org/3/tutorial/venv.html). _Inbuilt_ `python -m venv` 16 | * Use `pip` for installing packages if not using `poetry`. 17 | 18 | :::info 19 | Docker based containerized python can be used as well. Official images [here](https://hub.docker.com/_/python). It is better to use virtualenvs in docker as well rather than root based user. 20 | ::: 21 | 22 | ### Dependency Management: 23 | 24 | * [poetry](https://python-poetry.org/) is recommended as it handles dependency as well as build system. 25 | * You can use `setuptools` and `setup.py` as well for requirements handling through `requires`. They **must** be used for install-able modules. 26 | * `requirements.txt` style should be avoided although you may come across this style a lot. 27 | -------------------------------------------------------------------------------- /docs/python/exceptions.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: exceptions 3 | title: Exception Handling 4 | sidebar_label: Exception Handling 5 | --- 6 | 7 | #### The following convention should be followed for `Exception` handling: 8 | 9 | * `Exception` handling is a must and should be mitigated. 10 | * Do not use bare `except` or `except Exception` which catches all the exception. 11 | - Always be specific on exception. E.g. catch only `FileNotFoundError` if you are say moving a file. 12 | * **User Defined Exceptions**: 13 | - Write your custom error only when your error is not described or fulfilled by [internal exceptions](https://docs.python.org/3/library/exceptions.html). 14 | - Create custom `Exception` class primarily suffixing it with `Error` such as `MyCustomError(Exception)` and use it. 15 | - Always use `Exception` as your parent class for user defined exceptions. Donot use `BaseException`. 16 | * Add traceback to your mitigation. i.e. either `logging` or mails. Donot `pass`. 17 | * The `try` block should be specific to desired exception. Donot use huge code chunk in `try`. Use `else` if needed. 18 | ```python 19 | try: 20 | value = int(some_str) 21 | except ValueError: # when not using exception object 22 | WHEN some_str IS not valid as value. 23 | except TypeError: 24 | WHEN some_str IS OTHER TYPE such as [], () 25 | else: #can be avoided if exceptions are handled and returned. This is in context to try block. 26 | DO SOMETHING WITH VALUE 27 | 28 | try: 29 | value = int(some_str) 30 | except (ValueError, TypeError) as error: 31 | HANDLE BOTH exception and use exception object 32 | else: # If needed 33 | do something when try succeeds. 34 | finally: 35 | codebase to run anyway 36 | ``` 37 | * `finally` can be used if you need to run the block whatever the case. `context` can be used in many cases to avoid `finally`. 38 | * `sys.exc_info` and [`traceback`](https://docs.python.org/3/library/traceback.html) can be used for traceback. 39 | * Please read [this](https://cosmicpercolator.com/2016/01/13/exception-leaks-in-python-2-and-3/) on exceptions handling internals and leaks when referencing exceptions. 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/python/files.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: files 3 | title: Files, Folders & Modules 4 | sidebar_label: Files, Folders & Modules 5 | --- 6 | 7 | #### The following convention should be followed for files, folders and package naming: 8 | 9 | * Name in `snake_case` or descriptive single words all in **lowercase**. E.g. `helper.py` or `sftp_fetcher.py` or `tools` 10 | * Be explicit and descriptive of their functionality. Donot have short and ambiguous file and folder names. 11 | - E.g. `utils.py` or `utils` will describe of utility. 12 | - E.g. `aws_helper.py` will describe helper related to AWS. 13 | * Donot clash names with inbuilt and famous modules. 14 | - E.g. donot use `requests.py` or `list.py` 15 | * Be consistent when you are naming. Go with one form when choosing singular or plural names. i.e. 16 | - `tools`, `utils` or `tool`, `util` but not `tools`, `util` combination. 17 | * When designing OOP styled files, go for `abstract.py`, `base.py` or `parent.py` like files/folders for abstract classes. 18 | -------------------------------------------------------------------------------- /docs/python/functions.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: functions 3 | title: Functions and Methods 4 | sidebar_label: Functions 5 | --- 6 | 7 | #### The following convention should be followed for `def` naming: 8 | 9 | * Avoid inbuilt names. 10 | * `snake_case` or descriptive single word in **lowercase** should be used. 11 | * function names should explain the functionality. 12 | * for bound methods in class `self` should be used for first argument. 13 | * for class methods in class `cls` should be used for first argument. 14 | * `decorators` should be named in function convention. 15 | 16 | 17 | ```python 18 | def get_db_connection(username, db_name): 19 | return connection 20 | 21 | #method 22 | 23 | def get_db_connection(self, username, db_name): 24 | return connection 25 | 26 | 27 | # classmethod 28 | @classmethod 29 | def multiple_param_initializer(cls, cls_param): 30 | return cls(cls_param) 31 | 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/python/general.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: general 3 | title: General Coding Guidelines 4 | sidebar_label: General Coding Guidelines 5 | --- 6 | 7 | #### These are the general guidelines to be followed: 8 | 9 | :::tip 10 | It is recommended to upgrade the package dependency whenever possible although version pinning is a must. 11 | ::: 12 | 13 | * See [tools](tools.md) that can be used in development environment setup to ease your coding process. 14 | * Always use `python3`. **Latest stable** is always recommended. Ensure version is no older than 2 versions back. i.e. if current stable is `3.11` then use atleast `3.9`. 15 | * Indentation should always be **space** and width should always be **4**. 16 | * File size and functionality: 17 | - break files into modules if you feel they have multiple functionalities. 18 | - Always try to adhere to single functionality or single class per file. 19 | - Set a goal of approximate line numbers per file confining to relatable functionality. 20 | * Always go for pythonic syntax 21 | - comprehensions over `map` and loop 22 | - minimal use of `lambda`, use `operator` module with keyfunctions in `sorted`, `groupby` etc. 23 | - ternary with `if else` in same line. Using `and or` clause. i.e. `value and req_value or default` is not **recommended**. 24 | * Imports: 25 | - Always `import` specific namespace. 26 | - Try to use parent namespace for actions. i.e. `import sys: sys.path` or `import sys.path` rather that `from sys import path` 27 | - Never use `import *` i.e. `from MODULE import *` 28 | - use namespace whenever possible. Use alias i.e. `as SOMEOTHERNAMESPACE` for collision of namespace 29 | * If you are using `else` with loops that has `break`. Just comment `#nobreak` for reference as it is for that usage. See [this](http://python-notes.curiousefficiency.org/en/latest/python_concepts/break_else.html) for some clarity. 30 | ```python 31 | for each in each_collection: 32 | if condition: 33 | break 34 | else: #nobreak 35 | WHEN break DOESNOT HAPPEN 36 | 37 | while True: 38 | if condition: 39 | break 40 | else: #nobreak 41 | WHEN break DOESNOT HAPPEN 42 | ``` 43 | * Use `pathlib` for path related use case rather than `os.path` 44 | * Use type annotation or type hints for type safe code especially for newer projects. Look into [tools](tools.md) for inference checker. 45 | * `Docker` can be used for deployment. Use `python` images for [`docker`](https://hub.docker.com/_/python). 46 | * Use `generators` and `yield` instead of data structures for high streams of data. 47 | * Use `itertools`, `functools` for utilities and `collections` for data structures when needed. 48 | * Use `is not` and `is` for `None`, `True` and `False` specific check only. If most cases truthy and falsy can be checked with `if VARNAME:`. 49 | * Strings: 50 | - Adhere to one quote practice. Double quote is recommended. Python doesnot differentiate between **'** or **"**. This may be controlled by `formatter` used as well. 51 | - Should be interpolated with either [fstring](https://www.python.org/dev/peps/pep-0498/) or `.format` methods. Try to avoid `%`. 52 | + `format_map` should be used for key mapped formatting. 53 | + use `fstring` for newer codebase as it is not compatible below version `3.6`. 54 | - `+` can be used for direct string concatenation. Use `join` method for concatenation instead of `+=` when iterating. 55 | * Use `context` whenever supported especially for io related closing actions. 56 | - i.e. `with` statement when supported. 57 | - Always remember to close on exit. i.e. if you open the file `close` on `finally` or better use `with` or `contextlib.closing`. 58 | * **OOP** 59 | - While `python` is an OOP, you can always choose `functions` and `modules` over `class` if there is only one `object` to be created like `Singletons`. 60 | - Use [`abc`](https://docs.python.org/3/library/abc.html) if you need abstraction. Mixins are more famous in python due to multiple inheritance. 61 | + Use `collections` and [`collections.abc`](https://docs.python.org/3/library/collections.abc.html) for data structures designs. 62 | - Use `property` setter getter only when you need readonly attributes. `__` variables can be used for some privacy. 63 | - Use `super` for overrides and parent calls. 64 | - Use inbuilt `dataclasses` if available. Go for `attrs` library if `dataclasses` is not present or you require a much richer library. 65 | - Use `classmethod` decorator for multiple initialization of classes as well as `staticmethod` where needed. 66 | * Use `pdb` as debugger whenever required. Newer code can use `breakpoint` directly. 67 | * Multi-threading can be especially used when we have io bound and network bound multiple operation. Multiprocessing can be used to use multiple cores. 68 | - Recommended module is `concurrent.futures` in most cases. If lower level API is needed there is always `threading` and `multiprocessing` module. 69 | - Be very carefult on threads and locks, so always discuss what you are doing as it may not always be optimized. 70 | - Use `asyncio` for IO bound async flow. This is something new and constantly changing in `python`. There are alternative like `trio` as well. 71 | * Try to use configurations outside python files. Usually they are not git tracked so should be editable by others. Try `settings.py` or `config.py` if you **must**. This cannot be the case for frameworks as they recommend their own practice mostly. 72 | * **Docstrings** in code is a must. Please follow consistent format. **google** style is more readable and should be used except for `numpy` related projects i.e. AI/ML projects where they follow `numpy` style mostly. 73 | - If you must use `rst` style, be consistent with the team. 74 | - Try to be compatible with documenting tool such as `sphinx`. 75 | * Recommended third party modules: 76 | - For Relational Database: 77 | + Use `sqlalchemy` [core](https://docs.sqlalchemy.org/en/13/core/) for DB abstraction. This is particularly helpful when doing testing in `sqlite` and some other database for production. Also, for query and parameters consistency. 78 | + Use `sqlalchemy` [ORM](https://docs.sqlalchemy.org/en/13/orm/) or framework supported **ORM** when using specific framework. 79 | + Use DBAPI drivers such as `pyodbc`, `sqlite`, `mysqlclient` etc only when you donot want `sqlalchemy` dependency or when you are very performance conscious. While the API will be mostly compatible for this as python has DBAPI specification. Parameters binding and some methods may be incompatible or unavailable. **sqlalchemy core is recommended.** 80 | - `requests` for http request stuff. 81 | + `aiohttp` or `httpx` are also good. 82 | - `attrs` for data oriented objects and classes design. If you don't want to use `dataclasses`. 83 | - `pytest` for tests. 84 | -------------------------------------------------------------------------------- /docs/python/logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: logging 3 | title: Logging 4 | sidebar_label: Logging Convention 5 | --- 6 | 7 | #### The following convention should be followed for using `logging` in python: 8 | 9 | * Inbuilt `logging` module is used in most cases. You can look into [structlog](https://www.structlog.org/en/stable/) for more granular logging. 10 | * `logging` is always a must. Use the following levels as required: 11 | - **DEBUG**: log parameters and arguments. Information needed when we need to debug or develop. Should be avoided in production. 12 | - **INFO**: log basic information such as function entry, file being processed et al 13 | - **WARN**: log user security and other warnings that may require attention or may need to be avoided. 14 | - **ERROR**: errors in programs. 15 | - **CRITICAL**: blocking issues or immediate attention issues. 16 | * `logger` is used for naming single logger object. Use `NAME_logger` name for more than one logger when required. 17 | * It is singleton and single threaded by default for given name of the logger. Can be [non-blocking](https://docs.python.org/3/howto/logging-cookbook.html#dealing-with-handlers-that-block) if required. 18 | * See [Logging Cookbook](https://docs.python.org/3/howto/logging-cookbook.html) for reference. 19 | * **ERROR and CRITICAL** levels should be mitigated and informed. 20 | - Always use `exception` method rather than `error` method of `logger` object to log traceback when catching exceptions. 21 | -------------------------------------------------------------------------------- /docs/python/project-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: project-structure 3 | title: Project Structure and Templates 4 | sidebar_label: Project Structure 5 | --- 6 | 7 | #### The following folder structure should be used for projects: 8 | 9 | 10 | * :file_folder: Project Root: 11 | - :memo: pyproject.toml 12 | - :memo: setup.py `and` :memo: setup.cfg (**OPTIONAL**) 13 | 14 | :::info 15 | * If not using `poetry`, `pyproject.toml` file can be omitted as `setup.py` can have dependencies as well. 16 | * `pyproject.toml` can be used for [alternate build system](https://www.python.org/dev/peps/pep-0518/) if needed. 17 | ::: 18 | 19 | * 20 | - :file_folder: docs 21 | * Your documentation 22 | - :file_folder: bin (**OPTIONAL**) => For entrypoint scripts which calls {PROJECT_NAME} 23 | + This can be generated using `setup.py` as well. 24 | - :file_folder: data (**OPTIONAL**) 25 | * Data for project. 26 | 27 | :::tip 28 | * This folder structure can be used as well. It will have **src** folder for more descriptive stature. 29 | + :file_folder: src 30 | - :file_folder: {PROJECT_NAME} 31 | 32 | ::: 33 | * 34 | - :file_folder: {PROJECT_NAME} 35 | + :memo: `__init__.py` 36 | + :memo: `__main__.py` (**OPTIONAL**) => for calling with `python -m` 37 | + :file_folder: utils 38 | + :file_folder: service 39 | + :file_folder: config 40 | - :file_folder: tests 41 | + :file_folder: test of projects 42 | + :memo: conftest.py 43 | - :memo: LICENSE (**OPTIONAL**) 44 | - :memo: README (can be `md` or `rst`) 45 | - :file_folder: :memo: Other files/folders from third parties (**OPTIONAL**) such as tox.ini 46 | 47 | :::note 48 | + **There can be cases where MVC folder structure as well as framework related folder structure can be used.** 49 | - The framework recommended structure should be followed in such case. E.g. `flask`, `django` etc. 50 | + The OOP style cases of class as filename structue is not always necessary or recommended but can be used if needed. 51 | ::: 52 | 53 | 54 | ### Project Template 55 | * [Python Package Authority Sample](https://github.com/pypa/sampleproject) can be used as bootstrap. 56 | * Look into [cookiecutter](https://cookiecutter.readthedocs.io/en/1.7.2/) tool for template generation. 57 | - [List of templates for cookiecutter.](http://cookiecutter-templates.sebastianruml.name/) 58 | -------------------------------------------------------------------------------- /docs/python/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: testing 3 | title: Testing in python 4 | sidebar_label: Testing 5 | --- 6 | 7 | #### Test is integral part of sofware quality and should not be missed. 8 | 9 | 10 | 11 | * Always use `pytest` for testing codes. 12 | + `unittest` provided by standard python can be used too if there is some blockage in using `pytest`. 13 | * `tox` and `nox` are vey good tools especially for CI and multiple version tests. 14 | * `mock` should be used for mocking data. 15 | * `factory_boy` and `faker` can be used for fixtures and fake data. 16 | * `hypothesis` can be used for property testing. 17 | * Testing should be broken to `unit` as well as `functional`. 18 | * Use `coverage` to alert yourself of test coverage. Keep a target of **80 % - 90 %** coverage if **100%** is not achieved. 19 | * Only test the changes you made or functionality you added when testing a codebase of well known frameworks. 20 | * `selenium` as well as `webtest` can be used for web based API testing. 21 | * `jsonschema` and `genson` like tool can be used for JSON validity. 22 | * Always confirm the `schema` when testing Web API response data. 23 | * Passing tests for `merge` should be priority for all projects. 24 | * Tests should always cover: 25 | + **Unit**: for your code units. Please use `mock` for external dependency and side effects. 26 | + **Functional**: Your program functionality. 27 | + **Integration**: Your whole program integration. 28 | 29 | See [tools](tools.md) for packages links. -------------------------------------------------------------------------------- /docs/python/tools.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: tools 3 | title: Tools to use for easing development and maintaining consistency. There are links to readings as well. 4 | sidebar_label: Tools and Libraries 5 | --- 6 | 7 | :::info 8 | These tools can be used along with your development environment and IDE so that you can follow coding conventions better. 9 | ::: 10 | ### Version Management 11 | :::info 12 | These can be used with dependency Management 13 | ::: 14 | * [pyenv](https://github.com/pyenv/pyenv) with [venv](https://github.com/pyenv/pyenv-virtualenv) support. 15 | + [virtualenv](https://virtualenv.pypa.io/en/latest/) 16 | 17 | ### Dependency Management: 18 | * [poetry](https://python-poetry.org/) 19 | + [pipenv](https://pipenv.pypa.io/en/latest/) can be used as well. 20 | 21 | ### Project Templates: 22 | * [cookiecutter](https://cookiecutter.readthedocs.io/en/1.7.2/) 23 | 24 | ### Linters: 25 | * [flake8](https://flake8.pycqa.org/en/latest/) with [plugins](https://github.com/DmytroLitvinov/awesome-flake8-extensions) 26 | * Alternative: [pylint](https://www.pylint.org) 27 | * Alternative: [ruff](https://beta.ruff.rs/docs/) 28 | * [bandit](https://bandit.readthedocs.io/en/latest/) to find common security issues. This can be used with `flake8` as a [plugin](https://pypi.org/project/flake8-bandit/) 29 | 30 | ### Formatters: 31 | * [black](https://black.readthedocs.io/en/stable/) 32 | - Alternative: [autopep8](https://pypi.org/project/autopep8/) 33 | - Alternative: [yapf](https://pypi.org/project/yapf/) 34 | * [isort](https://timothycrosley.github.io/isort/) for sorting only imports in codes. This is OPTIONAL. 35 | - Alternative: [reorder-python-imports](https://github.com/asottile/reorder_python_imports) another way of sorting imports. 36 | 37 | 38 | ### Type Inference 39 | * [mypy](http://mypy-lang.org/index.html) optional static type coding with python through annotations. from Dropbox but most famous in community. 40 | - Alternative: [pyright](https://github.com/microsoft/pyright#readme) from Microsoft. Usually available in VSCode 41 | - Alternative: [pyre](https://pyre-check.org/) from Facebook. 42 | - Alternative: [pytype](https://google.github.io/pytype/) from Google. 43 | 44 | ### Testing: 45 | * [pytest](https://pytest.org) with [plugins](https://docs.pytest.org/en/7.0.x/reference/plugin_list.html) 46 | - Alternative: Inbuilt `unittest` 47 | * [hypothesis](https://hypothesis.readthedocs.io/en/latest/) and [mock](https://docs.python.org/3/library/unittest.mock.html) for data generation and mocking in tests. 48 | * [tox](https://tox.readthedocs.io/en/latest/) for test automation in different `python` version 49 | - Alternative: [nox](https://nox.thea.codes/en/stable/) is `tox` with `python` API i.e. py file settings so can be used if you need any dynamism. 50 | 51 | ### Other tools: 52 | * [faker](https://faker.readthedocs.io/en/master/) for fake data generation. 53 | * [factory_boy](https://factoryboy.readthedocs.io/en/stable/index.html) for fixture generation. 54 | * [coverage](https://coverage.readthedocs.io/en/coverage-5.1/) for checking code coverage of tests. 55 | * [interrogate](https://interrogate.readthedocs.io/en/latest/) for docstring coverage check. 56 | 57 | 58 | 59 | ### Readings and References: 60 | * [Design Patterns](https://python-patterns.guide/) 61 | * [Official Documentation](https://docs.python.org/3/) 62 | * [Python Code Quality](https://github.com/PyCQA) for the tools like `flake8`, `pylint`, `bandit` etc along with others. 63 | * [Python Packages](https://www.pypa.io/en/latest/) 64 | -------------------------------------------------------------------------------- /docs/python/variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: variables 3 | title: Variables 4 | sidebar_label: Variables 5 | --- 6 | 7 | #### The following convention should be followed for variable naming: 8 | 9 | * `snake_case` or descriptive word all in **lowercase** for any type of variables except `CONSTANTS`. 10 | * `ALL_CAPS` for constants. `python` doesnot have the concept of constants so this is just a convention. 11 | * Variable Privacy is not something that python encourages or supports but there may be case where privacy is required. 12 | - `__{variable_name}` if you want something to denote private. 13 | - `_{variable_name}` if you want something to denote not publicly used or something that may change later. 14 | - `__{variable_name}` are not directly accesible while `_{variable_name}` are. They are just for convention. 15 | * Avoid builtin variable clash. Especially in `globals`. You can attach `_` as suffix to builtin names if you deem the name necessary for your variable. 16 | - `all` or `id` is very tempting variable names but they are builtin methods in python. Go with `all_` or `id_` for these or better yet choose something else as a name. 17 | * While it is tempting to use `i`, `k`, `v` and `f` especially in contexts and for loops. Please avoid them. 18 | - use `key`, `value`, `index` instead. 19 | - use descriptive contexts such as `with open(FILENAME) as open_file: pass` rather than `with open(FILENAME) as f: pass` 20 | -------------------------------------------------------------------------------- /docs/rdbms/naming-convention.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: rdbms-naming-convention 3 | title: RDBMS Naming Convention 4 | sidebar_label: Naming Convention 5 | --- 6 | 7 | #### The following convention should be followed for naming RDBMS: 8 | 9 | > Consistency is the best approach. 10 | 11 | * Use lowercase names. e.g. `user`, `username` 12 | * If the name of the table or column must consist of more than one word, use an underscore(`_`) to connect them(i.e. `snake_case`). e.g. `user_account` 13 | * Use `UPPERCASE` for SQL keywords (e.g. `SELECT`, `INSERT`) and built-in functions (e.g. `LOWER()`, `COUNT()`). 14 | * Avoid use of dots, spaces, or dashes in database, schema, table, or column names. 15 | * When naming objects, balance the objective of keeping names short and easy to use with the objective of making names as descriptive as possible. When in doubt, choose the more descriptive name, because the objects in the database may be used by many people over a period of time. 16 | For example use `payment_due_date` instead of `pmdd`. 17 | 18 | ### Database 19 | 20 | Example `dvd_rental`. 21 | 22 | ```sql 23 | -- 24 | -- Good 25 | CREATE DATABASE dvd_rental; 26 | 27 | -- 28 | -- Bad 29 | CREATE DATABASE [dvd rental]; 30 | ``` 31 | 32 | ### Schema 33 | 34 | Schema works as a namespace. 35 | 36 | Example `raw`, `ops`, `util`. 37 | 38 | ```sql 39 | CREATE SCHEMA util; 40 | ``` 41 | 42 | ### Table 43 | 44 | When naming tables, you have two options – either to use the singular name (e.g. `user`) or to use a plural name (e.g. `users`). **Singular table name is preferred.** 45 | 46 | Example `actor`, `staff`, `category`, `film`, `film_category`, `film_actor`, `customer`, `sales`. 47 | 48 | ```sql 49 | CREATE TABLE dbo.actor ( 50 | id INT UNSIGNED NOT NULL AUTO_INCREMENT, 51 | first_name VARCHAR(45) NOT NULL, 52 | last_name VARCHAR(45) NOT NULL, 53 | created_at TIMESTAMP NOT NULL 54 | ); 55 | ``` 56 | 57 | ### View 58 | 59 | Prefix views with `vw_` to make them obvious. 60 | 61 | Example `vw_actor_info`, `vw_staff_list`, `vw_film_list`, `vw_customer_list`, `vw_sales_by_category` 62 | 63 | ```sql 64 | CREATE VIEW report.vw_staff_list 65 | AS 66 | SELECT 67 | s.staff_id AS staff_id, 68 | CONCAT(s.first_name, ' ', s.last_name) AS name, 69 | a.address AS address, 70 | a.postal_code AS zip_code, 71 | a.phone AS phone, 72 | s.store_id AS store_id 73 | FROM dbo.staff AS s 74 | JOIN dbo.address AS a 75 | ON s.address_id = a.address_id; 76 | ``` 77 | 78 | ### Procedure 79 | 80 | Example `mark_as_expired`, `sync_actor_rating`. 81 | 82 | ```sql 83 | CREATE OR ALTER PROCEDURE automation.mark_as_expired () 84 | AS 85 | BEGIN 86 | -- Statements here 87 | END; 88 | ``` 89 | 90 | 91 | ### Function 92 | 93 | Example `get_capitalized_text`, `calculate_actor_rating`. 94 | 95 | ```sql 96 | CREATE OR ALTER FUNCTION util.get_capitalized_text ( 97 | @param_1 VARCHAR(50), 98 | @param_2 VARCHAR(50) 99 | ) 100 | RETURNS VARCHAR(255) 101 | AS 102 | BEGIN 103 | DECLARE @result VARCHAR(255); 104 | 105 | -- 106 | -- Statements to set result 107 | 108 | RETURN @result; 109 | END; 110 | ``` 111 | 112 | ## Constraints 113 | 114 | Two popular way of naming a constraints uses either abbreviation or the short name of the constraint type. 115 | It's a user preference to use one or the other but make sure they are used consistently everywhere. 116 | 117 | | Constraints | Abbreviation | Short Name | 118 | |:------------|:------------:|:-----------:| 119 | | Primary Key | pk | primary | 120 | | Foreign Key | fk | foreign | 121 | | Unique | uc | unique | 122 | | Check | chk | check | 123 | 124 | When naming a constraint use the following template (replace `` using the above table) as reference: 125 | 126 | ``` 127 | ___... 128 | ``` 129 | 130 | ### Primary Key Constraint 131 | 132 | ```sql 133 | ALTER TABLE dbo.actor 134 | ADD CONSTRAINT pk_actor_id PRIMARY KEY (id); 135 | ``` 136 | 137 | ### Foreign Key Constraint 138 | 139 | ```sql 140 | ALTER TABLE dbo.film 141 | ADD CONSTRAINT fk_film_actor_id FOREIGN KEY (actor_id) REFERENCES actor(id); 142 | ``` 143 | 144 | ### Unique Constraint 145 | 146 | ```sql 147 | ALTER TABLE dbo.user_account 148 | ADD CONSTRAINT uc_user_account_email UNIQUE (email); 149 | ``` 150 | 151 | ### Check Constraint 152 | 153 | ```sql 154 | ALTER TABLE dbo.user 155 | ADD CONSTRAINT chk_user_age CHECK (age >= 18); 156 | ``` 157 | 158 | ## Indexes 159 | 160 | When naming a index use the following template as reference: 161 | 162 | ``` 163 | ___... 164 | ``` 165 | 166 | *Note: Like constraint, the prefix can be either the abbreviation(`idx`) or `index` itself. Make sure you are using them consistently with constraint name.* 167 | 168 | Example `idx_user_account_first_name`, `idx_user_account_username_email`. 169 | 170 | ```sql 171 | CREATE INDEX idx_user_account_username_email 172 | ON user_account(username, email); 173 | ``` 174 | -------------------------------------------------------------------------------- /docs/rest-api/delete.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: delete 3 | title: Delete Method 4 | sidebar_label: DELETE 5 | --- 6 | 7 | As the name applies, **DELETE** APIs are used to delete resources (identified by the Request-URI). 8 | 9 | A successful response of DELETE requests SHOULD be HTTP response code 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has been queued, or 204 (No Content) if the action has been performed but the response does not include an entity. 10 | 11 | DELETE operations are idempotent. If you DELETE a resource, it’s removed from the collection of resources. Repeatedly calling DELETE API on that resource will not change the outcome – however, calling DELETE on a resource a second time will return a 404 (NOT FOUND) since it was already removed. Some may argue that it makes the DELETE method non-idempotent. It’s a matter of discussion and personal opinion. 12 | 13 | If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable. 14 | 15 | > * **/employees/{employee-id}** 16 | > * **/departments/{department-id}** 17 | 18 | | Response code | Result/Reason | 19 | |---------------------------|------------------------------| 20 | |200 OK | Sucessfully deleted the Enity.| 21 | |401 (Unauthorized) | Invalid Credentials/ Invalid Authentication | 22 | |403 (Forbidden) | Invalid Authorization/ Insufficient rights/ Incorrect Role | 23 | |405 (Method Not allowed) | If API supports methods other than PUT request | 24 | |500 (Internal server error)| Server encountered an unexpected condition that prevented it from fulfilling the request.| 25 | -------------------------------------------------------------------------------- /docs/rest-api/get.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: get 3 | title: Get Method 4 | sidebar_label: GET 5 | --- 6 | 7 | 8 | ### Introduction 9 | 10 | Use **GET requests** to retrieve resource representation/information only – and not to modify it in any way. As GET requests do not change the state of the resource, these are said to be safe methods. Additionally, GET APIs should be **idempotent**, which means that making multiple identical requests must produce the same result every time until another API (POST/PUT/PATCH/DELETE) has changed the state of the resource on the server. 11 | 12 | * **Avoid using request body in GET request** 13 | 14 | * Use `path params` instead of `query params` if its a must value to process a request. This way we can reduce unnucessary validation checks. 15 | 16 | * Use `query params` to filter response or get subset or limited resource. 17 | 18 | ### URL Example 19 | 20 | > * **/employees** 21 | > * **/employees/{employee-id}/leaves** 22 | > * **/employees/{employee-id}/employee-reports** 23 | > * **/employees/{employee-id}/leaves?type={leave-type}&order-by={leave-date}** 24 | 25 | ### Success Response Body 26 | 27 | * Expecting a single resource [**/employees/1**] 28 | 29 | ```yaml 30 | { 31 | "id": 1, 32 | "name": "John Doe", 33 | "email": "johndoe@xyz.com", 34 | "address": "123 Mockingbird Lane", 35 | "city": "New York", 36 | "state": "NY", 37 | "zip": "10001" 38 | } 39 | ``` 40 | 41 | * Expecting collection resource [**/employees**] 42 | 43 | ```yaml 44 | [ 45 | { 46 | "id": 1, 47 | "name": "John Doe", 48 | "email": "johndoe@xyz.com", 49 | "address": "123 Mockingbird Lane", 50 | "city": "New York", 51 | "state": "NY", 52 | "zip": "10001" 53 | }, 54 | { 55 | "id": 2, 56 | "name": "William", 57 | "email": "will@xyz.com", 58 | "address": "123 Mockingbird Lane", 59 | "city": "New York", 60 | "state": "NY", 61 | "zip": "10001" 62 | } 63 | ] 64 | ``` 65 | 66 | ### Error Response Body 67 | 68 | ```yaml 69 | { 70 | "error": "Invalid payoad.", 71 | "detail": { 72 | "name": "This field is required." 73 | } 74 | } 75 | 76 | ``` 77 | 78 | ### Response Header 79 | 80 | Specify `Content-type` header, and it should be `application/json` while returing json response, `application/xml` while returning xml response and so on. 81 | 82 | ### Response code and Results 83 | 84 | | Response code | Result/Reason | 85 | |---------------------------|------------------------------| 86 | |200 OK | Sucessfully Fetched the Enity.
Must include a response body. | 87 | |404 (Not found) | If Entity not found for given ID or is invalid ID| 88 | |405 (Method Not allowed) | If API supports methods other than GET request | 89 | |401 (Unauthorized) | Invalid Credentials/ Invalid Authentication | 90 | |403 (Forbidden) | Invalid Authorization/ Insufficient rights/ Incorrect Role | 91 | |410 (Gone) | Expired link/Server no longer serve this request.| 92 | |500 (Internal server error)| Server encountered an unexpected condition that prevented it from fulfilling the request. | -------------------------------------------------------------------------------- /docs/rest-api/headers.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: headers 3 | title: Headers Best Practices 4 | sidebar_label: Headers 5 | --- 6 | 7 | #### The following convention should be followed for REST API Headers 8 | 9 | * Headers names should be **noun** and should be **Captialised-Case** separated by **(-)**. e.g **Token-Key**, **Account-ID**, **Tenant-ID** etc 10 | 11 | * For cases like Acronym, use acronyms itself. eg. *PID-value*, *PIN* 12 | 13 | * Headers can be used for meta information that the API carries for e.g 14 | * Authentication 15 | * Authorization 16 | * Versioning the API 17 | * Content-Type 18 | * Caching etc 19 | * More Examples 20 | 21 | * Avoid using headers for business logic 22 | - Do avoid custom headers and confine with standard ones almost all the time. 23 | 24 | 25 | * Use headers for parameters that should not appear in the URL 26 | * for e.g https://api.application.com/users/{id}/fetch?apiKey=abcd123456789 //**BAD Practice** 27 | -------------------------------------------------------------------------------- /docs/rest-api/naming-convention.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: naming-convention 3 | title: Naming Convention 4 | sidebar_label: Naming Convention 5 | --- 6 | 7 | In REST(**REpresentational State Transfer**), primary data **representation** is called **Resource**. Having a strong and consistent REST resource naming strategy – will definitely prove one of the best design decisions in the long term. 8 | 9 | * Use **noun** and **hyphenated-lower-case** for CRUD operations to an entity/resource/document. The **GET/POST/PUT/DELETE/PATCH** requests represents the corresponding CRUD operation for the following resources like employees, reports, leaves. 10 | 11 | > * **/employees** 12 | > * **/employees/{employee-id}/leaves** 13 | > * **/employees/{employee-id}/employee-reports** 14 | 15 | * For cases of executable functions besides a basic CRUD operations, use **verb** and **hyphenated-lower-case**. 16 | 17 | > * **/customer/{customer-id}/check-validity** 18 | > * **/customer/{customer-id}/cart/checkout** 19 | 20 | * Use forward slash (/) to indicate hierarchical relationships 21 | 22 | > **/customers/{customer-id}/accounts/{account-id}/balance** 23 | > **/category/{cateogry-id}/products/{product-id}/balance** 24 | 25 | * Do not use trailing forward slash (/) in URIs 26 | 27 | > * **/employees** //Good practice 28 | > * **/employees/{employee-id}/leaves/** //Bad practice 29 | 30 | * Use hyphens (-) to improve the readability of URIs 31 | 32 | > * **/employees/{employee-id}/employee-reports** //Readable 33 | > * **/customer/{customer-id}/check-validity** //Readable 34 | > 35 | > * **/employees/{employee-id}/employeeReports** //Less Readable 36 | > * **/customer/{customer-id}/checkValidity** //Less Readable 37 | 38 | * Do not use file extentions and underscores 39 | 40 | > * **/employees/{employee-id}/employee-reports.pdf** /*Bad Practice*/ 41 | > * **/employees/{employee-id}/employee_reports** /*Bad Practice*/ 42 | 43 | * Never use CRUD function names in URIs 44 | 45 | URIs should not be used to indicate that a CRUD function is performed. URIs should be used to uniquely identify resources and not any action upon them. HTTP request methods should be used to indicate which CRUD function is performed. 46 | 47 | > * GET Request **/employees** // Get all employees 48 | > * POST Request **/employees** // Create new employees 49 | > * GET Request **/employees/{employee-id}** // Get one employee with given id 50 | > * PUT Request **/employees/{employee-id}** // Update one employee with given id 51 | > * DELETE Request **/employees/{employee-id}** // Delete one employee with given id -------------------------------------------------------------------------------- /docs/rest-api/patch.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: patch 3 | title: Patch Method 4 | sidebar_label: PATCH 5 | --- 6 | 7 | PATCH is used for **modify** capabilities. The PATCH request only needs to contain the changes to the resource, not the complete resource. 8 | 9 | This resembles PUT, but the body contains a set of instructions describing how a resource currently residing on the server should be modified to produce a new version.PATCH is neither safe nor idempotent. However, a PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame. Collisions from multiple PATCH requests may be more dangerous than PUT collisions because some patch formats need to operate from a known base-point or else they will corrupt the resource. Clients using this kind of patch application should use a conditional request such that the request will fail if the resource has been updated since the client last accessed the resource. 10 | 11 | *PATCH request can usually be used to update the status of resource like from `pending` to `accepted`, `active` to `expired`* 12 | 13 | > * **/employees/{employee-id}** 14 | > * **/departments/{department-id}** 15 | 16 | ### Request Body 17 | 18 | * Patch updating a single resource [**/employees/1**] 19 | 20 | ```yaml 21 | { 22 | "email": "johndoe@xyz.com" 23 | } 24 | ``` 25 | 26 | * Creating collection resource [**/employees**] 27 | 28 | ```yaml 29 | [ 30 | { 31 | "id":"1", 32 | "email": "johndoe@xyz.com" 33 | }, 34 | { 35 | "id":"2", 36 | "address": "123 Mockingbird Lane" 37 | } 38 | ] 39 | ``` 40 | 41 | ### Response Body 42 | 43 | * Patch updating a single resource [**/employees**] 44 | 45 | ```yaml 46 | { 47 | "id":"1", 48 | "email": "johndoe@xyz.com" 49 | } 50 | ``` 51 | 52 | * Patch updating collection resource [**/employees**] 53 | 54 | ```yaml 55 | [ 56 | { 57 | "id":"1", 58 | "email": "johndoe@xyz.com" 59 | }, 60 | { 61 | "id":"2", 62 | "address": "123 Mockingbird Lane" 63 | } 64 | ] 65 | ``` 66 | 67 | ### Error Response Body 68 | 69 | ```yaml 70 | { 71 | "error": "Invalid payoad.", 72 | "detail": { 73 | "name": "This field is required." 74 | } 75 | } 76 | 77 | ``` 78 | 79 | | Response code | Result/Reason | 80 | |---------------------------|------------------------------| 81 | |200 OK | Sucessfully updated the Enity.
Must include a response body. | 82 | |204 (No Content) | When the REST API declines to send back any status message or representation in the response message’s body. Must not contains the response body| 83 | |401 (Unauthorized) | Invalid Credentials/ Invalid Authentication | 84 | |403 (Forbidden) | Invalid Authorization/ Insufficient rights/ Incorrect Role | 85 | |400 (Bad Request) | Bad request object | validation error | 86 | |404 (Not found) | If ID not found or invalid| 87 | |405 (Method Not allowed) | If API supports methods other than PUT request | 88 | |500 (Internal server error)| Server encountered an unexpected condition that prevented it from fulfilling the request.| 89 | -------------------------------------------------------------------------------- /docs/rest-api/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: post 3 | title: Post Method 4 | sidebar_label: POST 5 | --- 6 | 7 | Use **POST requests** to create new subordinate resources, e.g., a file is subordinate to a directory containing it or a row is subordinate to a database table. Talking strictly in terms of REST, POST methods are used to create a new resource into the collection of resources.Note that POST is **neither safe nor idempotent**, and invoking two identical POST requests will result in two different resources containing the same information (except resource ids). 8 | 9 | > * **/employees** 10 | > * **/departments** 11 | 12 | ### Request Body 13 | 14 | * Creating a single resource [**/employees**] 15 | 16 | ```yaml 17 | { 18 | "name": "John Doe", 19 | "email": "johndoe@xyz.com", 20 | "address": "123 Mockingbird Lane", 21 | "city": "New York", 22 | "state": "NY", 23 | "zip": "10001" 24 | } 25 | ``` 26 | 27 | * Creating collection resource [**/employees**] 28 | 29 | ```yaml 30 | [ 31 | { 32 | "name": "John Doe", 33 | "email": "johndoe@xyz.com", 34 | "address": "123 Mockingbird Lane", 35 | "city": "New York", 36 | "state": "NY", 37 | "zip": "10001" 38 | }, 39 | { 40 | "name": "William", 41 | "email": "will@xyz.com", 42 | "address": "123 Mockingbird Lane", 43 | "city": "New York", 44 | "state": "NY", 45 | "zip": "10001" 46 | } 47 | ] 48 | ``` 49 | 50 | ### Response Body 51 | 52 | * Creating a single resource [**/employees**] 53 | 54 | ```yaml 55 | { 56 | "id":"1", 57 | "name": "John Doe", 58 | "email": "johndoe@xyz.com", 59 | "address": "123 Mockingbird Lane", 60 | "city": "New York", 61 | "state": "NY", 62 | "zip": "10001" 63 | } 64 | ``` 65 | 66 | * Creating collection resource [**/employees**] 67 | 68 | ```yaml 69 | [ 70 | { 71 | "id":"1", 72 | "name": "John Doe", 73 | "email": "johndoe@xyz.com", 74 | "address": "123 Mockingbird Lane", 75 | "city": "New York", 76 | "state": "NY", 77 | "zip": "10001" 78 | }, 79 | { 80 | "id":"2", 81 | "name": "William", 82 | "email": "will@xyz.com", 83 | "address": "123 Mockingbird Lane", 84 | "city": "New York", 85 | "state": "NY", 86 | "zip": "10001" 87 | } 88 | ] 89 | ``` 90 | 91 | ### Error Response Body 92 | 93 | ```yaml 94 | { 95 | "error": "Invalid payoad.", 96 | "detail": { 97 | "name": "This field is required." 98 | } 99 | } 100 | 101 | ``` 102 | 103 | | Response code | Result/Reason | 104 | |---------------------------|------------------------------| 105 | |201 (Created) | Sucessfully Created the Enity.
Must include a response body. | 106 | |202 (Accepted) | Actions that take a long while to process/ Batch/Queue Oriented Process Or resource will be created as a result of future processing | 107 | |204 (No Content) | When the REST API declines to send back any status message or representation in the response message’s body. Must not contains the response body| 108 | |401 (Unauthorized) | Invalid Credentials/ Invalid Authentication | 109 | |403 (Forbidden) | Invalid Authorization/ Insufficient rights/ Incorrect Role | 110 | |400 (Bad Request) | Bad request object | validation error | 111 | |405 (Method Not allowed) | If API supports methods other than POST request | 112 | |500 (Internal server error)| Server encountered an unexpected condition that prevented it from fulfilling the request.| 113 | -------------------------------------------------------------------------------- /docs/rest-api/put.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: put 3 | title: Put Method 4 | sidebar_label: PUT 5 | --- 6 | 7 | Use **PUT** APIs primarily to update existing resource (if the resource does not exist, then API may decide to create a new resource or not). If a new resource has been created by the PUT API, the origin server MUST inform the user agent via the HTTP response code 201 (Created) response and if an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. 8 | 9 | > * **/employees/{employee-id}** 10 | > * **/departments/{department-id}** 11 | 12 | ### Request Body 13 | 14 | * Updating a single resource [**/employees/1**] 15 | 16 | ```yaml 17 | { 18 | "id":"1", 19 | "name": "John Doe", 20 | "email": "johndoe@xyz.com", 21 | "address": "123 Mockingbird Lane", 22 | "city": "New York", 23 | "state": "NY", 24 | "zip": "10001" 25 | } 26 | ``` 27 | 28 | * Creating collection resource [**/employees**] 29 | 30 | ```yaml 31 | [ 32 | { 33 | "id":"1", 34 | "name": "John Doe", 35 | "email": "johndoe@xyz.com", 36 | "address": "123 Mockingbird Lane", 37 | "city": "New York", 38 | "state": "NY", 39 | "zip": "10001" 40 | }, 41 | { 42 | "id":"2", 43 | "name": "William", 44 | "email": "will@xyz.com", 45 | "address": "123 Mockingbird Lane", 46 | "city": "New York", 47 | "state": "NY", 48 | "zip": "10001" 49 | } 50 | ] 51 | ``` 52 | 53 | ### Response Body 54 | 55 | * Updating a single resource [**/employees**] 56 | 57 | ```yaml 58 | { 59 | "id":"1", 60 | "name": "John Doe", 61 | "email": "johndoe@xyz.com", 62 | "address": "123 Mockingbird Lane", 63 | "city": "New York", 64 | "state": "NY", 65 | "zip": "10001" 66 | } 67 | ``` 68 | 69 | * Updating collection resource [**/employees**] 70 | 71 | ```yaml 72 | [ 73 | { 74 | "id":"1", 75 | "name": "John Doe", 76 | "email": "johndoe@xyz.com", 77 | "address": "123 Mockingbird Lane", 78 | "city": "New York", 79 | "state": "NY", 80 | "zip": "10001" 81 | }, 82 | { 83 | "id":"2", 84 | "name": "William", 85 | "email": "will@xyz.com", 86 | "address": "123 Mockingbird Lane", 87 | "city": "New York", 88 | "state": "NY", 89 | "zip": "10001" 90 | } 91 | ] 92 | ``` 93 | 94 | ### Error Response Body 95 | 96 | ```yaml 97 | { 98 | "error": "Invalid payoad.", 99 | "detail": { 100 | "name": "This field is required." 101 | } 102 | } 103 | 104 | ``` 105 | 106 | | Response code | Result/Reason | 107 | |---------------------------|------------------------------| 108 | |200 OK | Sucessfully updated the Enity.
Must include a response body. | 109 | |204 (No Content) | When the REST API declines to send back any status message or representation in the response message’s body. Must not contains the response body| 110 | |401 (Unauthorized) | Invalid Credentials/ Invalid Authentication | 111 | |403 (Forbidden) | Invalid Authorization/ Insufficient rights/ Incorrect Role | 112 | |400 (Bad Request) | Bad request object | validation error | 113 | |404 (Not found) | If ID not found or invalid| 114 | |405 (Method Not allowed) | If API supports methods other than PUT request | 115 | |500 (Internal server error)| Server encountered an unexpected condition that prevented it from fulfilling the request.| 116 | -------------------------------------------------------------------------------- /docs/rest-api/security.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: security 3 | title: Security 4 | sidebar_label: Security 5 | --- 6 | 7 | ## Best Practices to Secure REST APIs 8 | 9 | * Always Use HTTPS.If you use HTTP 2, to improve performance – you can even send multiple requests over a single connection, that way you avoid the complete TCP and SSL handshake overhead on later requests. 10 | 11 | * Never expose information on URLs. //Bad practice 12 | 13 | * Consider using token based authentication like OAUTH2 14 | 15 | * Consider Adding Timestamp in Request 16 | 17 | * Log each request and response data 18 | 19 | * Validate and sanitize incoming requests against data types, injections 20 | -------------------------------------------------------------------------------- /docs/rest-api/status-code.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: status-code 3 | title: Status Code Usage 4 | sidebar_label: Status Code 5 | --- 6 | 7 | ### Status Code are integral part of HTTP as well as REST API and should be used to differentiate different responses. These should be used by clients according to explanation. 8 | 9 | 10 | 11 | Most of the explanation on status code is provided in link below: 12 | 13 | [Status Code Check](https://httpstatus.com/) 14 | 15 | [Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) 16 | 17 | In many cases REST based frameworks tend to handle status codes. 18 | 19 | Some status code to be considered are: 20 | 21 | * `200` for generic successful response. 22 | * `201` for creation of resources. Usually with `POST` request. 23 | * `204` for successful request processing but no response content required. 24 | - Usually with `DELETE` and `PATCH` `PUT` request. `HEAD` can be another method where this can be used. 25 | 26 | 27 | * `400` generic client issues. 28 | * `401` usually authentication and authorization issues. 29 | * `403` usually permission issues. We should differentiate our response between `401` and `403` 30 | - `401` there is no authorization 31 | - `403` there is authentication but no permission. 32 | * `404` the resource that client wanted is Not Found. 33 | * `405` the HTTP request method is not allowed. -------------------------------------------------------------------------------- /docs/rest-api/versioning.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: versioning 3 | title: Versioning 4 | sidebar_label: Versioning 5 | --- 6 | 7 | ## Four common REST API versioning strategies 8 | 9 | ### Versioning through URI Path (*recommended*) 10 | 11 | > 12 | > 13 | > One way to version a REST API is to include the version number in the URI path.This solution often uses URI routing to point to a specific version of the API. Because cache keys (in this situation URIs) are changed by version, clients can easily cache resources. When a new version of the REST API is released, it is perceived as a new entry in the cache. 14 | 15 | ### Versioning through custom header 16 | 17 | > curl -H "API-Version: 1.0" 18 | > 19 | > This approach doesn’t clutter the URI with versioning information. 20 | 21 | ### Versioning through query parameters 22 | 23 | > 24 | > 25 | >Another option for versioning a REST API is to include the version number as a query parameter. 26 | 27 | ### Versioning through content negotiation 28 | 29 | > curl -H "Accept: application/vnd.xm.device+json; version=1" 30 | > 31 | > The last strategy we are addressing is versioning through content negotiation. 32 | > 33 | > This approach allows us to version a single resource representation instead of versioning the entire API which gives us a more granular control over versioning. It also creates a smaller footprint in the code base as we don’t have to fork the entire application when creating a new version. Another advantage of this approach is that it doesn’t require implementing URI routing rules introduced by versioning through the URI path. 34 | > 35 | > One of the drawbacks of this approach is that it is less accessible than URI-versioned APIs: Requiring HTTP headers with media types makes it more difficult to test and explore the API using a browser. 36 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Leapfrog Coding Guidelines', 3 | tagline: 'Coding guidelines for projects at Leapfrog Technology', 4 | url: 'https://coding-guidelines.lftechnology.com', 5 | baseUrl: '/', 6 | favicon: 'img/icon.png', 7 | organizationName: 'lftechnology', // Usually your GitHub org/user name. 8 | projectName: 'coding-guidelines', // Usually your repo name. 9 | themeConfig: { 10 | navbar: { 11 | title: 'Leapfrog Coding Guidelines', 12 | logo: { 13 | alt: 'Leapfrog Technology Logo', 14 | src: 'img/icon.png', 15 | }, 16 | items: [ 17 | { 18 | href: 'https://github.com/leapfrogtechnology/coding-guidelines', 19 | label: 'GitHub', 20 | position: 'right', 21 | }, 22 | ], 23 | }, 24 | footer: { 25 | style: 'dark', 26 | links: [ 27 | { 28 | title: 'Community', 29 | items: [ 30 | { 31 | label: 'Facebook', 32 | href: 'https://www.facebook.com/lftechnology', 33 | }, 34 | { 35 | label: 'Twitter', 36 | href: 'https://twitter.com/lftechnology', 37 | }, 38 | { 39 | label: 'LinkedIn', 40 | href: 'https://www.linkedin.com/company/lftechnology', 41 | }, 42 | { 43 | label: 'Instagram', 44 | href: 'https://www.instagram.com/lftechnology', 45 | }, 46 | ], 47 | }, 48 | { 49 | title: 'More', 50 | items: [ 51 | { 52 | label: 'Blog', 53 | to: 'https://www.lftechnology.com/blog', 54 | }, 55 | { 56 | label: 'GitHub', 57 | href: 'https://github.com/leapfrogtechnology', 58 | }, 59 | ], 60 | }, 61 | ], 62 | copyright: `Copyright © ${new Date().getFullYear()} Leapfrog Technology, Inc.`, 63 | }, 64 | }, 65 | presets: [ 66 | [ 67 | '@docusaurus/preset-classic', 68 | { 69 | docs: { 70 | sidebarPath: require.resolve('./sidebars.js'), 71 | editUrl: 72 | 'https://github.com/leapfrogtechnology/coding-guidelines/edit/master/', 73 | }, 74 | theme: { 75 | customCss: require.resolve('./src/css/custom.css'), 76 | }, 77 | }, 78 | ], 79 | ], 80 | plugins: [ 81 | [ 82 | 'pwa', 83 | { 84 | debug: false, 85 | offlineModeActivationStrategies: [ 86 | 'appInstalled', 87 | 'standalone', 88 | 'queryString', 89 | ], 90 | pwaHead: [ 91 | { 92 | tagName: 'link', 93 | rel: 'icon', 94 | href: 'img/icon.png', 95 | }, 96 | { 97 | tagName: 'link', 98 | rel: 'manifest', 99 | href: 'manifest.json', 100 | }, 101 | { 102 | tagName: 'meta', 103 | name: 'theme-color', 104 | content: 'rgb(37, 194, 160)', 105 | }, 106 | { 107 | tagName: 'meta', 108 | name: 'apple-mobile-web-app-capable', 109 | content: 'yes', 110 | }, 111 | { 112 | tagName: 'meta', 113 | name: 'apple-mobile-web-app-status-bar-style', 114 | content: '#000', 115 | }, 116 | { 117 | tagName: 'link', 118 | rel: 'apple-touch-icon', 119 | href: 'img/icon.png', 120 | }, 121 | { 122 | tagName: 'link', 123 | rel: 'mask-icon', 124 | href: 'img/icon.png', 125 | color: 'rgb(62, 204, 94)', 126 | }, 127 | { 128 | tagName: 'meta', 129 | name: 'msapplication-TileImage', 130 | content: 'img/icon.png', 131 | }, 132 | { 133 | tagName: 'meta', 134 | name: 'msapplication-TileColor', 135 | content: '#000', 136 | }, 137 | ], 138 | }, 139 | ], 140 | ], 141 | }; 142 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@leapfrogtechnology/coding-guidelines", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "docusaurus start", 7 | "build": "docusaurus build", 8 | "swizzle": "docusaurus swizzle", 9 | "deploy": "docusaurus deploy", 10 | "serve": "docusaurus serve", 11 | "clear": "docusaurus clear" 12 | }, 13 | "dependencies": { 14 | "@docusaurus/core": "^2.4.1", 15 | "@docusaurus/preset-classic": "^2.4.1", 16 | "classnames": "^2.3.2", 17 | "react": "^17.0.2", 18 | "react-dom": "^17.0.2" 19 | }, 20 | "browserslist": { 21 | "production": [ 22 | ">0.2%", 23 | "not dead", 24 | "not op_mini all" 25 | ], 26 | "development": [ 27 | "last 1 chrome version", 28 | "last 1 firefox version", 29 | "last 1 safari version" 30 | ] 31 | }, 32 | "devDependencies": { 33 | "@docusaurus/plugin-pwa": "^2.4.1", 34 | "markdownlint": "^0.26.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | { 3 | "docs": { 4 | "Overview": [ 5 | "introduction", 6 | "general/clean-code", 7 | ], 8 | "REST API": [ 9 | "rest-api/headers", 10 | { 11 | "type": "category", 12 | "label": "Methods", 13 | "items": [ 14 | "rest-api/naming-convention", 15 | "rest-api/get", 16 | "rest-api/post", 17 | "rest-api/put", 18 | "rest-api/patch", 19 | "rest-api/delete" 20 | ] 21 | }, 22 | "rest-api/status-code", 23 | "rest-api/security", 24 | "rest-api/versioning" 25 | ], 26 | "Git & GitHub": [ 27 | "git/pull-request-guidelines", 28 | "git/code-review-checklist", 29 | "git/branch-naming-convention", 30 | "git/branching-strategy", 31 | "git/smart-commit", 32 | "git/pull-request-template", 33 | { 34 | "type": "category", 35 | "label": "Release Management", 36 | "items": [ 37 | "git/tagging" 38 | ] 39 | } 40 | ], 41 | "Python": [ 42 | "python/environment-and-dependency", 43 | "python/project-structure", 44 | { 45 | "type": "category", 46 | "label": "Practices and Tools", 47 | "items": [ 48 | "python/general", 49 | "python/tools" 50 | ] 51 | }, 52 | "python/docstrings", 53 | { 54 | "type": "category", 55 | "label": "Naming Convention", 56 | "items": [ 57 | "python/files", 58 | "python/variables", 59 | "python/functions", 60 | "python/classes" 61 | ] 62 | }, 63 | "python/exceptions", 64 | "python/logging", 65 | "python/testing" 66 | ], 67 | "JavaScript": [ 68 | { 69 | "type": "category", 70 | "label": "Naming Convention", 71 | "items": [ 72 | "javascript/variables", 73 | "javascript/functions", 74 | "javascript/classes" 75 | ] 76 | }, 77 | { 78 | "type": "category", 79 | "label": "General Coding Guidelines", 80 | "items": [ 81 | "javascript/js-general-guidelines", 82 | ] 83 | } 84 | ], 85 | "Java": [ 86 | { 87 | "type": "category", 88 | "label": "Naming Convention", 89 | "items": [ 90 | "java/packages", 91 | "java/classes", 92 | "java/interfaces", 93 | "java/variables", 94 | "java/functions" 95 | ], 96 | }, 97 | "java/logging", 98 | "java/tools", 99 | { 100 | "type": "category", 101 | "label": "Effective Java", 102 | "items": [ 103 | "java/effective-java" 104 | ] 105 | } 106 | ], 107 | "NoSQL" : [ 108 | { 109 | "type": "category", 110 | "label": "Document DB", 111 | "items": [ 112 | "nosql/documentdb/document-db-naming-convention", 113 | "nosql/documentdb/one-to-one-relationship", 114 | "nosql/documentdb/one-to-many-relationship", 115 | "nosql/documentdb/many-to-many-relationship" 116 | ] 117 | } 118 | ], 119 | "RDBMS": [ 120 | "rdbms/rdbms-naming-convention" 121 | ] 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | :root { 10 | --ifm-color-primary: #25c2a0; 11 | --ifm-color-primary-dark: rgb(33, 175, 144); 12 | --ifm-color-primary-darker: rgb(31, 165, 136); 13 | --ifm-color-primary-darkest: rgb(26, 136, 112); 14 | --ifm-color-primary-light: rgb(70, 203, 174); 15 | --ifm-color-primary-lighter: rgb(102, 212, 189); 16 | --ifm-color-primary-lightest: rgb(146, 224, 208); 17 | --ifm-code-font-size: 95%; 18 | } 19 | 20 | .docusaurus-highlight-code-line { 21 | background-color: rgb(72, 77, 91); 22 | display: block; 23 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 24 | padding: 0 var(--ifm-pre-padding); 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classnames from 'classnames'; 3 | 4 | import Layout from '@theme/Layout'; 5 | import Link from '@docusaurus/Link'; 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 8 | 9 | import styles from './index.module.css'; 10 | 11 | function Home() { 12 | const context = useDocusaurusContext(); 13 | const { siteConfig = {} } = context; 14 | 15 | return ( 16 | 17 |
18 |
19 | {siteConfig.title} 20 |

{siteConfig.tagline} 📓

21 | 25 | Let's Go! 26 | 27 |
28 |
29 |
30 | ); 31 | } 32 | 33 | export default Home; 34 | -------------------------------------------------------------------------------- /src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | .heroBanner { 2 | padding: 4rem; 3 | text-align: center; 4 | } 5 | 6 | .heroLogo { 7 | height: 3.5rem; 8 | margin-bottom: 1rem; 9 | } 10 | 11 | .heroTitle { 12 | font-size: 2rem; 13 | } 14 | -------------------------------------------------------------------------------- /static/clean-code/page-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/clean-code/page-1.png -------------------------------------------------------------------------------- /static/clean-code/page-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/clean-code/page-2.png -------------------------------------------------------------------------------- /static/clean-code/page-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/clean-code/page-3.png -------------------------------------------------------------------------------- /static/clean-code/page-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/clean-code/page-4.png -------------------------------------------------------------------------------- /static/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icon.png -------------------------------------------------------------------------------- /static/img/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-128x128.png -------------------------------------------------------------------------------- /static/img/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-144x144.png -------------------------------------------------------------------------------- /static/img/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-152x152.png -------------------------------------------------------------------------------- /static/img/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-192x192.png -------------------------------------------------------------------------------- /static/img/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-384x384.png -------------------------------------------------------------------------------- /static/img/icons/icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-48x48.png -------------------------------------------------------------------------------- /static/img/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-512x512.png -------------------------------------------------------------------------------- /static/img/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-72x72.png -------------------------------------------------------------------------------- /static/img/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leapfrogtechnology/coding-guidelines/c76b4f02acd818b2665beb6b374302eb6296f69c/static/img/icons/icon-96x96.png -------------------------------------------------------------------------------- /static/img/lf_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 82 | 83 | 84 | 85 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | Coding Standards And Conventions 15 | 16 | 17 | If you are not redirected automatically, follow this link. 18 | 19 | 20 | -------------------------------------------------------------------------------- /static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Leapfrog Coding Guidelines", 3 | "short_name": "Leapfrog Coding Guidelines", 4 | "theme_color": "#1976d2", 5 | "background_color": "#fafafa", 6 | "display": "standalone", 7 | "scope": "./", 8 | "start_url": "./index.html", 9 | "related_applications": [ 10 | { 11 | "platform": "webapp", 12 | "url": "https://www.coding-guidelines.lftechnology.com/manifest.json" 13 | } 14 | ], 15 | "icons": [ 16 | { 17 | "src": "img/icons/icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image/png", 20 | "purpose": "maskable any" 21 | }, 22 | { 23 | "src": "img/icons/icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image/png", 26 | "purpose": "maskable any" 27 | }, 28 | { 29 | "src": "img/icons/icon-128x128.png", 30 | "sizes": "128x128", 31 | "type": "image/png", 32 | "purpose": "maskable any" 33 | }, 34 | { 35 | "src": "img/icons/icon-144x144.png", 36 | "sizes": "144x144", 37 | "type": "image/png", 38 | "purpose": "maskable any" 39 | }, 40 | { 41 | "src": "img/icons/icon-152x152.png", 42 | "sizes": "152x152", 43 | "type": "image/png", 44 | "purpose": "maskable any" 45 | }, 46 | { 47 | "src": "img/icons/icon-192x192.png", 48 | "sizes": "192x192", 49 | "type": "image/png", 50 | "purpose": "maskable any" 51 | }, 52 | { 53 | "src": "img/icons/icon-384x384.png", 54 | "sizes": "384x384", 55 | "type": "image/png", 56 | "purpose": "maskable any" 57 | }, 58 | { 59 | "src": "img/icons/icon-512x512.png", 60 | "sizes": "512x512", 61 | "type": "image/png", 62 | "purpose": "maskable any" 63 | } 64 | ] 65 | } 66 | --------------------------------------------------------------------------------