0

My question is, how to write this in python? Is something like this possible?

How it should work: I'm getting data from an algorithm that will decide which letter to output. If there are certain conditions in the data that should not apply to one character, the conditions should be checked for another character. The data and the conditions are of course more complex than shown here.

Why enums: Because only this small main method has to be written in the algorithm file (iterable). And the conditions of the letters are encapsulated in another file and clearly structured.

enum Letter {
    
    A () {
        public boolean condition(int[] args) {
            if (args[0] > args[1]) return false;
            if (args[1] > args[2]) return false;
            return true;
        }
    },
    
    B () {
        public boolean condition(int[] args) {
            if (args[0] > args[1]) return false;
            if (args[1] < args[2]) return false;
            return true;
        }
    },
    
    C () {
        public boolean condition(int[] args) {
            if (args[0] < args[1]) return false;
            if (args[1] < args[2]) return false;
            return true;
        }
    };
    
    public abstract boolean condition(int[] args);
    
}
public class Alphabet {
    
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        //int[] arr = {1, 2, 1};
        //int[] arr = {3, 2, 1};
        
        for (Letter l : Letter.values()) {
            if (l.condition(arr)) {
                System.out.println(l);
                break;
            }
        }
    }
}
Nanilla
  • 19
  • 4
  • Please, take a look at https://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python. Is that what you need? – Ignatius Reilly Jun 04 '22 at 00:38
  • It looks like you're looking for a `LetterFactory` (named `Alphabet`) class that constructs a Letter instance based on conditions (an iterable of ints) passed to its main factory method? There's no particular advantage in having it be a Python `enum.Enum`? – Grismar Jun 04 '22 at 00:53

1 Answers1

2

While you could shoehorn an Enum into serving this purpose, it'd be much easier to just use a dict or list of functions that you can iterate over, e.g.:

letters = [
    ("A", lambda args: args[0] <= args[1] <= args[2]),
    ("B", lambda args: args[0] <= args[1] >= args[2]),
    ("C", lambda args: args[0] >= args[1] >= args[2]),
]

def alphabet(args):
    print(next(letter for letter, condition in letters if condition(args)))

alphabet([1, 2, 3])  # A
alphabet([1, 2, 1])  # B
alphabet([3, 2, 1])  # C

Or with type annotations (these are optional in Python, but they allow you to do static type analysis/testing similar to what you get in a compiled language, and can make tricky code easier to understand):

from typing import Callable, List, Tuple

Condition = Callable[[List[int]], bool]

letters: List[Tuple[str, Condition]] = [
    ("A", lambda args: args[0] <= args[1] <= args[2]),
    ("B", lambda args: args[0] <= args[1] >= args[2]),
    ("C", lambda args: args[0] >= args[1] >= args[2]),
]

def alphabet(args: List[int]) -> None:
    print(next(letter for letter, condition in letters if condition(args)))

Note that in the type-annotated version, we can just define Condition as a handy type alias for "a function that takes a list of ints and returns a bool". We don't need to actually make a new class or define a new abstract interface, since functions are first-class objects in Python and their interface already fits this use case perfectly.

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • 3
    aside: everyone coming to Python from Java goes through the same journey where they have to break themselves of the "everything needs to be a class" trauma that Java inflicts on you. Once you leave that behind you'll find that the code gets a lot easier to write. :) – Samwise Jun 04 '22 at 01:04