Code examples for my Write Better Python Code series on YouTube.

Overview
Comments
  • Coupling alternative

    Coupling alternative

    Saw your posts on reddit and watched your first video, the one on coupling. Before watching the walk-through, I had a try at improving the "before" code alone. I thought it could be fun to discuss that here, if you or someone else is up to it (btw, thanks for putting this up in a repo, super convenient!). Maybe it's silly. In any case, it's hard to find the right kind of feedback on these kinds of exercises (when you're self-learning and it's not just Hello World with a SyntaxError anymore) ;). And maybe you get something out of it by seeing how viewers "interpret" your content.

    import random
    import string
    from dataclasses import dataclass, field
    from enum import Enum
    from typing import Union
    
    
    class VehicleRegistry:
        def __init__(self, id_length) -> None:
            self.id_length = id_length
    
        def random_id(self):
            length = self.id_length
            id = "".join(random.choices(string.ascii_uppercase, k=length))
            license = f"{id[:2]}-{''.join(random.choices(string.digits, k=2))}-{''.join(random.choices(string.ascii_uppercase, k=2))}"
            return id, license
    
    
    class PropulsionTax(Enum):
        ELECTRIC = 0.02
        COMBUSTION = 0.05
    
    
    @dataclass
    class Vehicle:
        make: str
        model: str
        price: int
        tax_bracket: PropulsionTax
    
        # Include in class data (repr, ...), but do not init it, calculate it later:
        tax: float = field(init=False)
    
        # Straight from the factory, doesn't have any of these yet:
        id: Union[str, None] = None
        license: Union[str, None] = None
    
        def __post_init__(self):
            self.tax = self.price * self.tax_bracket.value
    
    
    class Application:
        def __init__(self, vehicle: Vehicle):
            self.vehicle = vehicle
            self.registry = VehicleRegistry(12)
    
        def register_vehicle(self):
            self.vehicle.id, self.vehicle.license = self.registry.random_id()
    
            print("Registration complete. Vehicle information:")
            print(self.vehicle)
    
    
    vehicle = Vehicle(
        make="Volkswagen",
        model="ID3",
        price=35000,
        tax_bracket=PropulsionTax.ELECTRIC,
    )
    app = Application(vehicle)
    app.register_vehicle()
    

    Comparing to your after code, there are some differences. There are a bunch of assumptions which might be incorrect.

    • Instead of implementing print methods, implement __str__ (or __repr__) and call built-in print on the objects. But wait...
    • When you drafted up your classes by putting type hints at the top, I thought you'd definitely convert them into dataclasses in a wild plot twist! That didn't end up happening, yet those bad boys are perfect for this use case. They have built-in representation for all their member variables, so the previous step is solved automatically.
    • Taxes are an Enum. Advantages:
      • Can be extended (hydrogen!) and used pretty arbitrarily
      • We get nice names/reprs, no hard-coded magic except in that one central place
    • License and ID generation are kind of the same thing. The license strictly depends on the generated ID. We therefore call both methods one after the other anyway, everytime. There's no instance where we call only one of each. So they can be the same thing, one method returning a tuple of ID and license plate.
    • I assumed VehicleRegistry was some kind of office that does... vehicle registrations. As such, it probably uses (again, an assumption) IDs of the same length anyway, for all vehicles. Hence, this is now a parameter to the constructor itself.
    • I thought you'd definitely hand in an Application for a vehicle. This makes sense. You hand in a string representing the vehicle, but we can just hand in the vehicle object itself. Makes it much more dynamic and less coupled, in my view.
    • Maybe the strangest thing to me was how the Application or, rather, its register_vehicle method creates the vehicle. I thought of the process more like real-life:
      1. Vehicle gets created in some car factory, it just exists for now (I just do vehicle = Vehicle(...) on the module level). At that point, it doesn't have a registration ID or license plate yet, but it comes with "empty slots" (defaults of None) for them. This abstraction works especially well for the license plate. Cars literally come with a blank space where that will go later, for which None is the perfect representation.
      2. Now, the consumer takes the car to the registry. They create an Application which has a (as opposed to is a/inheritance) vehicle. Makes sense, the application form contains the vehicle data sheet (the Vehicle dataclass instance object itself).
      3. The registry then only generates a new random ID/license plate for the new car. In the current state, it doesn't need to know/do anything else. This might change, at which point my shit breaks apart.
      4. We "take" the Application to the registry, where we simply slap on the new ID/license plate onto the new car, replacing None.

    I think using dataclasses is a big improvement and nicely showcases the "batteries included" aspect of Python. Lots of boilerplate taken care of for us. Secondly, pulling out the "car creation" process entirely makes things much simpler, too, while being more in line with the metaphore, in my mind. This all leads to very short (cohesive?) functions/methods will quite low coupling.

    Would be happy to hear your or someone else's thoughts on this! Loving the series so far, finally good content that fills the huge gap between Hello World (for which approx. 484092 guides exist) and actually working in the industry.

    opened by alexpovel 3
  • Why string, not str ?

    Why string, not str ?

    https://github.com/ArjanCodes/betterpython/blob/4151e184748856cbb3ea32ff8ef1bcca448e6a68/1%20-%20coupling%20and%20cohesion/coupling-cohesion-after.py#L60

    opened by ozkansen 1
  • Undefined name 'Blog' in type hint

    Undefined name 'Blog' in type hint

    $ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics

    ./betterpython/7 - dealing with errors/monadic-error-handling/example.py:22:35: F821 undefined name 'Blog'
    def fetch_blog(blog_id) -> Result['Blog', Exception]:
                                      ^
    ./betterpython/7 - dealing with errors/monadic-error-handling/example.py:41:27: F821 undefined name 'Blog'
    def blog_to_dict(item) -> 'Blog':
                              ^
    ./betterpython/7 - dealing with errors/monadic-error-handling/example.py:52:28: F821 undefined name 'Blog'
    def verify_access(blog) -> 'Blog':
                               ^
    3     F821 undefined name 'Blog'
    3
    
    opened by cclauss 0
  • Create dependency-inversion-after-comp.py

    Create dependency-inversion-after-comp.py

    Hi Arjan,

    thanks a lot for your videos on YouTube, it's super helpful for me to learn more about Python. You are doing a great work to the community, really appreciating.

    Here is just my simple idea how to (possibly) use composition instead of inheritance in the dependency-inversion-after.py. Please if you have some time, could you check this code and comment what would you change (if anything) and if you think it make sense we could even merge it.

    Thanks again.

    opened by m1009d 0
  • Minor spacing and naming fixes

    Minor spacing and naming fixes

    Hi there.

    I like your examples, so I'd like to propose some minor changes in the SOLID examples. The proposed changes are spacing and naming changes so the code is more consistent with PEP8. I hope this helps out your project!

    opened by mickeybeurskens 0
  • used default dict in api_v2/event instead of normal dict

    used default dict in api_v2/event instead of normal dict

    Defaultdict

    • The functionality of both dictionaries and defualtdict are almost same except for the fact that defualtdict never raises a KeyError.

    • When key is not present it will return --> [] (empty list)

    • This is how it improves the code

    • Before

    if event_type not in subscribers:
        subscribers[event_type] = []
    subscribers[event_type].append(fn)
    
    • After
    subscribers[event_type].append(fn)
    
    opened by ujass 3
  • get rid of redundant class

    get rid of redundant class

    If you find yourself creating a class just to call a function, you probably just needed a function... Also, Enums are better than dictionaries for holding an immutable table as in this demo, and dataclasses make the init declaration for you.

    opened by Motherboard 1
Owner
null
Write Python in Urdu - اردو میں کوڈ لکھیں

UrduPython Write simple Python in Urdu. How to Use Write Urdu code in سامپل۔پے The mappings are as following: "۔": ".", "،":

Saad A. Bazaz 26 Nov 27, 2022
Write Alphabet, Words and Sentences with your eyes.

The-Next-Gen-AI-Eye-Writer The Eye tracking Technique has become one of the most popular techniques within the human and computer interaction era, thi

Rohan Kasabe 2 Apr 5, 2022
Using context-free grammar formalism to parse English sentences to determine their structure to help computer to better understand the meaning of the sentence.

Sentance Parser Executing the Program Make sure Python 3.6+ is installed. Install requirements $ pip install requirements.txt Run the program:

Vaibhaw 12 Sep 28, 2022
This repository contains examples of Task-Informed Meta-Learning

Task-Informed Meta-Learning This repository contains examples of Task-Informed Meta-Learning (paper). We consider two tasks: Crop Type Classification

null 10 Dec 19, 2022
A relatively simple python program to generate one of those reddit text to speech videos dominating youtube.

Reddit text to speech generator A basic reddit tts video generator Current functionality Generate videos for subs based on comments,(askreddit) so rea

Aadvik 17 Dec 19, 2022
Simple Python script to scrape youtube channles of "Parity Technologies and Web3 Foundation" and translate them to well-known braille language or any language

Simple Python script to scrape youtube channles of "Parity Technologies and Web3 Foundation" and translate them to well-known braille language or any

Little Endian 1 Apr 28, 2022
Download videos from YouTube/Twitch/Twitter right in the Windows Explorer, without installing any shady shareware apps

youtube-dl and ffmpeg Windows Explorer Integration Download videos from YouTube/Twitch/Twitter and more (any platform that is supported by youtube-dl)

Wolfgang 226 Dec 30, 2022
Higher quality textures for the Metal Gear Solid series.

Metal Gear Solid: HD Textures Higher quality textures for the Metal Gear Solid series. The goal is to maximize the quality of assets that the engine w

Samantha 6 Dec 6, 2022
Code for the Python code smells video on the ArjanCodes channel.

7 Python code smells This repository contains the code for the Python code smells video on the ArjanCodes channel (watch the video here). The example

null 55 Dec 29, 2022
Code-autocomplete, a code completion plugin for Python

Code AutoComplete code-autocomplete, a code completion plugin for Python.

xuming 13 Jan 7, 2023
Code to use Augmented Shapiro Wilks Stopping, as well as code for the paper "Statistically Signifigant Stopping of Neural Network Training"

This codebase is being actively maintained, please create and issue if you have issues using it Basics All data files are included under losses and ea

Justin Terry 32 Nov 9, 2021
Code for CodeT5: a new code-aware pre-trained encoder-decoder model.

CodeT5: Identifier-aware Unified Pre-trained Encoder-Decoder Models for Code Understanding and Generation This is the official PyTorch implementation

Salesforce 564 Jan 8, 2023
Galois is an auto code completer for code editors (or any text editor) based on OpenAI GPT-2.

Galois is an auto code completer for code editors (or any text editor) based on OpenAI GPT-2. It is trained (finetuned) on a curated list of approximately 45K Python (~470MB) files gathered from the Github. Currently, it just works properly on Python but not bad at other languages (thanks to GPT-2's power).

Galois Autocompleter 91 Sep 23, 2022
Simple python code to fix your combo list by removing any text after a separator or removing duplicate combos

Combo List Fixer A simple python code to fix your combo list by removing any text after a separator or removing duplicate combos Removing any text aft

Hamidreza Dehghan 3 Dec 5, 2022
A python project made to generate code using either OpenAI's codex or GPT-J (Although not as good as codex)

CodeJ A python project made to generate code using either OpenAI's codex or GPT-J (Although not as good as codex) Install requirements pip install -r

TheProtagonist 1 Dec 6, 2021
Repository of the Code to Chatbots, developed in Python

Description In this repository you will find the Code to my Chatbots, developed in Python. I'll explain the structure of this Repository later. Requir

Li-am K. 0 Oct 25, 2022
Python code for ICLR 2022 spotlight paper EViT: Expediting Vision Transformers via Token Reorganizations

Expediting Vision Transformers via Token Reorganizations This repository contain

Youwei Liang 101 Dec 26, 2022
Converts python code into c++ by using OpenAI CODEX.

?? codex_py2cpp ?? OpenAI Codex Python to C++ Code Generator Your Python Code is too slow? ?? You want to speed it up but forgot how to code in C++? ⌨

Alexander 423 Jan 1, 2023