ex 8.1, 8.2, 8.3
This commit is contained in:
parent
1f4b203f61
commit
a9077d8308
1
.gitignore
vendored
1
.gitignore
vendored
@ -159,3 +159,4 @@ cython_debug/
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
Session.vim
|
||||
Data/stocklog.csv
|
||||
|
||||
34
cofollow.py
Normal file
34
cofollow.py
Normal file
@ -0,0 +1,34 @@
|
||||
import os
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
|
||||
def follow(filename, target):
|
||||
with open(filename, 'r') as f:
|
||||
f.seek(0, os.SEEK_END)
|
||||
while True:
|
||||
line = f.readline()
|
||||
if line != '':
|
||||
target.send(line)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
def consumer(func):
|
||||
@wraps(func)
|
||||
def start(*args, **kwargs):
|
||||
f = func(*args, **kwargs)
|
||||
f.send(None)
|
||||
return f
|
||||
return start
|
||||
|
||||
|
||||
@consumer
|
||||
def printer():
|
||||
while True:
|
||||
item = yield
|
||||
print(item)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
follow('Data/stocklog.csv', printer())
|
||||
57
coticker.py
Normal file
57
coticker.py
Normal file
@ -0,0 +1,57 @@
|
||||
import csv
|
||||
|
||||
from cofollow import consumer
|
||||
from tableformat import create_formatter
|
||||
from ticker import Ticker
|
||||
|
||||
|
||||
@consumer
|
||||
def to_csv(target):
|
||||
def producer():
|
||||
while True:
|
||||
yield line
|
||||
|
||||
reader = csv.reader(producer())
|
||||
while True:
|
||||
line = yield
|
||||
target.send(next(reader))
|
||||
|
||||
|
||||
@consumer
|
||||
def create_ticker(target):
|
||||
while True:
|
||||
row = yield
|
||||
target.send(Ticker.from_row(row))
|
||||
|
||||
|
||||
@consumer
|
||||
def negchange(target):
|
||||
while True:
|
||||
record = yield
|
||||
if record.change < 0:
|
||||
target.send(record)
|
||||
|
||||
|
||||
@consumer
|
||||
def ticker(fmt, fields):
|
||||
formatter = create_formatter(fmt)
|
||||
formatter.headings(fields)
|
||||
while True:
|
||||
rec = yield
|
||||
row = [getattr(rec, name) for name in fields]
|
||||
formatter.row(row)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from cofollow import follow
|
||||
|
||||
follow(
|
||||
'Data/stocklog.csv',
|
||||
to_csv(
|
||||
create_ticker(
|
||||
negchange(
|
||||
ticker('text', ['name', 'price', 'change'])
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
23
follow.py
Normal file
23
follow.py
Normal file
@ -0,0 +1,23 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
def follow(filename):
|
||||
f = open(filename)
|
||||
f.seek(0, os.SEEK_END)
|
||||
while True:
|
||||
line = f.readline()
|
||||
if line == '':
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
yield line
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for line in follow('Data/stocklog.csv'):
|
||||
fields = line.split(',')
|
||||
name = fields[0].strip('"')
|
||||
price = float(fields[1])
|
||||
change = float(fields[4])
|
||||
if change < 0:
|
||||
print(f"{name:s} {price:10.2f} {change:10.2f}")
|
||||
13
structure.py
13
structure.py
@ -35,7 +35,7 @@ class Structure(metaclass=StructureMeta):
|
||||
validate_attributes(cls)
|
||||
|
||||
def __repr__(self):
|
||||
args = map(lambda field: f"{field}={getattr(self, field)!r}", self._fields)
|
||||
args = map(lambda field: f"{getattr(self, field)!r}", self._fields)
|
||||
return f"{type(self).__name__}({', '.join(args)})"
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
@ -44,6 +44,13 @@ class Structure(metaclass=StructureMeta):
|
||||
else:
|
||||
raise AttributeError(f"No attribute {name}")
|
||||
|
||||
def __iter__(self):
|
||||
for name in self._fields:
|
||||
yield getattr(self, name)
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, type(self)) and tuple(self) == tuple(other)
|
||||
|
||||
@classmethod
|
||||
def create_init(cls):
|
||||
code = f'def __init__(self, {", ".join(cls._fields)}):\n'
|
||||
@ -53,6 +60,10 @@ class Structure(metaclass=StructureMeta):
|
||||
exec(code, locs)
|
||||
cls.__init__ = locs['__init__']
|
||||
|
||||
@classmethod
|
||||
def from_row(cls, row):
|
||||
return cls(*[func(val) for func, val in zip(cls._types, row)])
|
||||
|
||||
|
||||
def typed_structure(clsname, **validators):
|
||||
cls = type(clsname, (Structure,), validators)
|
||||
|
||||
28
ticker.py
Normal file
28
ticker.py
Normal file
@ -0,0 +1,28 @@
|
||||
from structure import Structure
|
||||
|
||||
|
||||
class Ticker(Structure):
|
||||
name = String()
|
||||
price = Float()
|
||||
date = String()
|
||||
time = String()
|
||||
change = Float()
|
||||
open = Float()
|
||||
high = Float()
|
||||
low = Float()
|
||||
volume = Integer()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import csv
|
||||
|
||||
from follow import follow
|
||||
from tableformat import create_formatter, print_table
|
||||
|
||||
formatter = create_formatter('text')
|
||||
|
||||
lines = follow('Data/stocklog.csv')
|
||||
rows = csv.reader(lines)
|
||||
records = (Ticker.from_row(row) for row in rows)
|
||||
negative = (rec for rec in records if rec.change < 0)
|
||||
print_table(negative, ['name', 'price', 'change'], formatter)
|
||||
Loading…
x
Reference in New Issue
Block a user