#!/usr/bin/env python3
from abc import ABCMeta, abstractmethod
class Terminator(metaclass=ABCMeta):
def __init__(self):
self.props = {}
def template_method(self):
self.legs_cnt()
self.hands_cnt()
self.liquid_body()
self.steel_skeleton()
return self
@abstractmethod
def legs_cnt(self):
pass
@abstractmethod
def hands_cnt(self):
pass
def liquid_body(self):
pass
def steel_skeleton(self):
pass
class T_800(Terminator):
def legs_cnt(self):
self.props['legs_cnt'] = 2
def hands_cnt(self):
self.props['hands_cnt'] = 2
def steel_skeleton(self):
self.props['steel_skeleton'] = True
class T_1000(Terminator):
def legs_cnt(self):
self.props['legs'] = 2
def hands_cnt(self):
self.props['hands_cnt'] = 2
def liquid_body(self):
self.props['liquid_body'] = True
t_800 = T_800().template_method()
print(t_800.__class__, t_800.props)
t_1000 = T_1000().template_method()
print(t_1000.__class__, t_1000.props)
IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoKZnJvbSBhYmMgaW1wb3J0IEFCQ01ldGEsIGFic3RyYWN0bWV0aG9kCgpjbGFzcyBUZXJtaW5hdG9yKG1ldGFjbGFzcz1BQkNNZXRhKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLnByb3BzID0ge30KCiAgICBkZWYgdGVtcGxhdGVfbWV0aG9kKHNlbGYpOgogICAgICAgIHNlbGYubGVnc19jbnQoKQogICAgICAgIHNlbGYuaGFuZHNfY250KCkKICAgICAgICBzZWxmLmxpcXVpZF9ib2R5KCkKICAgICAgICBzZWxmLnN0ZWVsX3NrZWxldG9uKCkKICAgICAgICByZXR1cm4gc2VsZgoKICAgIEBhYnN0cmFjdG1ldGhvZAogICAgZGVmIGxlZ3NfY250KHNlbGYpOgogICAgICAgIHBhc3MKCiAgICBAYWJzdHJhY3RtZXRob2QKICAgIGRlZiBoYW5kc19jbnQoc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiBsaXF1aWRfYm9keShzZWxmKToKICAgICAgICBwYXNzCgogICAgZGVmIHN0ZWVsX3NrZWxldG9uKHNlbGYpOgogICAgICAgIHBhc3MKCgpjbGFzcyBUXzgwMChUZXJtaW5hdG9yKToKICAgIGRlZiBsZWdzX2NudChzZWxmKToKICAgICAgICBzZWxmLnByb3BzWydsZWdzX2NudCddID0gMgoKICAgIGRlZiBoYW5kc19jbnQoc2VsZik6CiAgICAgICAgc2VsZi5wcm9wc1snaGFuZHNfY250J10gPSAyCgogICAgZGVmIHN0ZWVsX3NrZWxldG9uKHNlbGYpOgogICAgICAgIHNlbGYucHJvcHNbJ3N0ZWVsX3NrZWxldG9uJ10gPSBUcnVlCgpjbGFzcyBUXzEwMDAoVGVybWluYXRvcik6CiAgICBkZWYgbGVnc19jbnQoc2VsZik6CiAgICAgICAgc2VsZi5wcm9wc1snbGVncyddID0gMgoKICAgIGRlZiBoYW5kc19jbnQoc2VsZik6CiAgICAgICAgc2VsZi5wcm9wc1snaGFuZHNfY250J10gPSAyCgogICAgZGVmIGxpcXVpZF9ib2R5KHNlbGYpOgogICAgICAgIHNlbGYucHJvcHNbJ2xpcXVpZF9ib2R5J10gPSBUcnVlCgoKdF84MDAgPSBUXzgwMCgpLnRlbXBsYXRlX21ldGhvZCgpCnByaW50KHRfODAwLl9fY2xhc3NfXywgdF84MDAucHJvcHMpCgp0XzEwMDAgPSBUXzEwMDAoKS50ZW1wbGF0ZV9tZXRob2QoKQpwcmludCh0XzEwMDAuX19jbGFzc19fLCB0XzEwMDAucHJvcHMpCgo=