ex 9
This commit is contained in:
parent
4ea5a4503f
commit
88f54d1a2f
13
simplemod.py
Normal file
13
simplemod.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
x = 42
|
||||||
|
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
print('x is', x)
|
||||||
|
|
||||||
|
|
||||||
|
class Spam:
|
||||||
|
def yow(self):
|
||||||
|
print('Yow!')
|
||||||
|
|
||||||
|
|
||||||
|
print('loaded simplemod')
|
||||||
5
stock.py
5
stock.py
@ -1,4 +1,4 @@
|
|||||||
from structure import Structure
|
from structly import *
|
||||||
|
|
||||||
|
|
||||||
class Stock(Structure):
|
class Stock(Structure):
|
||||||
@ -21,6 +21,7 @@ class Stock(Structure):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from reader import read_csv_as_instances
|
|
||||||
|
|
||||||
portfolio = read_csv_as_instances('Data/portfolio.csv', Stock)
|
portfolio = read_csv_as_instances('Data/portfolio.csv', Stock)
|
||||||
|
formatter = create_formatter('text')
|
||||||
|
print_table(portfolio, ['name', 'shares', 'price'], formatter)
|
||||||
|
|||||||
9
structly/__init__.py
Normal file
9
structly/__init__.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from .reader import *
|
||||||
|
from .structure import *
|
||||||
|
from .tableformat import *
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
*structure.__all__,
|
||||||
|
*reader.__all__,
|
||||||
|
*tableformat.__all__
|
||||||
|
]
|
||||||
@ -2,6 +2,8 @@ import csv
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any, Callable, Iterable, Mapping, Optional, Sequence
|
from typing import Any, Callable, Iterable, Mapping, Optional, Sequence
|
||||||
|
|
||||||
|
__all__ = ['read_csv_as_dicts', 'read_csv_as_instances']
|
||||||
|
|
||||||
|
|
||||||
def convert_csv(
|
def convert_csv(
|
||||||
lines: Iterable[str],
|
lines: Iterable[str],
|
||||||
@ -24,7 +26,8 @@ def convert_csv(
|
|||||||
|
|
||||||
|
|
||||||
def csv_as_dicts(
|
def csv_as_dicts(
|
||||||
lines: Iterable[str], types: Sequence[type], headers: Optional[Sequence[str]] = None
|
lines: Iterable[str], types: Sequence[type],
|
||||||
|
headers: Optional[Sequence[str]] = None
|
||||||
) -> Sequence[Mapping[str, Any]]:
|
) -> Sequence[Mapping[str, Any]]:
|
||||||
"""Parse CSV lines into a list of dictionaries."""
|
"""Parse CSV lines into a list of dictionaries."""
|
||||||
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
from collections import ChainMap
|
from collections import ChainMap
|
||||||
|
|
||||||
from validate import Validator, validated
|
from .validate import Validator, validated
|
||||||
|
|
||||||
|
__all__ = ['Structure']
|
||||||
|
|
||||||
|
|
||||||
def validate_attributes(cls):
|
def validate_attributes(cls):
|
||||||
3
structly/tableformat/__init__.py
Normal file
3
structly/tableformat/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from .formatter import create_formatter, print_table
|
||||||
|
|
||||||
|
__all__ = ['create_formatter', 'print_table']
|
||||||
12
structly/tableformat/csv.py
Normal file
12
structly/tableformat/csv.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from .formatter import TableFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class CSVTableFormatter(TableFormatter):
|
||||||
|
def _printer(self, data):
|
||||||
|
print(",".join(str(value) for value in data))
|
||||||
|
|
||||||
|
def headings(self, headers):
|
||||||
|
return self._printer(headers)
|
||||||
|
|
||||||
|
def row(self, rowdata):
|
||||||
|
return self._printer(rowdata)
|
||||||
@ -2,6 +2,13 @@ from abc import ABC, abstractmethod
|
|||||||
|
|
||||||
|
|
||||||
class TableFormatter(ABC):
|
class TableFormatter(ABC):
|
||||||
|
_formats = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __init_subclass__(cls):
|
||||||
|
name = cls.__module__.split('.')[-1]
|
||||||
|
TableFormatter._formats[name] = cls
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def headings(self, headers):
|
def headings(self, headers):
|
||||||
pass
|
pass
|
||||||
@ -11,44 +18,6 @@ class TableFormatter(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TextTableFormatter(TableFormatter):
|
|
||||||
def _printer(self, data):
|
|
||||||
print(*("{: >10}".format(value) for value in data))
|
|
||||||
|
|
||||||
def headings(self, headers):
|
|
||||||
self._printer(headers)
|
|
||||||
print(*("{:->10}".format("") for _ in headers))
|
|
||||||
|
|
||||||
def row(self, rowdata):
|
|
||||||
self._printer(rowdata)
|
|
||||||
|
|
||||||
|
|
||||||
class CSVTableFormatter(TableFormatter):
|
|
||||||
def _printer(self, data):
|
|
||||||
print(",".join(str(value) for value in data))
|
|
||||||
|
|
||||||
def headings(self, headers):
|
|
||||||
return self._printer(headers)
|
|
||||||
|
|
||||||
def row(self, rowdata):
|
|
||||||
return self._printer(rowdata)
|
|
||||||
|
|
||||||
|
|
||||||
class HTMLTableFormatter(TableFormatter):
|
|
||||||
def _cell(self, value, tag):
|
|
||||||
return f"<{tag}>{value}</{tag}>"
|
|
||||||
|
|
||||||
def _printer(self, data, tag):
|
|
||||||
line = f"<tr>{' '.join(self._cell(str(value), tag) for value in data)}</tr>"
|
|
||||||
print(line)
|
|
||||||
|
|
||||||
def headings(self, headers):
|
|
||||||
return self._printer(headers, "th")
|
|
||||||
|
|
||||||
def row(self, rowdata):
|
|
||||||
return self._printer(rowdata, "td")
|
|
||||||
|
|
||||||
|
|
||||||
class ColumnFormatMixin:
|
class ColumnFormatMixin:
|
||||||
formats = []
|
formats = []
|
||||||
|
|
||||||
@ -63,16 +32,15 @@ class UpperHeadersMixin:
|
|||||||
|
|
||||||
|
|
||||||
def create_formatter(name, column_formats=None, upper_headers=False):
|
def create_formatter(name, column_formats=None, upper_headers=False):
|
||||||
formatters = {
|
|
||||||
"text": TextTableFormatter,
|
|
||||||
"csv": CSVTableFormatter,
|
|
||||||
"html": HTMLTableFormatter,
|
|
||||||
}
|
|
||||||
formatter = formatters.get(name, None)
|
|
||||||
if not name:
|
if not name:
|
||||||
raise ValueError(f'formatter named "{name}" not implemented')
|
raise ValueError(f'formatter named "{name}" not implemented')
|
||||||
if upper_headers:
|
if name not in TableFormatter._formats:
|
||||||
|
__import__(f'{__package__}.{name}')
|
||||||
|
formatter = TableFormatter._formats.get(name)
|
||||||
|
if not formatter:
|
||||||
|
raise RuntimeError(f'Unknown format {name}')
|
||||||
|
|
||||||
|
if upper_headers:
|
||||||
class _UpperFormatter(UpperHeadersMixin, formatter):
|
class _UpperFormatter(UpperHeadersMixin, formatter):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
16
structly/tableformat/html.py
Normal file
16
structly/tableformat/html.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from .formatter import TableFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class HTMLTableFormatter(TableFormatter):
|
||||||
|
def _cell(self, value, tag):
|
||||||
|
return f"<{tag}>{value}</{tag}>"
|
||||||
|
|
||||||
|
def _printer(self, data, tag):
|
||||||
|
line = f"<tr>{' '.join(self._cell(str(value), tag) for value in data)}</tr>"
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
def headings(self, headers):
|
||||||
|
return self._printer(headers, "th")
|
||||||
|
|
||||||
|
def row(self, rowdata):
|
||||||
|
return self._printer(rowdata, "td")
|
||||||
13
structly/tableformat/text.py
Normal file
13
structly/tableformat/text.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from .formatter import TableFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class TextTableFormatter(TableFormatter):
|
||||||
|
def _printer(self, data):
|
||||||
|
print(*("{: >10}".format(value) for value in data))
|
||||||
|
|
||||||
|
def headings(self, headers):
|
||||||
|
self._printer(headers)
|
||||||
|
print(*("{:->10}".format("") for _ in headers))
|
||||||
|
|
||||||
|
def row(self, rowdata):
|
||||||
|
self._printer(rowdata)
|
||||||
Loading…
x
Reference in New Issue
Block a user