Skip to content

Instantly share code, notes, and snippets.

@arnobaer
Last active May 31, 2019 15:35
Show Gist options
  • Save arnobaer/c673a63924aec2d151525db026ae315a to your computer and use it in GitHub Desktop.
Save arnobaer/c673a63924aec2d151525db026ae315a to your computer and use it in GitHub Desktop.
================================================================================
Generated periods
================================================================================
Period Range Diagram
================================================================================
P01 40-360 .##########................................................
P02 180-420 .....#######...............................................
P03 220-540 ......##########...........................................
P04 660-1000 ....................##########.............................
P05 960-1140 ..............................#####........................
P06 1120-1280 ...................................#####...................
P07 1160-1640 ....................................###############........
P08 1220-1660 ......................................#############........
P09 1720-1840 .....................................................###...
================================================================================
Generated contexts
================================================================================
Ctx P01 P02 P03 P04 P05 P06 P07 P08 P09 Range
================================================================================
C01 . . . . . . . 1 4] 1220-1840 P08-P09
C02 . . . . . . . . 4] 1720-1840 P09
C03 . . . . 1 . 4 . 1] 960-1840 P05-P09
C04 1 . . 1 . . . .] . 40-1000 P01-P04
C05 . . . . 5 . . .] . 960-1140 P05
C06 . . . . . . 1 .] . 1160-1640 P07
C07 . . . 1 2 . . 1] . 660-1660 P04-P08
C08 . . . . 2 1 2] . . 960-1640 P05-P07
C09 1 2 . .] . . . . . 40-420 P01-P02
C10 3 . . .] . . . . . 40-360 P01
C11 . . . 3] . . . . . 660-1000 P04
C12 . . 3] . . . . . . 220-540 P03
sum 5 2 3 5 10 1 7 2 9
d/U d d U U d d U U d
================================================================================
seed: 1559260424.6490061
#
# Simulating test-pit find matrices
#
# Requires: texttable
#
import argparse
import random
import time
import sys, os
from texttable import Texttable
class TestPit:
def __init__(self, name, number, contexts):
self.name = name
self.number = number
self.contexts = contexts
self.date_contexts()
def date_contexts(self):
prev_period = None
# Iterate from bottom to top of trench
for context in self.contexts[::-1]:
# If context contains datable finds
if context.finds:
period = context.finds[-1].period
if prev_period is None:
prev_period = period
elif period.end > prev_period.end:
prev_period = period
elif period.end == prev_period.end:
if period.begin >= prev_period.begin:
prev_period = period
context.period = prev_period
def get_periods(self):
periods = []
for context in self.contexts:
period = context.period
if period and period not in periods:
periods.append(period)
for find in context.finds:
period = find.period
if period not in periods:
periods.append(period)
periods.sort(key=lambda period: period.sort_key)
return periods
def get_disturbed(self, periods):
used_periods = periods#self.get_periods()
states = []
prev_period = None
for p in used_periods:
disturbed = None
# HACK latest is always disturbed
if p.end == used_periods[-1].end:
disturbed = True
for c in self.contexts[::-1]:
for f in c.finds:
if f.period is p:
if f.period is c.period:
if disturbed is None:
disturbed = False
else:
if f.period.end < c.period.end:
if disturbed is None:
disturbed = True
states.append(disturbed)
return states
class Period:
def __init__(self, name, begin, end):
assert(begin < end)
self.name = name
self.begin = begin
self.end = end
@property
def span(self):
return self.end - self.begin
@property
def sort_key(self):
return self.end, self.begin, self.name
class Context:
def __init__(self, index, finds):
self.index = index
self.finds = finds
self.period = None
self.sort_finds()
def sort_finds(self):
self.finds.sort(key=lambda find: (find.sort_key))
@property
def name(self):
return 'C{:02}'.format(self.index)
@property
def finds_span(self):
if self.finds:
begin = self.finds[0].period.begin
end = self.finds[-1].period.end
return begin, end
return 0, 0
def count_finds(self, period=None):
count = 0
for find in self.finds:
if period is not None:
if period is not find.period:
continue
count += find.count
return count
class Find:
def __init__(self, type, period, count, weight):
self.type = type
self.period = period
self.count = count
self.weight = weight
@property
def sort_key(self):
return self.period.sort_key, self.type, self.count, self.weight
parser = argparse.ArgumentParser()
parser.add_argument('--seed', type=float, default=time.time())
parser.add_argument('--begin', type=int, default=0)
parser.add_argument('--end', type=int, default=1900)
args = parser.parse_args()
random.seed(args.seed)
def create_periods(n):
periods = []
for _ in range(n):
a, b = sorted((0, 0))
while b-a < 100 or b-a > 500:
a, b = sorted((random.randint(args.begin//20, args.end//20)*20, random.randint(args.begin//20, args.end//20)*20))
periods.append(Period(None, a, b))
# sort by end, then begin
periods.sort(key=lambda period: period.sort_key)
for i, period in enumerate(periods):
name = 'P{:02}'.format(i + 1)
period.name = name
return periods
def create_finds(n, periods):
finds = []
types = ('pottery','clay-pipe','CBM')
counts = (1,1,1,1,1,1,2,2,2,3,3,4)
weights = (1,1,2,2,3,3,4,5,6,7)
for _ in range(n):
count = random.choice(counts)
weight = 0
for _ in range(count):
weight += random.choice(weights)
find = Find(random.choice(types), random.choice(periods), count, weight)
finds.append(find)
return finds
def create_contexts(n, periods):
contexts = []
for index in range(n):
finds = create_finds(random.randint(0, 3), periods)
context = Context(index + 1, finds)
contexts.append(context)
return contexts
def draw_title(*args, width=80, separator=''):
bar = '=' * width
title = separator.join(args).center(80)
return os.linesep.join((bar, title, bar))
periods = create_periods(9)
contexts = create_contexts(random.randint(8, 12), periods)
testpit = TestPit("TO/16/03", 3, contexts)
print(draw_title("Generated periods"))
table = Texttable()
table.set_deco(Texttable.HEADER)
table.set_cols_align(["l", "c", "l"])
table.header(("Period", "Range", "Diagram"))
for period in periods:
scale = 32
offset = '.'*(period.begin // scale)
bar = '#'*(period.span // scale)
frame = offset + bar + '.'*((1900 // scale)-(len(offset)+len(bar)))
table.add_row((period.name, "{:>4}-{:<4}".format(period.begin, period.end), frame))
print(table.draw())
print(draw_title("Generated contexts"))
used_periods = periods#testpit.get_periods()
table = Texttable()
table.set_deco(Texttable.HEADER)
align = ["l"]
header = ["Ctx"]
for period in used_periods:
align.append("r")
header.append(period.name)
align.append("c")
header.append("Range")
table.set_cols_align(align)
table.header(header)
for c in testpit.contexts:
row = [c.name]
for p in used_periods:
count = 0
for f in c.finds:
if f.period is p:
count += f.count
gate = " "
if c.period:
if c.period.end is p.end:
gate = "]"
if count:
row.append('{:>2}{}'.format(count, gate))
else:
row.append('{:>2}{}'.format('.', gate))
span = c.finds_span
if span != (0, 0):
lhs, rhs = c.finds[0].period, c.finds[-1].period
if lhs is rhs and c.finds[0] is not c.finds[-1]:
row.append(' {:>4}-{:<4} {:>3} '.format(*c.finds_span, lhs.name))
else:
row.append(' {:>4}-{:<4} {:>3}-{:<3} '.format(*c.finds_span, lhs.name, rhs.name))
else:
row.append('')
table.add_row(row)
row = ["sum"]
for p in used_periods:
count = 0
for c in testpit.contexts:
count += c.count_finds(p)
if count:
row.append("{:>2} ".format(count))
else:
row.append("-")
table.add_row(row + [""])
row = ["d/U"]
for disturbed in testpit.get_disturbed(periods):
row.append({None: "-", False: "U", True: "d"}[disturbed])
table.add_row(row + [""])
data = table.draw()
# Add colored output
if sys.stdout.isatty():
data = data.replace("]", "\033[35m]\033[0m")
data = data.replace(" d ", "\033[31m d \033[0m")
data = data.replace(" U ", "\033[32m U \033[0m")
print(data)
print("=" * 80)
print("seed:", args.seed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment