In [2]:
from abc import abstractmethod

Builder template¶

Here, we create interface for builders, IExporter which defines available methods.

In [6]:
class IExporter:
    @abstractmethod
    def setData(self, data):
        pass
    
    @abstractmethod
    def prepareAuthorsList(self):
        pass
    
    @abstractmethod
    def prepareAbstractsList(self):
        pass
    
    @abstractmethod
    def getDatabaseForExport(self):
        pass

ExportXML builder provides conveting of the database to XML format:

In [11]:
class ExportXML(IExporter):
    def __init__(self):
        self.__result = ''
        print('XML exporter works')
    
    def setData(self, data):
        self.__data = data
    
    def prepareAuthorsList(self):
        self.__result += '<authors>\n'
        for author in self.__data[0]:
            self.__result += '\t<author>' + author + '</author>\n'
        self.__result += '</authors>\n'
    
    def prepareAbstractsList(self):
        self.__result += '<abstracts>\n'
        for abstract in self.__data[1]:
            self.__result += '\t<abstract>' + abstract + '</abstract>\n'
        self.__result += '</abstracts>\n'
    
    def getDatabaseForExport(self):
        return '<xml>\n' + self.__result + '</xml>\n'

ExportJSON builder provides conveting of the database to JSON format:

In [8]:
class ExportJSON(IExporter):
    def __init__(self):
        self.__result = ''
        print('JSON exporter works')
    
    def setData(self, data):
        self.__data = data
    
    def prepareAuthorsList(self):
        self.__result += '{"authors": \n'
        for author in self.__data[0]:
            self.__result += '\t{"author": ' + author + '}\n'
        self.__result += '},\n'
    
    def prepareAbstractsList(self):
        self.__result += '{"abstracts":\n'
        for abstract in self.__data[1]:
            self.__result += '\t{"abstract:"' + abstract + '}\n'
        self.__result += '},\n'
    
    def getDatabaseForExport(self):
        return '{"Book of abstracts":\n' + self.__result + '}\n'

DatabaseExporter is the director, which receives the concrete builder and calls its methods into the proper order to finish the database in the desired format:

In [9]:
class DatabaseExporter:
    def __init__(self, concreteBuilder):
        self._builder = concreteBuilder
    
    def getDatabase(self, data):
        self._builder.setData(data)
        self._builder.prepareAuthorsList()
        self._builder.prepareAbstractsList()
        return self._builder.getDatabaseForExport()
In [10]:
data = [
    ['Alice', 'Bob', 'Candy', 'Denis'],
    ['Lorem ipsum 01', 'Lorem ipsum 02', 'Lorem ipsum 03', 'Lorem ipsum 04', 'Lorem ipsum 05', 'Lorem ipsum 06']
]
In [12]:
xmlConverter = ExportXML()
jsonConverter = ExportJSON()
XML exporter works
JSON exporter works
In [13]:
director = DatabaseExporter(xmlConverter)
print(director.getDatabase(data))
<xml>
<authors>
	<author>Alice</author>
	<author>Bob</author>
	<author>Candy</author>
	<author>Denis</author>
</authors>
<abstracts>
	<abstract>Lorem ipsum 01</abstract>
	<abstract>Lorem ipsum 02</abstract>
	<abstract>Lorem ipsum 03</abstract>
	<abstract>Lorem ipsum 04</abstract>
	<abstract>Lorem ipsum 05</abstract>
	<abstract>Lorem ipsum 06</abstract>
</abstracts>
</xml>

In [14]:
director = DatabaseExporter(jsonConverter)
print(director.getDatabase(data))
{"Book of abstracts":
{"authors": 
	{"author": Alice}
	{"author": Bob}
	{"author": Candy}
	{"author": Denis}
},
{"abstracts":
	{"abstract:"Lorem ipsum 01}
	{"abstract:"Lorem ipsum 02}
	{"abstract:"Lorem ipsum 03}
	{"abstract:"Lorem ipsum 04}
	{"abstract:"Lorem ipsum 05}
	{"abstract:"Lorem ipsum 06}
},
}

Composite template¶

Here, we provide the interface Numeric and classes for a composite of an arichmetic expression

In [15]:
class Numeric:
    @abstractmethod
    def evaluate(self):
        pass

Class for a number

In [16]:
class NumericOperand(Numeric):
    def __init__(self, number):
        self.__value = number
    
    def evaluate(self):
        return self.__value

Class for a composite expression

In [17]:
class CompositeOperand(Numeric):
    def __init__(self, lhs, rhs, operation):
        self.__lhs = lhs
        self.__rhs = rhs
        self.__operation = operation
    
    def evaluate(self):
        lft = self.__lhs.evaluate()
        rht = self.__rhs.evaluate()
        
        if self.__operation == '+':
            return lft + rht
        elif self.__operation == '-':
            return lft - rht
        elif self.__operation == '*':
            return lft * rht
        elif self.__operation == '/':
            return lft / rht
In [18]:
op1 = NumericOperand(42)
op2 = NumericOperand(4)
op3 = CompositeOperand(op1, op2, '/')
print(op3.evaluate())
10.5
In [21]:
# 42 * 4 + 4
op1 = NumericOperand(42)
op2 = NumericOperand(4)
op3 = CompositeOperand(
    CompositeOperand(op1, op2, '*'), op2, '+'
)
print(op3.evaluate())
172
In [22]:
42*4+4
Out[22]:
172
In [ ]: