-1

I would like to know if there's a way of not implementing two Vector aliases (Vector1 and Vector2), and reusing a single Vector hint.

from typing import Union, TypeVar, Generic, List, Set, Tuple, FrozenSet

Number = Union[int, float]
Vector1 = Union[List[Number], Set[Number], Tuple[Number], FrozenSet[Number]]
Vector2 = Union[List[str], Set[str], Tuple[str], FrozenSet[str]]

def mean(vector: Vector1) -> Number:
    return (sum(vector) / len(vector))

def readPrint(vector: Vector2) -> None:
    for i in vector: print(i)
  • 1
    Your functions would throw an error, have you tried it? – juanpa.arrivillaga Oct 07 '21 at 15:23
  • 1
    You ask about implementation, but your title talks about type hints. – juanpa.arrivillaga Oct 07 '21 at 15:24
  • Could you just please elaborate on what is the purpose of this implementation? python is dynamically typed, you can set you class vector with any of tuple and list, and mean and readPrint would still work. – Guinther Kovalski Oct 07 '21 at 15:33
  • Error? Ah! I didn't put the imports. I will change it. – Amâncio de Noronha Brito Oct 07 '21 at 15:34
  • 1
    Can you clarify what exactly you are asking about? The implementation? The annotations? Something else? Your class does not implement an iterator, so both ``sum(vector)`` and ``for i in vector:`` would not be correct. In that regard, the answer is just "no". – MisterMiyagi Oct 07 '21 at 15:39
  • 1
    @GuintherKovalski I am just practicing, it's not a serious implementation. The whole purpose is to give a hint about the types I am looking forward to work with which are list, set, tuple, and frozenset. I would like be more specific, and say the type of the items inside list, set, tuple, or frozenset. For not creating two aliases, I tried to make a generic class, and use it, nevertheless I don't know if this is good practice. – Amâncio de Noronha Brito Oct 07 '21 at 15:42
  • The functions aren't inside of the class... If they were, it would throw indeed an error. – Amâncio de Noronha Brito Oct 07 '21 at 15:46
  • 2
    Does this answer your question? [How to define a generic type that is not a class?](https://stackoverflow.com/questions/66363364/how-to-define-a-generic-type-that-is-not-a-class) – MisterMiyagi Oct 07 '21 at 15:53
  • 1
    @MisterMiyagi Yeah! It does ^^! Thanks a lot! – Amâncio de Noronha Brito Oct 07 '21 at 15:57

1 Answers1

3

This doesn't work because your Vector class doesn't implement the Iterable or Sized protocols. You could fix it to do that (and pass through to the _store), but with the code you've given it would be simpler to represent the typing you desire for mean and readPrint by just aliasing Vector to Collection:

from typing import Collection


Vector = Collection


def mean(vector: Vector[float]) -> float:
    return sum(vector) / len(vector)


def readPrint(vector: Vector[str]) -> None:
    for i in vector:
        print(i)


print(mean({2, 3, 4}))
readPrint(["foo", "bar"])

mean(["foo", "bar"])  # error: List item has incompatible type "str"; expected "float"

Note that int already conforms to float so defining a union of the two is typically not necessary in order to denote a numeric value.

Samwise
  • 68,105
  • 3
  • 30
  • 44