[
  {
    "path": "chapter1/abstract_factory.py",
    "content": "class Frog:\n\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return self.name\n\n    def interact_with(self, obstacle):\n        print('{} the Frog encounters {} and {}!'.format(self,\n                                                         obstacle, obstacle.action()))\n\n\nclass Bug:\n\n    def __str__(self):\n        return 'a bug'\n\n    def action(self):\n        return 'eats it'\n\n\nclass FrogWorld:\n\n    def __init__(self, name):\n        print(self)\n        self.player_name = name\n\n    def __str__(self):\n        return '\\n\\n\\t------ Frog World ———'\n\n    def make_character(self):\n        return Frog(self.player_name)\n\n    def make_obstacle(self):\n        return Bug()\n\n\nclass Wizard:\n\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return self.name\n\n    def interact_with(self, obstacle):\n        print('{} the Wizard battles against {} and {}!'.format(self, obstacle, obstacle.action()))\n\n\nclass Ork:\n\n    def __str__(self):\n        return 'an evil ork'\n\n    def action(self):\n        return 'kills it'\n\n\nclass WizardWorld:\n\n    def __init__(self, name):\n        print(self)\n        self.player_name = name\n\n    def __str__(self):\n        return '\\n\\n\\t------ Wizard World ———'\n\n    def make_character(self):\n        return Wizard(self.player_name)\n\n    def make_obstacle(self):\n        return Ork()\n\n\nclass GameEnvironment:\n\n    def __init__(self, factory):\n        self.hero = factory.make_character()\n        self.obstacle = factory.make_obstacle()\n\n    def play(self):\n        self.hero.interact_with(self.obstacle)\n\n\ndef validate_age(name):\n    try:\n        age = input('Welcome {}. How old are you? '.format(name))\n        age = int(age)\n    except ValueError as err:\n        print(\"Age {} is invalid, please try \\\n        again…\".format(age))\n        return (False, age)\n    return (True, age)\n\n\ndef main():\n    name = input(\"Hello. What's your name? \")\n    valid_input = False\n    while not valid_input:\n        valid_input, age = validate_age(name)\n    game = FrogWorld if age < 18 else WizardWorld\n    environment = GameEnvironment(game(name))\n    environment.play()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter1/data/donut.json",
    "content": "[\n    {\n        \"id\": \"0001\",\n        \"type\": \"donut\",\n        \"name\": \"Cake\",\n        \"ppu\": 0.55,\n        \"batters\": {\n            \"batter\": [\n                {\n                    \"id\": \"1001\",\n                    \"type\": \"Regular\"\n                },\n                {\n                    \"id\": \"1002\",\n                    \"type\": \"Chocolate\"\n                },\n                {\n                    \"id\": \"1003\",\n                    \"type\": \"Blueberry\"\n                },\n                {\n                    \"id\": \"1004\",\n                    \"type\": \"Devil's Food\"\n                }\n            ]\n        },\n        \"topping\": [\n            {\n                \"id\": \"5001\",\n                \"type\": \"None\"\n            },\n            {\n                \"id\": \"5002\",\n                \"type\": \"Glazed\"\n            },\n            {\n                \"id\": \"5005\",\n                \"type\": \"Sugar\"\n            },\n            {\n                \"id\": \"5007\",\n                \"type\": \"Powdered Sugar\"\n            },\n            {\n                \"id\": \"5006\",\n                \"type\": \"Chocolate with Sprinkles\"\n            },\n            {\n                \"id\": \"5003\",\n                \"type\": \"Chocolate\"\n            },\n            {\n                \"id\": \"5004\",\n                \"type\": \"Maple\"\n            }\n        ]\n    },\n    {\n        \"id\": \"0002\",\n        \"type\": \"donut\",\n        \"name\": \"Raised\",\n        \"ppu\": 0.55,\n        \"batters\": {\n            \"batter\": [\n                {\n                    \"id\": \"1001\",\n                    \"type\": \"Regular\"\n                }\n            ]\n        },\n        \"topping\": [\n            {\n                \"id\": \"5001\",\n                \"type\": \"None\"\n            },\n            {\n                \"id\": \"5002\",\n                \"type\": \"Glazed\"\n            },\n            {\n                \"id\": \"5005\",\n                \"type\": \"Sugar\"\n            },\n            {\n                \"id\": \"5003\",\n                \"type\": \"Chocolate\"\n            },\n            {\n                \"id\": \"5004\",\n                \"type\": \"Maple\"\n            }\n        ]\n    },\n    {\n        \"id\": \"0003\",\n        \"type\": \"donut\",\n        \"name\": \"Old Fashioned\",\n        \"ppu\": 0.55,\n        \"batters\": {\n            \"batter\": [\n                {\n                    \"id\": \"1001\",\n                    \"type\": \"Regular\"\n                },\n                {\n                    \"id\": \"1002\",\n                    \"type\": \"Chocolate\"\n                }\n            ]\n        },\n        \"topping\": [\n            {\n                \"id\": \"5001\",\n                \"type\": \"None\"\n            },\n            {\n                \"id\": \"5002\",\n                \"type\": \"Glazed\"\n            },\n            {\n                \"id\": \"5003\",\n                \"type\": \"Chocolate\"\n            },\n            {\n                \"id\": \"5004\",\n                \"type\": \"Maple\"\n            }\n        ]\n    }\n]"
  },
  {
    "path": "chapter1/data/person.xml",
    "content": "<persons>\n     <person>\n       <firstName>John</firstName>\n       <lastName>Smith</lastName>\n       <age>25</age>\n       <address>\n         <streetAddress>21 2nd Street</streetAddress>\n         <city>New York</city>\n         <state>NY</state>\n         <postalCode>10021</postalCode>\n       </address>\n       <phoneNumbers>\n         <phoneNumber type=\"home\">212 555-1234</phoneNumber>\n         <phoneNumber type=\"fax\">646 555-4567</phoneNumber>\n       </phoneNumbers>\n       <gender>\n         <type>male</type>\n       </gender>\n     </person>\n     <person>\n       <firstName>Jimy</firstName>\n       <lastName>Liar</lastName>\n    <age>19</age>\n    <address>\n      <streetAddress>18 2nd Street</streetAddress>\n      <city>New York</city>\n      <state>NY</state>\n      <postalCode>10021</postalCode>\n    </address>\n    <phoneNumbers>\n      <phoneNumber type=\"home\">212 555-1234</phoneNumber>\n    </phoneNumbers>\n    <gender>\n      <type>male</type>\n    </gender>\n  </person>\n  <person>\n    <firstName>Patty</firstName>\n    <lastName>Liar</lastName>\n    <age>20</age>\n    <address>\n      <streetAddress>18 2nd Street</streetAddress>\n      <city>New York</city>\n      <state>NY</state>\n      <postalCode>10021</postalCode>\n    </address>\n    <phoneNumbers>\n      <phoneNumber type=\"home\">212 555-1234</phoneNumber>\n      <phoneNumber type=\"mobile\">001 452-8819</phoneNumber>\n    </phoneNumbers>\n    <gender>\n      <type>female</type>\n    </gender>\n  </person>\n</persons>"
  },
  {
    "path": "chapter1/factory_method.py",
    "content": "import xml.etree.ElementTree as etree\nimport json\n\n\nclass JSONConnector:\n\n    def __init__(self, filepath):\n        self.data = dict()\n        with open(filepath, mode='r', encoding='utf-8') as f:\n            self.data = json.load(f)\n\n    @property\n    def parsed_data(self):\n        return self.data\n\n\nclass XMLConnector:\n\n    def __init__(self, filepath):\n        self.tree = etree.parse(filepath)\n\n    @property\n    def parsed_data(self):\n        return self.tree\n\n\ndef connection_factory(filepath):\n    if filepath.endswith('json'):\n        connector = JSONConnector\n    elif filepath.endswith('xml'):\n        connector = XMLConnector\n    else:\n        raise ValueError('Cannot connect to {}'.format(filepath))\n    return connector(filepath)\n\n\ndef connect_to(filepath):\n    factory = None\n    try:\n        factory = connection_factory(filepath)\n    except ValueError as ve:\n        print(ve)\n    return factory\n\n\ndef main():\n    sqlite_factory = connect_to('data/person.sq3')\n    print()\n\n    xml_factory = connect_to('data/person.xml')\n    xml_data = xml_factory.parsed_data\n    liars = xml_data.findall(\".//{}[{}='{}']\".format('person',\n                                                     'lastName', 'Liar'))\n    print('found: {} persons'.format(len(liars)))\n    for liar in liars:\n        print('first name: {}'.format(liar.find('firstName').text))\n        print('last name: {}'.format(liar.find('lastName').text))\n        [print('phone number ({})'.format(p.attrib['type']),\n               p.text) for p in liar.find('phoneNumbers')]\n\n    print()\n\n    json_factory = connect_to('data/donut.json')\n    json_data = json_factory.parsed_data\n    print('found: {} donuts'.format(len(json_data)))\n    for donut in json_data:\n        print('name: {}'.format(donut['name']))\n        print('price: ${}'.format(donut['ppu']))\n        [print('topping: {} {}'.format(t['id'], t['type'])) for t in donut['topping']]\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter1/id.py",
    "content": "class A(object):\n    pass\n\nif __name__ == '__main__':\n    a = A()\n    b = A()\n\n    print(id(a) == id(b))\n    print(a, b)\n"
  },
  {
    "path": "chapter10/chain.py",
    "content": "class Event:\n\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return self.name\n\n\nclass Widget:\n\n    def __init__(self, parent=None):\n        self.parent = parent\n\n    def handle(self, event):\n        handler = 'handle_{}'.format(event)\n        if hasattr(self, handler):\n            method = getattr(self, handler)\n            method(event)\n        elif self.parent:\n            self.parent.handle(event)\n        elif hasattr(self, 'handle_default'):\n            self.handle_default(event)\n\n\nclass MainWindow(Widget):\n\n    def handle_close(self, event):\n        print('MainWindow: {}'.format(event))\n\n    def handle_default(self, event):\n        print('MainWindow Default: {}'.format(event))\n\n\nclass SendDialog(Widget):\n\n    def handle_paint(self, event):\n        print('SendDialog: {}'.format(event))\n\n\nclass MsgText(Widget):\n\n    def handle_down(self, event):\n        print('MsgText: {}'.format(event))\n\n\ndef main():\n    mw = MainWindow()\n    sd = SendDialog(mw)\n    msg = MsgText(sd)\n\n    for e in ('down', 'paint', 'unhandled', 'close'):\n        evt = Event(e)\n        print('\\nSending event -{}- to MainWindow'.format(evt))\n        mw.handle(evt)\n        print('Sending event -{}- to SendDialog'.format(evt))\n        sd.handle(evt)\n        print('Sending event -{}- to MsgText'.format(evt))\n        msg.handle(evt)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter11/command.py",
    "content": "import os\n\nverbose = True\n\n\nclass RenameFile:\n\n    def __init__(self, path_src, path_dest):\n        self.src, self.dest = path_src, path_dest\n\n    def execute(self):\n        if verbose:\n            print(\"[renaming '{}' to '{}']\".format(self.src, self.dest))\n        os.rename(self.src, self.dest)\n\n    def undo(self):\n        if verbose:\n            print(\"[renaming '{}' back to '{}']\".format(self.dest, self.src))\n        os.rename(self.dest, self.src)\n\n\nclass CreateFile:\n\n    def __init__(self, path, txt='hello world\\n'):\n        self.path, self.txt = path, txt\n\n    def execute(self):\n        if verbose:\n            print(\"[creating file '{}']\".format(self.path))\n        with open(self.path, mode='w', encoding='utf-8') as out_file:\n            out_file.write(self.txt)\n\n    def undo(self):\n        delete_file(self.path)\n\n\nclass ReadFile:\n\n    def __init__(self, path):\n        self.path = path\n\n    def execute(self):\n        if verbose:\n            print(\"[reading file '{}']\".format(self.path))\n        with open(self.path, mode='r', encoding='utf-8') as in_file:\n            print(in_file.read(), end='')\n\n\ndef delete_file(path):\n    if verbose:\n        print(\"deleting file '{}'\".format(path))\n    os.remove(path)\n\n\ndef main():\n    orig_name, new_name = 'file1', 'file2'\n\n    commands = []\n    for cmd in CreateFile(orig_name), ReadFile(orig_name), RenameFile(orig_name, new_name):\n        commands.append(cmd)\n\n    [c.execute() for c in commands]\n\n    answer = input('reverse the executed commands? [y/n] ')\n\n    if answer not in 'yY':\n        print(\"the result is {}\".format(new_name))\n        exit()\n\n    for c in reversed(commands):\n        try:\n            c.undo()\n        except AttributeError as e:\n            pass\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter11/first-class.py",
    "content": "import os\n\nverbose = True\n\n\nclass RenameFile:\n\n    def __init__(self, path_src, path_dest):\n        self.src, self.dest = path_src, path_dest\n\n    def execute(self):\n        if verbose:\n            print(\"[renaming '{}' to '{}']\".format(self.src, self.dest))\n        os.rename(self.src, self.dest)\n\n    def undo(self):\n        if verbose:\n            print(\"[renaming '{}' back to '{}']\".format(self.dest, self.src))\n        os.rename(self.dest, self.src)\n\n\nclass CreateFile:\n\n    def __init__(self, path, txt='hello world\\n'):\n        self.path, self.txt = path, txt\n\n    def execute(self):\n        if verbose:\n            print(\"[creating file '{}']\".format(self.path))\n        with open(self.path, mode='w', encoding='utf-8') as out_file:\n            out_file.write(self.txt)\n\n    def undo(self):\n        delete_file(self.path)\n\n\nclass ReadFile:\n\n    def __init__(self, path):\n        self.path = path\n\n    def execute(self):\n        if verbose:\n            print(\"[reading file '{}']\".format(self.path))\n        with open(self.path, mode='r', encoding='utf-8') as in_file:\n            print(in_file.read(), end='')\n\n\ndef delete_file(path):\n    if verbose:\n        print(\"deleting file '{}'\".format(path))\n    os.remove(path)\n\n\ndef main():\n    orig_name = 'file1'\n    df = delete_file\n\n    commands = []\n    commands.append(df)\n\n    for c in commands:\n        try:\n            c.execute()\n        except AttributeError as e:\n            df(orig_name)\n\n    for c in reversed(commands):\n        try:\n            c.undo()\n        except AttributeError as e:\n            pass\n\nif __name__ == '__main__':\n    '''\n    译注：这个程序会异常退出\n    '''\n    main()\n"
  },
  {
    "path": "chapter12/interpreter.py",
    "content": "# coding: utf-8\n\nfrom pyparsing import Word, OneOrMore, Optional, Group, Suppress, alphanums\n\n\nclass Gate:\n\n    def __init__(self):\n        self.is_open = False\n\n    def __str__(self):\n        return 'open' if self.is_open else 'closed'\n\n    def open(self):\n        print('opening the gate')\n        self.is_open = True\n\n    def close(self):\n        print('closing the gate')\n        self.is_open = False\n\n\nclass Garage:\n\n    def __init__(self):\n        self.is_open = False\n\n    def __str__(self):\n        return 'open' if self.is_open else 'closed'\n\n    def open(self):\n        print('opening the garage')\n        self.is_open = True\n\n    def close(self):\n        print('closing the garage')\n        self.is_open = False\n\n\nclass Aircondition:\n\n    def __init__(self):\n        self.is_on = False\n\n    def __str__(self):\n        return 'on' if self.is_on else 'off'\n\n    def turn_on(self):\n        print('turning on the aircondition')\n        self.is_on = True\n\n    def turn_off(self):\n        print('turning off the aircondition')\n        self.is_on = False\n\n\nclass Heating:\n\n    def __init__(self):\n        self.is_on = False\n\n    def __str__(self):\n        return 'on' if self.is_on else 'off'\n\n    def turn_on(self):\n        print('turning on the heating')\n        self.is_on = True\n\n    def turn_off(self):\n        print('turning off the heating')\n        self.is_on = False\n\n\nclass Boiler:\n\n    def __init__(self):\n        self.temperature = 83  # in celsius\n\n    def __str__(self):\n        return 'boiler temperature: {}'.format(self.temperature)\n\n    def increase_temperature(self, amount):\n        print(\"increasing the boiler's temperature by {} degrees\".format(amount))\n        self.temperature += amount\n\n    def decrease_temperature(self, amount):\n        print(\"decreasing the boiler's temperature by {} degrees\".format(amount))\n        self.temperature -= amount\n\n\nclass Fridge:\n\n    def __init__(self):\n        self.temperature = 2  # 单位为摄氏度\n\n    def __str__(self):\n        return 'fridge temperature: {}'.format(self.temperature)\n\n    def increase_temperature(self, amount):\n        print(\"increasing the fridge's temperature by {} degrees\".format(amount))\n        self.temperature += amount\n\n    def decrease_temperature(self, amount):\n        print(\"decreasing the fridge's temperature by {} degrees\".format(amount))\n        self.temperature -= amount\n\n\ndef main():\n    word = Word(alphanums)\n    command = Group(OneOrMore(word))\n    token = Suppress(\"->\")\n    device = Group(OneOrMore(word))\n    argument = Group(OneOrMore(word))\n    event = command + token + device + Optional(token + argument)\n\n    gate = Gate()\n    garage = Garage()\n    airco = Aircondition()\n    heating = Heating()\n    boiler = Boiler()\n    fridge = Fridge()\n\n    tests = ('open -> gate',\n             'close -> garage',\n             'turn on -> aircondition',\n             'turn off -> heating',\n             'increase -> boiler temperature -> 5 degrees',\n             'decrease -> fridge temperature -> 2 degrees')\n    open_actions = {'gate': gate.open,\n                    'garage': garage.open,\n                    'aircondition': airco.turn_on,\n                    'heating': heating.turn_on,\n                    'boiler temperature': boiler.increase_temperature,\n                    'fridge temperature': fridge.increase_temperature}\n    close_actions = {'gate': gate.close,\n                     'garage': garage.close,\n                     'aircondition': airco.turn_off,\n                     'heating': heating.turn_off,\n                     'boiler temperature': boiler.decrease_temperature,\n                     'fridge temperature': fridge.decrease_temperature}\n\n    for t in tests:\n        if len(event.parseString(t)) == 2:  # 没有参数\n            cmd, dev = event.parseString(t)\n            cmd_str, dev_str = ' '.join(cmd), ' '.join(dev)\n            if 'open' in cmd_str or 'turn on' in cmd_str:\n                open_actions[dev_str]()\n            elif 'close' in cmd_str or 'turn off' in cmd_str:\n                close_actions[dev_str]()\n        elif len(event.parseString(t)) == 3:  # 有参数\n            cmd, dev, arg = event.parseString(t)\n            cmd_str, dev_str, arg_str = ' '.join(cmd), ' '.join(dev), ' '.join(arg)\n            num_arg = 0\n            try:\n                num_arg = int(arg_str.split()[0])  # 抽取数值部分\n            except ValueError as err:\n                print(\"expected number but got: '{}'\".format(arg_str[0]))\n            if 'increase' in cmd_str and num_arg > 0:\n                open_actions[dev_str](num_arg)\n            elif 'decrease' in cmd_str and num_arg > 0:\n                close_actions[dev_str](num_arg)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter13/observer.py",
    "content": "class Publisher:\n\n    def __init__(self):\n        self.observers = []\n\n    def add(self, observer):\n        if observer not in self.observers:\n            self.observers.append(observer)\n        else:\n            print('Failed to add: {}'.format(observer))\n\n    def remove(self, observer):\n        try:\n            self.observers.remove(observer)\n        except ValueError:\n            print('Failed to remove: {}'.format(observer))\n\n    def notify(self):\n        [o.notify(self) for o in self.observers]\n\n\nclass DefaultFormatter(Publisher):\n\n    def __init__(self, name):\n        Publisher.__init__(self)\n        self.name = name\n        self._data = 0\n\n    def __str__(self):\n        return \"{}: '{}' has data = {}\".format(type(self).__name__, self.name, self._data)\n\n    @property\n    def data(self):\n        return self._data\n\n    @data.setter\n    def data(self, new_value):\n        try:\n            self._data = int(new_value)\n        except ValueError as e:\n            print('Error: {}'.format(e))\n        else:\n            self.notify()\n\n\nclass HexFormatter:\n\n    def notify(self, publisher):\n        print(\"{}: '{}' has now hex data = {}\".format(type(self).__name__,\n                                                      publisher.name, hex(publisher.data)))\n\n\nclass BinaryFormatter:\n\n    def notify(self, publisher):\n        print(\"{}: '{}' has now bin data = {}\".format(type(self).__name__,\n                                                      publisher.name, bin(publisher.data)))\n\n\ndef main():\n    df = DefaultFormatter('test1')\n    print(df)\n\n    print()\n    hf = HexFormatter()\n    df.add(hf)\n    df.data = 3\n    print(df)\n\n    print()\n    bf = BinaryFormatter()\n    df.add(bf)\n    df.data = 21\n    print(df)\n\n    print()\n    df.remove(hf)\n    df.data = 40\n    print(df)\n\n    print()\n    df.remove(hf)\n    df.add(bf)\n    df.data = 'hello'\n    print(df)\n\n    print()\n    df.data = 15.8\n    print(df)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter14/state.py",
    "content": "from state_machine import State, Event, acts_as_state_machine, after, before, InvalidStateTransition\n\n\n@acts_as_state_machine\nclass Process:\n    created = State(initial=True)\n    waiting = State()\n    running = State()\n    terminated = State()\n    blocked = State()\n    swapped_out_waiting = State()\n    swapped_out_blocked = State()\n\n    wait = Event(from_states=(created, running, blocked,\n                              swapped_out_waiting), to_state=waiting)\n    run = Event(from_states=waiting, to_state=running)\n    terminate = Event(from_states=running, to_state=terminated)\n    block = Event(from_states=(running, swapped_out_blocked),\n                  to_state=blocked)\n    swap_wait = Event(from_states=waiting, to_state=swapped_out_waiting)\n    swap_block = Event(from_states=blocked, to_state=swapped_out_blocked)\n\n    def __init__(self, name):\n        self.name = name\n\n    @after('wait')\n    def wait_info(self):\n        print('{} entered waiting mode'.format(self.name))\n\n    @after('run')\n    def run_info(self):\n        print('{} is running'.format(self.name))\n\n    @before('terminate')\n    def terminate_info(self):\n        print('{} terminated'.format(self.name))\n\n    @after('block')\n    def block_info(self):\n        print('{} is blocked'.format(self.name))\n\n    @after('swap_wait')\n    def swap_wait_info(self):\n        print('{} is swapped out and waiting'.format(self.name))\n\n    @after('swap_block')\n    def swap_block_info(self):\n        print('{} is swapped out and blocked'.format(self.name))\n\n\ndef transition(process, event, event_name):\n    try:\n        event()\n    except InvalidStateTransition as err:\n        print('Error: transition of {} from {} to {} failed'.format(process.name,\n                                                                    process.current_state, event_name))\n\n\ndef state_info(process):\n    print('state of {}: {}'.format(process.name, process.current_state))\n\n\ndef main():\n    RUNNING = 'running'\n    WAITING = 'waiting'\n    BLOCKED = 'blocked'\n    TERMINATED = 'terminated'\n\n    p1, p2 = Process('process1'), Process('process2')\n    [state_info(p) for p in (p1, p2)]\n\n    print()\n    transition(p1, p1.wait, WAITING)\n    transition(p2, p2.terminate, TERMINATED)\n    [state_info(p) for p in (p1, p2)]\n\n    print()\n    transition(p1, p1.run, RUNNING)\n    transition(p2, p2.wait, WAITING)\n    [state_info(p) for p in (p1, p2)]\n\n    print()\n    transition(p2, p2.run, RUNNING)\n    [state_info(p) for p in (p1, p2)]\n\n    print()\n    [transition(p, p.block, BLOCKED) for p in (p1, p2)]\n    [state_info(p) for p in (p1, p2)]\n\n    print()\n    [transition(p, p.terminate, TERMINATED) for p in (p1, p2)]\n    [state_info(p) for p in (p1, p2)]\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter15/langs.py",
    "content": "import pprint\nfrom collections import namedtuple\nfrom operator import attrgetter\nif __name__ == '__main__':\n    ProgrammingLang = namedtuple('ProgrammingLang', 'name ranking')\n    stats = (('Ruby', 14), ('Javascript', 8), ('Python', 7),\n             ('Scala', 31), ('Swift', 18), ('Lisp', 23))\n    lang_stats = [ProgrammingLang(n, r) for n, r in stats]\n    pp = pprint.PrettyPrinter(indent=5)\n    pp.pprint(sorted(lang_stats, key=attrgetter('name')))\n    print()\n    pp.pprint(sorted(lang_stats, key=attrgetter('ranking')))\n"
  },
  {
    "path": "chapter15/strategy.py",
    "content": "# coding: utf-8\n\nimport time\nSLOW = 3  # 单位为秒\nLIMIT = 5   # 字符数\nWARNING = 'too bad, you picked the slow algorithm :('\n\n\ndef pairs(seq):\n    n = len(seq)\n    for i in range(n):\n        yield seq[i], seq[(i + 1) % n]\n\n\ndef allUniqueSort(s):\n    if len(s) > LIMIT:\n        print(WARNING)\n        time.sleep(SLOW)\n    srtStr = sorted(s)\n    for (c1, c2) in pairs(srtStr):\n        if c1 == c2:\n            return False\n    return True\n\n\ndef allUniqueSet(s):\n    if len(s) < LIMIT:\n        print(WARNING)\n        time.sleep(SLOW)\n    return True if len(set(s)) == len(s) else False\n\n\ndef allUnique(s, strategy):\n    return strategy(s)\n\n\ndef main():\n    while True:\n        word = None\n        while not word:\n            word = input('Insert word (type quit to exit)> ')\n            if word == 'quit':\n                print('bye')\n                return\n\n            strategy_picked = None\n            strategies = {'1': allUniqueSet, '2': allUniqueSort}\n            while strategy_picked not in strategies.keys():\n                strategy_picked = input('Choose strategy: [1] Use a set, [2] Sort and pair> ')\n\n                try:\n                    strategy = strategies[strategy_picked]\n                    print('allUnique({}): {}'.format(word, allUnique(word, strategy)))\n                except KeyError as err:\n                    print('Incorrect option: {}'.format(strategy_picked))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter16/graph.py",
    "content": "# coding: utf-8\n\n\ndef bfs(graph, start, end):\n    path = []\n    visited = [start]\n    while visited:\n        current = visited.pop(0)\n        if current not in path:\n            path.append(current)\n            if current == end:\n                print(path)\n                return (True, path)\n            # 两个顶点不相连，则跳过\n            if current not in graph:\n                continue\n        visited = visited + graph[current]\n    return (False, path)\n\n\ndef dfs(graph, start, end):\n    path = []\n    visited = [start]\n    while visited:\n        current = visited.pop(0)\n        if current not in path:\n            path.append(current)\n            if current == end:\n                print(path)\n                return (True, path)\n            # 两个顶点不相连，则跳过\n            if current not in graph:\n                continue\n        visited = graph[current] + visited\n    return (False, path)\n\n\ndef main():\n    graph = {\n        'Frankfurt': ['Mannheim', 'Wurzburg', 'Kassel'],\n        'Mannheim': ['Karlsruhe'],\n        'Karlsruhe': ['Augsburg'],\n        'Augsburg': ['Munchen'],\n        'Wurzburg': ['Erfurt', 'Nurnberg'],\n        'Nurnberg': ['Stuttgart', 'Munchen'],\n        'Kassel': ['Munchen'],\n        'Erfurt': [],\n        'Stuttgart': [],\n        'Munchen': []\n    }\n\n    bfs_path = bfs(graph, 'Frankfurt', 'Nurnberg')\n    dfs_path = dfs(graph, 'Frankfurt', 'Nurnberg')\n    print('bfs Frankfurt-Nurnberg: {}'.format(bfs_path[1] if bfs_path[0] else 'Not found'))\n    print('dfs Frankfurt-Nurnberg: {}'.format(dfs_path[1] if dfs_path[0] else 'Not found'))\n\n    bfs_nopath = bfs(graph, 'Wurzburg', 'Kassel')\n    print('bfs Wurzburg-Kassel: {}'.format(bfs_nopath[1] if bfs_nopath[0] else 'Not found'))\n    dfs_nopath = dfs(graph, 'Wurzburg', 'Kassel')\n    print('dfs Wurzburg-Kassel: {}'.format(dfs_nopath[1] if dfs_nopath[0] else 'Not found'))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter16/graph_template.py",
    "content": "# coding: utf-8\n\n\ndef traverse(graph, start, end, action):\n    path = []\n    visited = [start]\n    while visited:\n        current = visited.pop(0)\n        if current not in path:\n            path.append(current)\n            if current == end:\n                return (True, path)\n            # 两个顶点不相连，则跳过\n            if current not in graph:\n                continue\n        visited = action(visited, graph[current])\n    return (False, path)\n\n\ndef extend_bfs_path(visited, current):\n    return visited + current\n\n\ndef extend_dfs_path(visited, current):\n    return current + visited\n\n\ndef main():\n    graph = {\n        'Frankfurt': ['Mannheim', 'Wurzburg', 'Kassel'],\n        'Mannheim': ['Karlsruhe'],\n        'Karlsruhe': ['Augsburg'],\n        'Augsburg': ['Munchen'],\n        'Wurzburg': ['Erfurt', 'Nurnberg'],\n        'Nurnberg': ['Stuttgart', 'Munchen'],\n        'Kassel': ['Munchen'],\n        'Erfurt': [],\n        'Stuttgart': [],\n        'Munchen': []\n    }\n\n    bfs_path = traverse(graph, 'Frankfurt', 'Nurnberg', extend_bfs_path)\n    dfs_path = traverse(graph, 'Frankfurt', 'Nurnberg', extend_dfs_path)\n    print('bfs Frankfurt-Nurnberg: {}'.format(bfs_path[1] if bfs_path[0] else 'Not found'))\n    print('dfs Frankfurt-Nurnberg: {}'.format(dfs_path[1] if dfs_path[0] else 'Not found'))\n\n    bfs_nopath = traverse(graph, 'Wurzburg', 'Kassel', extend_bfs_path)\n    print('bfs Wurzburg-Kassel: {}'.format(bfs_nopath[1] if bfs_nopath[0] else 'Not found'))\n    dfs_nopath = traverse(graph, 'Wurzburg', 'Kassel', extend_dfs_path)\n    print('dfs Wurzburg-Kassel: {}'.format(dfs_nopath[1] if dfs_nopath[0] else 'Not found'))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter16/graph_template_slower.py",
    "content": "# coding: utf-8\n\nBFS = 1\nDFS = 2\n\n\ndef traverse(graph, start, end, algorithm):\n    path = []\n    visited = [start]\n    while visited:\n        current = visited.pop(0)\n        if current not in path:\n            path.append(current)\n            if current == end:\n                return (True, path)\n            # 顶点不相连，则跳过\n            if current not in graph:\n                continue\n        if algorithm == BFS:\n            visited = extend_bfs_path(visited, graph[current])\n        elif algorithm == DFS:\n            visited = extend_dfs_path(visited, graph[current])\n        else:\n            raise ValueError(\"No such algorithm\")\n    return (False, path)\n\n\ndef extend_bfs_path(visited, current):\n    return visited + current\n\n\ndef extend_dfs_path(visited, current):\n    return current + visited\n\n\ndef main():\n    graph = {\n        'Frankfurt': ['Mannheim', 'Wurzburg', 'Kassel'],\n        'Mannheim': ['Karlsruhe'],\n        'Karlsruhe': ['Augsburg'],\n        'Augsburg': ['Munchen'],\n        'Wurzburg': ['Erfurt', 'Nurnberg'],\n        'Nurnberg': ['Stuttgart', 'Munchen'],\n        'Kassel': ['Munchen'],\n        'Erfurt': [],\n        'Stuttgart': [],\n        'Munchen': []\n    }\n\n    bfs_path = traverse(graph, 'Frankfurt', 'Nurnberg', 1)\n    dfs_path = traverse(graph, 'Frankfurt', 'Nurnberg', 2)\n    print('bfs Frankfurt-Nurnberg: {}'.format(bfs_path[1] if bfs_path[0] else 'Not found'))\n    print('dfs Frankfurt-Nurnberg: {}'.format(dfs_path[1] if dfs_path[0] else 'Not found'))\n\n    bfs_nopath = traverse(graph, 'Wurzburg', 'Kassel', 1)\n    print('bfs Wurzburg-Kassel: {}'.format(bfs_nopath[1] if bfs_nopath[0] else 'Not found'))\n    dfs_nopath = traverse(graph, 'Wurzburg', 'Kassel', 2)\n    print('dfs Wurzburg-Kassel: {}'.format(dfs_nopath[1] if dfs_nopath[0] else 'Not found'))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter16/template.py",
    "content": "from cowpy import cow\n\n\ndef dots_style(msg):\n    msg = msg.capitalize()\n    msg = '.' * 10 + msg + '.' * 10\n    return msg\n\n\ndef admire_style(msg):\n    msg = msg.upper()\n    return '!'.join(msg)\n\n\ndef cow_style(msg):\n    msg = cow.milk_random_cow(msg)\n    return msg\n\n\ndef generate_banner(msg, style=dots_style):\n    print('-- start of banner --')\n    print(style(msg))\n    print('-- end of banner --\\n\\n')\n\n\ndef main():\n    msg = 'happy coding'\n    [generate_banner(msg, style) for style in (dots_style, admire_style, cow_style)]\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter2/apple-factory.py",
    "content": "# coding: utf-8\n\nMINI14 = '1.4GHz Mac mini'\n\n\nclass AppleFactory:\n\n    class MacMini14:\n\n        def __init__(self):\n            self.memory = 4  # 单位为GB\n            self.hdd = 500  # 单位为GB\n            self.gpu = 'Intel HD Graphics 5000'\n\n        def __str__(self):\n            info = ('Model: {}'.format(MINI14),\n                    'Memory: {}GB'.format(self.memory),\n                    'Hard Disk: {}GB'.format(self.hdd),\n                    'Graphics Card: {}'.format(self.gpu))\n            return '\\n'.join(info)\n\n    def build_computer(self, model):\n        if (model == MINI14):\n            return self.MacMini14()\n        else:\n            print(\"I dont't know how to build {}\".format(model))\n\nif __name__ == '__main__':\n    afac = AppleFactory()\n    mac_mini = afac.build_computer(MINI14)\n    print(mac_mini)\n"
  },
  {
    "path": "chapter2/builder.py",
    "content": "# coding: utf-8\n\nfrom enum import Enum\nimport time\n\nPizzaProgress = Enum('PizzaProgress', 'queued preparation baking ready')\nPizzaDough = Enum('PizzaDough', 'thin thick')\nPizzaSauce = Enum('PizzaSauce', 'tomato creme_fraiche')\nPizzaTopping = Enum('PizzaTopping', 'mozzarella double_mozzarella bacon ham mushrooms red_onion oregano')\nSTEP_DELAY = 3          # 考虑是示例，单位为秒\n\n\nclass Pizza:\n\n    def __init__(self, name):\n        self.name = name\n        self.dough = None\n        self.sauce = None\n        self.topping = []\n\n    def __str__(self):\n        return self.name\n\n    def prepare_dough(self, dough):\n        self.dough = dough\n        print('preparing the {} dough of your {}...'.format(self.dough.name, self))\n        time.sleep(STEP_DELAY)\n        print('done with the {} dough'.format(self.dough.name))\n\n\nclass MargaritaBuilder:\n\n    def __init__(self):\n        self.pizza = Pizza('margarita')\n        self.progress = PizzaProgress.queued\n        self.baking_time = 5        # 考虑是示例，单位为秒\n\n    def prepare_dough(self):\n        self.progress = PizzaProgress.preparation\n        self.pizza.prepare_dough(PizzaDough.thin)\n\n    def add_sauce(self):\n        print('adding the tomato sauce to your margarita...')\n        self.pizza.sauce = PizzaSauce.tomato\n        time.sleep(STEP_DELAY)\n        print('done with the tomato sauce')\n\n    def add_topping(self):\n        print('adding the topping (double mozzarella, oregano) to your margarita')\n        self.pizza.topping.append([i for i in\n                                   (PizzaTopping.double_mozzarella, PizzaTopping.oregano)])\n        time.sleep(STEP_DELAY)\n        print('done with the topping (double mozzarrella, oregano)')\n\n    def bake(self):\n        self.progress = PizzaProgress.baking\n        print('baking your margarita for {} seconds'.format(self.baking_time))\n        time.sleep(self.baking_time)\n        self.progress = PizzaProgress.ready\n        print('your margarita is ready')\n\n\nclass CreamyBaconBuilder:\n\n    def __init__(self):\n        self.pizza = Pizza('creamy bacon')\n        self.progress = PizzaProgress.queued\n        self.baking_time = 7        # 考虑是示例，单位为秒\n\n    def prepare_dough(self):\n        self.progress = PizzaProgress.preparation\n        self.pizza.prepare_dough(PizzaDough.thick)\n\n    def add_sauce(self):\n        print('adding the crème fraîche sauce to your creamy bacon')\n        self.pizza.sauce = PizzaSauce.creme_fraiche\n        time.sleep(STEP_DELAY)\n        print('done with the crème fraîche sauce')\n\n    def add_topping(self):\n        print('adding the topping (mozzarella, bacon, ham, mushrooms, red onion, oregano) to your creamy bacon')\n        self.pizza.topping.append([t for t in\n                                   (PizzaTopping.mozzarella, PizzaTopping.bacon,\n                                    PizzaTopping.ham, PizzaTopping.mushrooms,\n                                    PizzaTopping.red_onion, PizzaTopping.oregano)])\n        time.sleep(STEP_DELAY)\n        print('done with the topping (mozzarella, bacon, ham, mushrooms, red onion, oregano)')\n\n    def bake(self):\n        self.progress = PizzaProgress.baking\n        print('baking your creamy bacon for {} seconds'.format(self.baking_time))\n        time.sleep(self.baking_time)\n        self.progress = PizzaProgress.ready\n        print('your creamy bacon is ready')\n\n\nclass Waiter:\n\n    def __init__(self):\n        self.builder = None\n\n    def construct_pizza(self, builder):\n        self.builder = builder\n        [step() for step in (builder.prepare_dough,\n                             builder.add_sauce, builder.add_topping, builder.bake)]\n\n    @property\n    def pizza(self):\n        return self.builder.pizza\n\n\ndef validate_style(builders):\n    try:\n        pizza_style = input('What pizza would you like, [m]argarita or [c]reamy bacon? ')\n        builder = builders[pizza_style]()\n        valid_input = True\n    except KeyError as err:\n        print('Sorry, only margarita (key m) and creamy bacon (key c) are available')\n        return (False, None)\n    return (True, builder)\n\n\ndef main():\n    builders = dict(m=MargaritaBuilder, c=CreamyBaconBuilder)\n    valid_input = False\n    while not valid_input:\n        valid_input, builder = validate_style(builders)\n    print()\n    waiter = Waiter()\n    waiter.construct_pizza(builder)\n    pizza = waiter.pizza\n    print()\n    print('Enjoy your {}!'.format(pizza))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter2/builder2.py",
    "content": "# coding: utf-8\n\n\nclass Pizza:\n\n    def __init__(self, builder):\n        self.garlic = builder.garlic\n        self.extra_cheese = builder.extra_cheese\n\n    def __str__(self):\n        garlic = 'yes' if self.garlic else 'no'\n        cheese = 'yes' if self.extra_cheese else 'no'\n        info = ('Garlic: {}'.format(garlic), 'Extra cheese: {}'.format(cheese))\n        return '\\n'.join(info)\n\n    class PizzaBuilder:\n\n        def __init__(self):\n            self.extra_cheese = False\n            self.garlic = False\n\n        def add_garlic(self):\n            self.garlic = True\n            return self\n\n        def add_extra_cheese(self):\n            self.extra_cheese = True\n            return self\n\n        def build(self):\n            return Pizza(self)\n\nif __name__ == '__main__':\n    pizza = Pizza.PizzaBuilder().add_garlic().add_extra_cheese().build()\n    print(pizza)\n"
  },
  {
    "path": "chapter2/computer-builder.py",
    "content": "# coding: utf-8\n\n\nclass Computer:\n\n    def __init__(self, serial_number):\n        self.serial = serial_number\n        self.memory = None      # 单位为GB\n        self.hdd = None         # 单位为GB\n        self.gpu = None\n\n    def __str__(self):\n        info = ('Memory: {}GB'.format(self.memory),\n                'Hard Disk: {}GB'.format(self.hdd),\n                'Graphics Card: {}'.format(self.gpu))\n        return '\\n'.join(info)\n\n\nclass ComputerBuilder:\n\n    def __init__(self):\n        self.computer = Computer('AG23385193')\n\n    def configure_memory(self, amount):\n        self.computer.memory = amount\n\n    def configure_hdd(self, amount):\n        self.computer.hdd = amount\n\n    def configure_gpu(self, gpu_model):\n        self.computer.gpu = gpu_model\n\n\nclass HardwareEngineer:\n\n    def __init__(self):\n        self.builder = None\n\n    def construct_computer(self, memory, hdd, gpu):\n        self.builder = ComputerBuilder()\n        [step for step in (self.builder.configure_memory(memory),\n                           self.builder.configure_hdd(hdd),\n                           self.builder.configure_gpu(gpu))]\n\n    @property\n    def computer(self):\n        return self.builder.computer\n\n\ndef main():\n    engineer = HardwareEngineer()\n    engineer.construct_computer(hdd=500, memory=8, gpu='GeForce GTX 650 Ti')\n    computer = engineer.computer\n    print(computer)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter3/clone.py",
    "content": "import copy\n\n\nclass A:\n\n    def __init__(self):\n        self.x = 18\n        self.msg = 'Hello'\n\n\nclass B(A):\n\n    def __init__(self):\n        A.__init__(self)\n        self.y = 34\n\n    def __str__(self):\n        return '{}, {}, {}'.format(self.x, self.msg, self.y)\n\nif __name__ == '__main__':\n    b = B()\n    c = copy.deepcopy(b)\n    print([str(i) for i in (b, c)])\n    print([i for i in (b, c)])\n"
  },
  {
    "path": "chapter3/prototype.py",
    "content": "# coding: utf-8\n\nimport copy\nfrom collections import OrderedDict\n\n\nclass Book:\n\n    def __init__(self, name, authors, price, **rest):\n        '''rest的例子有：出版商，长度，标签，出版日期'''\n        self.name = name\n        self.authors = authors\n        self.price = price      # 单位为美元\n        self.__dict__.update(rest)\n\n    def __str__(self):\n        mylist = []\n        ordered = OrderedDict(sorted(self.__dict__.items()))\n        for i in ordered.keys():\n            mylist.append('{}: {}'.format(i, ordered[i]))\n            if i == 'price':\n                mylist.append('$')\n            mylist.append('\\n')\n        return ''.join(mylist)\n\n\nclass Prototype:\n\n    def __init__(self):\n        self.objects = dict()\n\n    def register(self, identifier, obj):\n        self.objects[identifier] = obj\n\n    def unregister(self, identifier):\n        del self.objects[identifier]\n\n    def clone(self, identifier, **attr):\n        found = self.objects.get(identifier)\n        if not found:\n            raise ValueError('Incorrect object identifier: {}'.format(identifier))\n        obj = copy.deepcopy(found)\n        obj.__dict__.update(attr)\n        return obj\n\n\ndef main():\n    b1 = Book('The C Programming Language', ('Brian W. Kernighan', 'Dennis M.Ritchie'), price=118, publisher='Prentice Hall',\n              length=228, publication_date='1978-02-22', tags=('C', 'programming', 'algorithms', 'data structures'))\n\n    prototype = Prototype()\n    cid = 'k&r-first'\n    prototype.register(cid, b1)\n    b2 = prototype.clone(cid, name='The C Programming Language(ANSI)', price=48.99,\n                         length=274, publication_date='1988-04-01', edition=2)\n\n    for i in (b1, b2):\n        print(i)\n    print('ID b1 : {} != ID b2 : {}'.format(id(b1), id(b2)))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter4/adapter.py",
    "content": "from external import Synthesizer, Human\n\n\nclass Computer:\n\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return 'the {} computer'.format(self.name)\n\n    def execute(self):\n        return 'executes a program'\n\n\nclass Adapter:\n\n    def __init__(self, obj, adapted_methods):\n        self.obj = obj\n        self.__dict__.update(adapted_methods)\n\n    def __str__(self):\n        return str(self.obj)\n\n\ndef main():\n    objects = [Computer('Asus')]\n    synth = Synthesizer('moog')\n    objects.append(Adapter(synth, dict(execute=synth.play)))\n    human = Human('Bob')\n    objects.append(Adapter(human, dict(execute=human.speak)))\n\n    for i in objects:\n        print('{} {}'.format(str(i), i.execute()))\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "chapter4/external.py",
    "content": "class Synthesizer:\n\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return 'the {} synthesizer'.format(self.name)\n\n    def play(self):\n        return 'is playing an electronic song'\n\n\nclass Human:\n\n    def __init__(self, name):\n        self.name = name\n\n    def __str__(self):\n        return '{} the human'.format(self.name)\n\n    def speak(self):\n        return 'says hello'\n"
  },
  {
    "path": "chapter5/mymath.py",
    "content": "# coding: utf-8\n\nimport functools\n\n\ndef memoize(fn):\n    known = dict()\n\n    @functools.wraps(fn)\n    def memoizer(*args):\n        if args not in known:\n            known[args] = fn(*args)\n        return known[args]\n\n    return memoizer\n\n\n@memoize\ndef nsum(n):\n    '''返回前n个数字的和'''\n    assert(n >= 0), 'n must be >= 0'\n    return 0 if n == 0 else n + nsum(n-1)\n\n\n@memoize\ndef fibonacci(n):\n    '''返回斐波那契数列的第n个数'''\n    assert(n >= 0), 'n must be >= 0'\n    return n if n in (0, 1) else fibonacci(n-1) + fibonacci(n-2)\n\nif __name__ == '__main__':\n    from timeit import Timer\n    measure = [{'exec': 'fibonacci(100)', 'import': 'fibonacci',\n                'func': fibonacci}, {'exec': 'nsum(200)', 'import': 'nsum',\n                                     'func': nsum}]\n    for m in measure:\n        t = Timer('{}'.format(m['exec']), 'from __main__ import \\\n            {}'.format(m['import']))\n        print('name: {}, doc: {}, executing: {}, time: \\\n            {}'.format(m['func'].__name__, m['func'].__doc__,\n                       m['exec'], t.timeit()))\n"
  },
  {
    "path": "chapter6/facade.py",
    "content": "# coding: utf-8\n\nfrom enum import Enum\nfrom abc import ABCMeta, abstractmethod\n\nState = Enum('State', 'new running sleeping restart zombie')\n\n\nclass User:\n    pass\n\n\nclass Process:\n    pass\n\n\nclass File:\n    pass\n\n\nclass Server(metaclass=ABCMeta):\n\n    @abstractmethod\n    def __init__(self):\n        pass\n\n    def __str__(self):\n        return self.name\n\n    @abstractmethod\n    def boot(self):\n        pass\n\n    @abstractmethod\n    def kill(self, restart=True):\n        pass\n\n\nclass FileServer(Server):\n\n    def __init__(self):\n        '''初始化文件服务进程要求的操作'''\n        self.name = 'FileServer'\n        self.state = State.new\n\n    def boot(self):\n        print('booting the {}'.format(self))\n        '''启动文件服务进程要求的操作'''\n        self.state = State.running\n\n    def kill(self, restart=True):\n        print('Killing {}'.format(self))\n        '''杀死文件服务进程要求的操作'''\n        self.state = State.restart if restart else State.zombie\n\n    def create_file(self, user, name, permissions):\n        '''检查访问权限的有效性、用户权限，等等'''\n\n        print(\"trying to create the file '{}' for user '{}' with permissions {}\".format(name, user, permissions))\n\n\nclass ProcessServer(Server):\n\n    def __init__(self):\n        '''初始化进程服务进程要求的操作'''\n        self.name = 'ProcessServer'\n        self.state = State.new\n\n    def boot(self):\n        print('booting the {}'.format(self))\n        '''启动进程服务进程要求的操作'''\n        self.state = State.running\n\n    def kill(self, restart=True):\n        print('Killing {}'.format(self))\n        '''杀死进程服务进程要求的操作'''\n        self.state = State.restart if restart else State.zombie\n\n    def create_process(self, user, name):\n        '''检查用户权限、生成PID，等等'''\n\n        print(\"trying to create the process '{}' for user '{}'\".format(name, user))\n\n\nclass WindowServer:\n    pass\n\n\nclass NetworkServer:\n    pass\n\n\nclass OperatingSystem:\n\n    '''外观'''\n\n    def __init__(self):\n        self.fs = FileServer()\n        self.ps = ProcessServer()\n\n    def start(self):\n        [i.boot() for i in (self.fs, self.ps)]\n\n    def create_file(self, user, name, permissions):\n        return self.fs.create_file(user, name, permissions)\n\n    def create_process(self, user, name):\n        return self.ps.create_process(user, name)\n\n\ndef main():\n    os = OperatingSystem()\n    os.start()\n    os.create_file('foo', 'hello', '-rw-r-r')\n    os.create_process('bar', 'ls /tmp')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter7/flyweight.py",
    "content": "# coding: utf-8\n\nimport random\nfrom enum import Enum\n\nTreeType = Enum('TreeType', 'apple_tree cherry_tree peach_tree')\n\n\nclass Tree:\n    pool = dict()\n\n    def __new__(cls, tree_type):\n        obj = cls.pool.get(tree_type, None)\n        if not obj:\n            obj = object.__new__(cls)\n            cls.pool[tree_type] = obj\n            obj.tree_type = tree_type\n        return obj\n\n    def render(self, age, x, y):\n        print('render a tree of type {} and age {} at ({}, {})'.format(self.tree_type, age, x, y))\n\n\ndef main():\n    rnd = random.Random()\n    age_min, age_max = 1, 30    # 单位为年\n    min_point, max_point = 0, 100\n    tree_counter = 0\n\n    for _ in range(10):\n        t1 = Tree(TreeType.apple_tree)\n        t1.render(rnd.randint(age_min, age_max),\n                  rnd.randint(min_point, max_point),\n                  rnd.randint(min_point, max_point))\n        tree_counter += 1\n\n    for _ in range(3):\n        t2 = Tree(TreeType.cherry_tree)\n        t2.render(rnd.randint(age_min, age_max),\n                  rnd.randint(min_point, max_point),\n                  rnd.randint(min_point, max_point))\n        tree_counter += 1\n\n    for _ in range(5):\n        t3 = Tree(TreeType.peach_tree)\n        t3.render(rnd.randint(age_min, age_max),\n                  rnd.randint(min_point, max_point),\n                  rnd.randint(min_point, max_point))\n        tree_counter += 1\n\n    print('trees rendered: {}'.format(tree_counter))\n    print('trees actually created: {}'.format(len(Tree.pool)))\n\n    t4 = Tree(TreeType.cherry_tree)\n    t5 = Tree(TreeType.cherry_tree)\n    t6 = Tree(TreeType.apple_tree)\n    print('{} == {}? {}'.format(id(t4), id(t5), id(t4) == id(t5)))\n    print('{} == {}? {}'.format(id(t5), id(t6), id(t5) == id(t6)))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter8/mvc.py",
    "content": "quotes = ('A man is not complete until he is married. Then he is finished.',\n          'As I said before, I never repeat myself.',\n          'Behind a successful man is an exhausted woman.',\n          'Black holes really suck...', 'Facts are stubborn things.')\n\n\nclass QuoteModel:\n\n    def get_quote(self, n):\n        try:\n            value = quotes[n]\n        except IndexError as err:\n            value = 'Not found!'\n        return value\n\n\nclass QuoteTerminalView:\n\n    def show(self, quote):\n        print('And the quote is: \"{}\"'.format(quote))\n\n    def error(self, msg):\n        print('Error: {}'.format(msg))\n\n    def select_quote(self):\n        return input('Which quote number would you like to see?')\n\n\nclass QuoteTerminalController:\n\n    def __init__(self):\n        self.model = QuoteModel()\n        self.view = QuoteTerminalView()\n\n    def run(self):\n        valid_input = False\n        while not valid_input:\n            n = self.view.select_quote()\n            try:\n                n = int(n)\n            except ValueError as err:\n                self.view.error(\"Incorrect index '{}'\".format(n))\n            else:\n                valid_input = True\n        quote = self.model.get_quote(n)\n        self.view.show(quote)\n\n\ndef main():\n    controller = QuoteTerminalController()\n    while True:\n        controller.run()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter9/lazy.py",
    "content": "# coding: utf-8\n\n\nclass LazyProperty:\n\n    def __init__(self, method):\n        self.method = method\n        self.method_name = method.__name__\n        # print('function overriden: {}'.format(self.method))\n        # print(\"function's name: {}\".format(self.method_name))\n\n    def __get__(self, obj, cls):\n        if not obj:\n            return None\n        value = self.method(obj)\n        # print('value {}'.format(value))\n        setattr(obj, self.method_name, value)\n        return value\n\n\nclass Test:\n\n    def __init__(self):\n        self.x = 'foo'\n        self.y = 'bar'\n        self._resource = None\n\n    @LazyProperty\n    def resource(self):\n        print('initializing self._resource which is: {}'.format(self._resource))\n        self._resource = tuple(range(5))    # 代价大的\n        return self._resource\n\n\ndef main():\n    t = Test()\n    print(t.x)\n    print(t.y)\n    # 做更多的事情。。。\n    print(t.resource)\n    print(t.resource)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "chapter9/proxy.py",
    "content": "# coding: utf-8\n\n\nclass SensitiveInfo:\n\n    def __init__(self):\n        self.users = ['nick', 'tom', 'ben', 'mike']\n\n    def read(self):\n        print('There are {} users: {}'.format(len(self.users), ' '.join(self.users)))\n\n    def add(self, user):\n        self.users.append(user)\n        print('Added user {}'.format(user))\n\n\nclass Info:\n\n    '''SensitiveInfo的保护代理'''\n\n    def __init__(self):\n        self.protected = SensitiveInfo()\n        self.secret = '0xdeadbeef'\n\n    def read(self):\n        self.protected.read()\n\n    def add(self, user):\n        sec = input('what is the secret? ')\n        self.protected.add(user) if sec == self.secret else print(\"That's wrong!\")\n\n\ndef main():\n    info = Info()\n    while True:\n        print('1. read list |==| 2. add user |==| 3. quit')\n        key = input('choose option: ')\n        if key == '1':\n            info.read()\n        elif key == '2':\n            name = input('choose username: ')\n            info.add(name)\n        elif key == '3':\n            exit()\n        else:\n            print('unknown option: {}'.format(key))\n\nif __name__ == '__main__':\n    main()\n"
  }
]