Function arguments (2 or fewer ideally)
Bad:
def create_menu(title, body, button_text, cancellable): # ...
best:
from dataclasses import astuple, dataclass @dataclass class MenuConfig: """A configuration for the Menu. Attributes: title: The title of the Menu. body: The body of the Menu. button_text: The text for the button label. cancellable: Can it be cancelled? """ title: str body: str button_text: str cancellable: bool = False def create_menu(config: MenuConfig): title, body, button_text, cancellable = astuple(config) # ... create_menu( MenuConfig( title="My delicious menu", body="A description of the various items on the menu", button_text="Order now!" ) )
Functions should do one thing
Bad:
def email_clients(clients: List[Client]): """Filter active clients and send them an email. """ for client in clients: if client.active: email(client)
best:
def active_clients(clients: List[Client]) -> Generator[Client]: """Only active clients. """ return (client for client in clients if client.active) def email_client(clients: Iterator[Client]) -> None: """Send an email to a given list of clients. """ for client in clients: email(client)
Avoid conditionals:
Bad:
class Airplane { // ... public function getCruisingAltitude(): int { switch ($this->type) { case '777': return $this->getMaxAltitude() - $this->getPassengerCount(); case 'Air Force One': return $this->getMaxAltitude(); case 'Cessna': return $this->getMaxAltitude() - $this->getFuelExpenditure(); } } }
Good:
interface Airplane { // ... public function getCruisingAltitude(): int; } class Boeing777 implements Airplane { // ... public function getCruisingAltitude(): int { return $this->getMaxAltitude() - $this->getPassengerCount(); } } class AirForceOne implements Airplane { // ... public function getCruisingAltitude(): int { return $this->getMaxAltitude(); } } class Cessna implements Airplane { // ... public function getCruisingAltitude(): int { return $this->getMaxAltitude() - $this->getFuelExpenditure(); } }