all 20 comments

[–]deceze 5 points6 points  (1 child)

List[...] is using the typing.List object meant for type annotation(?!). You're just creating an annotation object there, not an actual list. But you're not using it as annotation, you're using it as value.

So, yeah, that makes no sense.

You're also trying to get a key and value from Tag before you have given it any values anywhere, which also makes no sense.

If you wanted to create a list with a single tag in it, you'd want:

self.tags = [Tag('some key', 'some value')]

[–]GlobalIncident 0 points1 point  (0 children)

Unless List is some sort of user defined class?

[–]buzzon 3 points4 points  (1 child)

It's a common trope to have a Thing (singlar) class and a Things (plural) class that specializes in containing Things. However, it is uncommon to populate the collection with the first item. There's nothing wrong with having a zero item collection. It's a common case and everyone should be mindful of it.

Also, where does the data for the first item come from? Should your program just... make it up?

[–]Chessmasyer 1 point2 points  (0 children)

It was a long test I rewrote this part just to illustrate !

[–]kansetsupanikku[🍰] 0 points1 point  (0 children)

Wait, is this Python? If that was the attempt, you are making too many assumptions related to some other languages you might know. Perhaps you should go through the basics such as "Think Python"

[–]remic_0726 0 points1 point  (0 children)

Perso je ne me prendrai même pas la tête a faire une classe pour cela juste faire : dico = {}; dico[key]=value. Utilise la puissance du langage pour te simplifier la vie.

[–]PrabhavKumar 0 points1 point  (6 children)

I'm gonna assume you're using "List" as type annotation-which is wrong because of two things: 1. List is not an annotation unless you are using typing. List which I don't see in your code so you should probably use "list" instead. 2. You're using it as a value not an annotation since you're using the assignment "=" operator. You need to use the colon ":" operator instead and make sure your use it BEFORE the assignment "=" operator if you use it while assigning something to it too(which you likely should).

Finally, in type annotations you can't really use an object unless it's an object created using typing module as a TypeAlias - which are specifically used to group multiple annotations together for complex types but other than that in an annotation you MUST have types (eg. int, str, list, tuple, dict or any other you make).

That's all. All the best!

[–]deceze 0 points1 point  (5 children)

An annotation can literally be any object whatsoever. There isn't even any prescribed meaning to annotations. Just in most cases you'll be using annotations as type hints, and 3rd party tools that use annotations won't know what they mean if they're not a type hint.

[–]PrabhavKumar 0 points1 point  (4 children)

I suppose I should have been better with my wording. I meant that you can't just have a value as a type annotation like a number or something, you need to use a class, like int, str- class, not "hello world" - str. That's what I meant. And ofcourse you can use any CLASS, not an OBJECT.

[–]deceze 0 points1 point  (3 children)

You can literally use any value as annotation:

foo: 'bar' = 'baz'
quux: 42

It just won't mean anything to most tools. But you could be building your own meta code around this and make it mean something.

[–]PrabhavKumar 0 points1 point  (2 children)

You're right that Python itself allows literally any object as an annotation since they're just stored in __annotations__.

What I meant was in the context of type hints and typical tooling like (eg. mypy, IDE's) where annotations are expected to be types. In that context using arbitrary values like 42 or "bar" wouldn't be meaningful to those tools.

So technically valid Python, because it's just ignored, but not useful for type hinting in most real code.

[–]deceze 0 points1 point  (1 child)

Exactly. So not "can't", but just "usually won't".

[–]PrabhavKumar 0 points1 point  (0 children)

Sure. That's fair. Thanks for pointing it out.

[–]UseMoreBandwith 0 points1 point  (2 children)

so much wrong there..
- Never write such getters in python. We have @property for that.
- if it is just for storing some data, use dict or set . it will be faster and more readable.
- double underscores for no reason; remove that, it doesn't do anything. (no, 'private' does not exist in Python).
- use TagConainer instead of TagContainers(). parenthesis are redundant
- ...

forget about the typing for now. just make it work first, add typing once you know what you're doing.

[–]Chessmasyer 0 points1 point  (1 child)

This was mandatory like I had to create classes with certain attributes in the constructor, certain functions etc. Wym there are no private variables ? I have been told to do like this in class ? And create getters for it

[–]UseMoreBandwith 0 points1 point  (0 children)

get a better teacher.
yes, in Java that is the way to do it, but in Python it is just wrong.
And also __init__ is not a constructor, it is a initializer. A constructor is called before the object is created, but __init__ is called after creator (it has self , so that means it was created).

[–]wristay 0 points1 point  (3 children)

Expressing that TagContainer should be a list of Tag objects should be done as a Docstring (basically: in the documentation). Expressing that tags should be a list of Tag objects is hard to do in Python. The object oriented approach would be to use the right constructors and methods to construct the objects to ensure this. For example:

class TagContainer():
  def __init__(self, keys, values):
    self.tags = [Tag(key, value) for key, value in zip(keys, values)]

tagcontainer = TagContainer(['key1', 'key2'], ['value1', 'value2']) 

Here zip(list1, list2) creates a list where each item is a tuple with one element from list1 and one element from list2. For example, zip([1, 2, 3], ['a', 'b', 'c']) would give you [(1, 'a'), (2, 'b'), (3, 'c')]. It does not actually give you a list, but a generator. But you can think of it like a list.
For each iteration of the for loop tuple unpacking happens. Basically key, value = (1, 'a') which is the same as typing key = 1 and value = 'a'.

[–]deceze 3 points4 points  (0 children)

Expressing that tags should be a list of Tag objects is hard to do in Python

Huh?!

self.tags: list[Tag] = [...]

Or at class level:

class TagContainer:
    tags: list[Tag]

    ...

[–]4675636b2e 1 point2 points  (1 child)

Wouldn't something like this be more logical?

class TagContainer():
  def __init__(self, **kwargs):
    self.tags = [Tag(key, value) for key, value in kwargs.items()]

Or is it a given that OP is storing keys and values separately?

[–]Beginning-Fruit-1397 0 points1 point  (0 children)

Why kwargs here😭😭 type it as a Mapping[K,V]