-
-
Notifications
You must be signed in to change notification settings - Fork 46.7k
[mypy] annotate compression
#5570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,31 @@ | ||
from __future__ import annotations | ||
|
||
import sys | ||
|
||
|
||
class Letter: | ||
def __init__(self, letter, freq): | ||
self.letter = letter | ||
self.freq = freq | ||
self.bitstring = {} | ||
def __init__(self, letter: str, freq: int): | ||
self.letter: str = letter | ||
self.freq: int = freq | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are Python and mypy smart enough to know the data types being assigned on lines 8 and 9? Even without the type hint, won’t mypy still complain if I later try to assign 1 to self.letter or “A” to self.freq? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you are being rhetoric here 😅 but I thought I should add my two cents but tbh I would like to know the answer as well 😂 From my limited knowledge of using python, Mypy would still complain but I think the main use of type hints that I have found is when language servers used in IDE's help the programmer to look at the function signature/definition and not make any mistakes. For example, when you're writing something in VSCode and use a package it gives you an autocomplete suggestion which also contains the information for the type expected in a particular argument. This immediately makes the programmer aware that they are making a mistake because language servers raise a warning squiggly lines whereas the type hint inside the def doesn't (I think). If I'm wrong, let me know as well 😂 I would also like to know whether language servers would be able raise a flag when type hint is only provided in the definition and not the signature of the function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You and I agree with each other. The most helpful use of type hints is in function parameters and return types. |
||
self.bitstring: dict[str, str] = {} | ||
|
||
def __repr__(self): | ||
def __repr__(self) -> str: | ||
return f"{self.letter}:{self.freq}" | ||
|
||
|
||
class TreeNode: | ||
def __init__(self, freq, left, right): | ||
self.freq = freq | ||
self.left = left | ||
self.right = right | ||
def __init__(self, freq: int, left: Letter | TreeNode, right: Letter | TreeNode): | ||
self.freq: int = freq | ||
self.left: Letter | TreeNode = left | ||
self.right: Letter | TreeNode = right | ||
|
||
|
||
def parse_file(file_path): | ||
def parse_file(file_path: str) -> list[Letter]: | ||
""" | ||
Read the file and build a dict of all letters and their | ||
frequencies, then convert the dict into a list of Letters. | ||
""" | ||
chars = {} | ||
chars: dict[str, int] = {} | ||
with open(file_path) as f: | ||
while True: | ||
c = f.read(1) | ||
|
@@ -33,36 +35,38 @@ def parse_file(file_path): | |
return sorted((Letter(c, f) for c, f in chars.items()), key=lambda l: l.freq) | ||
|
||
|
||
def build_tree(letters): | ||
def build_tree(letters: list[Letter]) -> Letter | TreeNode: | ||
""" | ||
Run through the list of Letters and build the min heap | ||
for the Huffman Tree. | ||
""" | ||
while len(letters) > 1: | ||
left = letters.pop(0) | ||
right = letters.pop(0) | ||
response: list[Letter | TreeNode] = letters # type: ignore | ||
while len(response) > 1: | ||
left = response.pop(0) | ||
right = response.pop(0) | ||
total_freq = left.freq + right.freq | ||
node = TreeNode(total_freq, left, right) | ||
letters.append(node) | ||
letters.sort(key=lambda l: l.freq) | ||
return letters[0] | ||
response.append(node) | ||
response.sort(key=lambda l: l.freq) | ||
return response[0] | ||
|
||
|
||
def traverse_tree(root, bitstring): | ||
def traverse_tree(root: Letter | TreeNode, bitstring: str) -> list[Letter]: | ||
""" | ||
Recursively traverse the Huffman Tree to set each | ||
Letter's bitstring dictionary, and return the list of Letters | ||
""" | ||
if type(root) is Letter: | ||
root.bitstring[root.letter] = bitstring | ||
return [root] | ||
treenode: TreeNode = root # type: ignore | ||
letters = [] | ||
letters += traverse_tree(root.left, bitstring + "0") | ||
letters += traverse_tree(root.right, bitstring + "1") | ||
letters += traverse_tree(treenode.left, bitstring + "0") | ||
letters += traverse_tree(treenode.right, bitstring + "1") | ||
return letters | ||
|
||
|
||
def huffman(file_path): | ||
def huffman(file_path: str) -> None: | ||
""" | ||
Parse the file, build the tree, then run through the file | ||
again, using the letters dictionary to find and print out the | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this change run counter to
flake8 return
error R504? https://github.com/afonasev/flake8-return#errors