codexpast-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford2016imperative-resit-observer-uml.py
past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2016/imperative-resit-observer-uml.py
"""Service observer UML. Python 3.14; matplotlib 3.10.7; writes PNG to CWD."""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, FancyArrowPatch
def main():
fig,ax=plt.subplots(figsize=(13.5,7.4),facecolor='white')
ax.set(xlim=(0,18.3),ylim=(0,9.6))
ax.axis('off')
def box(x,y,w,h,title,body,tint='#f2f6fa'):
ax.add_patch(Rectangle((x-w/2,y-h/2),w,h,facecolor=tint,
edgecolor='#25364a',lw=1.4,zorder=3))
split=y+h/2-.55
ax.plot([x-w/2,x+w/2],[split,split],color='#25364a',lw=1,zorder=4)
ax.text(x,y+h/2-.27,title,ha='center',va='center',fontsize=11,
weight='bold',zorder=5)
ax.text(x-w/2+.12,split-.16,body,ha='left',va='top',fontsize=10.5,
linespacing=1.5,zorder=5)
def edge(start,end,dashed=False):
ax.add_patch(FancyArrowPatch(start,end,arrowstyle='-|>',mutation_scale=20,
edgecolor='#25364a',facecolor='white',linewidth=1.3,
linestyle='--' if dashed else '-',zorder=1))
box(3.0,7.15,5.1,3.1,'«trait» Service',
'- _value: Double\n- companies: List[Company]\n+ value / value_=\n+ addCompany(c), sendMessage()\n+ updateValue(newValue)')
box(11.5,7.55,4.0,1.6,'«interface» Company','+ meth(): Unit')
ax.annotate('',xy=(9.5,7.55),xytext=(5.55,7.55),
arrowprops=dict(arrowstyle='->',color='#25364a',lw=1.3))
ax.text(7.5,7.8,'companies 0..*',ha='center',fontsize=10.5)
ax.text(7.5,7.1,'notify: meth()',ha='center',fontsize=10.5)
box(3.0,2.65,5.1,2.0,'SomeService',
'+ updateValue(newValue):\n set value, then notify')
edge((3,3.65),(3,5.60))
for x,name,factor in [(8.0,'PrivateCompany','1.1'),
(12.0,'PublicCompany','0.9'),
(16.0,'NonProfit','1.0')]:
box(x,2.65,3.7,2.3,name,
'- service: SomeService\n- v: Double\n+ meth(): refresh v',
'#fff6df' if name=='NonProfit' else '#f2f6fa')
edge((x,3.8),(11.5,6.75),True)
ax.text(x,1.0,'callback factor '+factor,ha='center',fontsize=10)
ax.text(.5,9.1,'Service values: subject registers and notifies company observers',
fontsize=14,weight='bold')
ax.text(.5,.35,'Each concrete company retains one SomeService and registers itself with it.',
fontsize=10.5,color='#354354')
fig.tight_layout(pad=.6)
fig.savefig(Path.cwd()/'imperative-resit-observer-uml.png',dpi=115,
facecolor='white',transparent=False)
plt.close(fig)
if __name__ == '__main__':
main()