samedi 21 novembre 2020

Python: Better library/class design for intellisense

This is the best analogy I can come up with, similar to my actual problem, and its a bit more interesting, especially for a car enthusiast. Basically I have a library/class before that just takes string as its parameter. The problem with this is that its a bit hard for the users, because they have to know the string/options available to use it. Granted the backend could provide more error descriptions stating what the issue is/or whats available.

In order to make it a bit easier for users to use the library/class, I figured using an enum will help, and users can utilize intellisense to provide what options are available. The below example work fairly well, but the problem is that, it can provide a wrong model for a chosen make. For example Mclaren shouldnt have an F8 model, yet with this implementation, a user can select that.

Yes, the backend can do that check and provide an error stating this Model does not exist for this Make. But was wondering if there is a better way to design this, and package/provide it for users to easily use the library/class. Or is my best bet providing a superset of Make and Model (like my sample code), and the backend just have to do the validation?

In short, the main goals are:

  1. How to help users use the library, and provide them available options thru intellisense
  2. Still be able to have the string representation of the class the same. In this example, basically just have the same print out of the class as before.

sample code:

from enum import Enum


class Make(Enum):
    mclaren = "Mclaren"
    lamborghini = "Lamborghini"
    ferrari = "Ferrari"


class Model(Enum):
    # Mclaren models
    p1 = "P1"
    gt = "Gt"

    # Lamborghini models
    aventador = "Aventador"
    huracan = "Huracan"

    # Ferrari models
    f8 = "F8"
    sf90 = "SF90"


class Car():
    def __init__(self, make, model, option1=None, option2=None):
        self.make = make
        self.model = model
        self.option1 = option1
        self.option2 = option2

    def print_val(self, item):
        if isinstance(item, Enum):
            return item.value
        else:
            return item

    def __str__(self):
        return f"Car: Make: {self.print_val(self.make)} " \
               f"Model: {self.print_val(self.model)} " \
               f"Option1: {self.print_val(self.option1)} " \
               f"Option2: {self.print_val(self.option2)}"


print("String style")
a = Car(make="Mclaren", model="P1")        # example of user's code
print(a)

print("Class style")
a = Car(make=Make.mclaren, model=Model.p1) # example of user's code
print(a)

Output:

String style
Car: Make: Mclaren Model: P1 Option1: None Option2: None
Class style
Car: Make: Mclaren Model: P1 Option1: None Option2: None

Aucun commentaire:

Enregistrer un commentaire