Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
lfa:2023:lab_python_extras [2023/11/02 14:02] mihai.udubasa |
lfa:2023:lab_python_extras [2023/11/15 20:54] (current) mihai.udubasa [Dataclasses] |
||
---|---|---|---|
Line 50: | Line 50: | ||
Dataclasses are a shorthand way of implementing certain methods and generally removing some boilerplate code. | Dataclasses are a shorthand way of implementing certain methods and generally removing some boilerplate code. | ||
- | Assume you're writing a class to implement linked lists, which can be printed in a similar way to ADT's (so [1,2,3] should be printed as `Cons(1,Cons(2,Cons(3,Empty())))`). Your code may look like this: | + | Assume you're writing a class to implement linked lists, which can be printed in a similar way to ADT's (so ''[1,2,3]'' should be printed as ''Cons(1,Cons(2,Cons(3,Empty())))''). Your code may look like this: |
<code python> | <code python> | ||
Line 76: | Line 76: | ||
</code> | </code> | ||
- | contrast this to how a similar level of functionality would be implemented in haskell: | + | contrast this to how a similar level of functionality would be implemented in Haskell: |
<code haskell> | <code haskell> | ||
- | data List a = Cons a List | Empty deriving Show | + | data List a = Cons a (List a) | Empty deriving Show |
</code> | </code> | ||
Is it possible to eliminate most of the boilerplate code present in the python version while keeping most of the functionality? YES, using dataclasses. | Is it possible to eliminate most of the boilerplate code present in the python version while keeping most of the functionality? YES, using dataclasses. | ||
- | ''dataclass'' is a type of python object known as a decorator. In general, decorators are placed right before a class or function definition (preappended with the ''@'' symbol) and alter their behaviour in certain ways. In our case, the ''dataclass'' decorator implements some generic methods of the class, most importantly, ''`_`_init`_`_'', ''`_`_str`_`_'' and ''`_`_repr`_`_''. If we want our class to contain member variables, we only need to list them in the fucntion body. The list code rewritten with dataclasses looks like this: | + | ''dataclass'' is a type of python object known as a decorator. In general, decorators are placed right before a class or function definition (preappended with the ''@'' symbol) and alter their behaviour in certain ways. In our case, the ''dataclass'' decorator implements some generic methods of the class, most importantly, ''`_`_init`_`_'', ''`_`_str`_`_'' and ''`_`_repr`_`_''. If we want our class to contain member variables, we only need to list them in the function body. The list code rewritten with dataclasses looks like this: |
<code python> | <code python> | ||
from dataclasses import dataclass | from dataclasses import dataclass | ||
Line 107: | Line 107: | ||
===== Dictionaries, Sets and Hashable Objects ===== | ===== Dictionaries, Sets and Hashable Objects ===== | ||
- | As part of your project, it is very likely that you will attempt to use a set or list either as an element of another set, or as a part of the key of a dictionary. However, if you actually try this, you will get an error stating that your element is not hashable. Why is this? | + | As part of your project, i |
+ | t is very likely that you will attempt to use a set or list either as an element of another set, or as a part of the key of a dictionary. However, if you actually try this, you will get an error stating that your element is not hashable. Why is this? | ||
In short, both dictionaries and sets are implemented as hashmaps in the python library (for quick search and append of unique elements). This means that elements should have a hash method implemented (alongside a method to check equality between objects) and, moreover, this hash fuction should always be consistent with the equality comparison (objects which are equal should always have the same hash, but the other way around is not necessary). | In short, both dictionaries and sets are implemented as hashmaps in the python library (for quick search and append of unique elements). This means that elements should have a hash method implemented (alongside a method to check equality between objects) and, moreover, this hash fuction should always be consistent with the equality comparison (objects which are equal should always have the same hash, but the other way around is not necessary). | ||
Line 115: | Line 116: | ||
All of this essentially boils down to: **mutable collections (such as lists, sets and dictionaries) can __NOT__ be used as set elements or dictionary keys**. However, the use of a collection in such a situation may still be desirable in some situations (such as the subset constructon algorithm). | All of this essentially boils down to: **mutable collections (such as lists, sets and dictionaries) can __NOT__ be used as set elements or dictionary keys**. However, the use of a collection in such a situation may still be desirable in some situations (such as the subset constructon algorithm). | ||
- | To work around this restriction we can use **IMMUTABLE COLELCTIONS** (collections which can no longer have elements added/removed/replaced), such as tuples (immutable lists, their elements may or may not be hashable, and the resulting tuple is hashable if all elements are hashable) and frozensets (immutable sets, their elements should still be hashable, as is the case of sets, and so frozensets are always hashable). | + | To work around this restriction we can use **IMMUTABLE COLLECTIONS** (collections which can no longer have elements added/removed/replaced), such as tuples (immutable lists, their elements may or may not be hashable, and the resulting tuple is hashable if all elements are hashable) and frozensets (immutable sets, their elements should still be hashable, as is the case of sets, and so frozensets are always hashable). |
Converting from a mutable to immutable collection is quite easy (you only apply the constructor over the original collection): | Converting from a mutable to immutable collection is quite easy (you only apply the constructor over the original collection): | ||
Line 140: | Line 141: | ||
Match statements are a way of performing structural matches (similar to the pattern matches in functional languages such as Haskell of Scala). They are able to differentiate the type of the object and match its attributes to a given list. Match statements can also be used on lists. | Match statements are a way of performing structural matches (similar to the pattern matches in functional languages such as Haskell of Scala). They are able to differentiate the type of the object and match its attributes to a given list. Match statements can also be used on lists. | ||
- | The synatx is as follows: | + | The syntax is as follows: |
<code python> | <code python> |