diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/consdiag/consdiag.py |
Initial commit
Diffstat (limited to 'support/consdiag/consdiag.py')
-rw-r--r-- | support/consdiag/consdiag.py | 1099 |
1 files changed, 1099 insertions, 0 deletions
diff --git a/support/consdiag/consdiag.py b/support/consdiag/consdiag.py new file mode 100644 index 0000000000..b328f5ee9f --- /dev/null +++ b/support/consdiag/consdiag.py @@ -0,0 +1,1099 @@ +import string + +""" +1998 Manuel Gutierrez Algaba +You are free to use , modify, distribute and copy this piece of +python code, if you keep this free copyright notice in it. + +consdiag.py Version 1.1 + +constructor of diagrams: + +Given a frame of classes and relationships among clases, it +generates latex code ,that represents those classes in the +Rumbaugh OO notation. +""" + +""" +The first idea is this : +If we have a box representing the class we stablish *contact_points* +in its borders, so we can connect them , the positions inside +a box are absolute to a relative point, the self.x , self.y in the +a_simple_class. + +- a_simple_class : just draw a box , with the name of the class , +attributes, functions, an the multiplicity of that class. + +- union_derivation : draws two simple classes , one of them the +mather class, and the other, the derived class. It also +supports several levels of derivation. + +- union_association : draw two simple classes, one of them has +0:n instances of the other or viceversa. + +- union_aggregation: as derivation but with aggregates + +Although it'd be really wise to do a class with the common +attributes of these three classes and inheritate from it, I've not +done it. So many functions seem to be redundant and what's worse, +some comments to common functions are done in just one class. +Sorry for that... Read the simpler classes first. + +The position of the boxes are determined by the position of a base +a_simple_class, whose contact_points will be supplied to the boxes +conected (by unions) to it , so that the other boxes can obtain +an absolute positioning. + +This model of contact points is not valid when you want to inheritate +from several classes at the same time. :( + +So this piece of code is +finished 3-1-99. Except for bugs. + +It's a nice piece of code for creating very simple drawings. + +""" + +""" +Here are some nice nice constant to scale the drawings. +Possibly, it'd be wiser to do some more. + +""" +sscale="0.2" +typeofletter = "\\small" + +""" + In this part we declare a higher level of interfaces +for functions that generate Latex code . +It'll be interesting that more of this kind of functions +would be created. So that we isolate low level details... + +""" + +def generate_move(f,x,y ): + f.write(" \\move("+`x` +" "+ `y`+" )") + +def rgenerate_move(f,x,y ): + f.write(" \\rmove("+`x` +" "+ `y`+" )") + +""" +a_placed_text and a_placed_line are objects for drawing +small elements in the class, elements that don't play a main +role in the structure of positioning of the draw. + +""" + +class a_placed_text: + def __init__(self,x,y,text): + self.x=x + self.y=y + self.text=text + + def generate_move(self,f): + rgenerate_move(f,self.x, self.y) + f.write("\\rlvec (0 0) ") + f.write("\\htext { "+self.text+" }\n ") + rgenerate_move(f,-self.x, -self.y) + + +class a_placed_line: + def __init__(self,x,y,x1,y1): + self.x=x + self.y=y + self.x1=x1 + self.y1= y1 + + def generate_move(self,f): + rgenerate_move(f,self.x, self.y) + f.write("\\rlvec ("+`self.x1`+" "+`self.y1`+") ") + f.write("\\rlvec ("+`-self.x1`+" "+`-self.y1`+") ") + rgenerate_move(f,-self.x, -self.y) + + +''' +scale: it is just a factor for adjusting the length of the lines. +This class is a simple abstraction for storing the scale. + +''' +class scale: + def __init__(self,l): + self.l = l + + def what_scale(self): + return self.l + +""" +line, horizontal_line, vertical_line,... are simple objects intentended +to keep information of a line to draw. Remember that we don't draw +until we have settled the absolute positions, that is, when we've +drawn another parts of the drawing, ... +All this objects are intentended to generate relative positioning +""" + +class line: + def __init__(self,length,dx,dy): + self.l = length + self.dx = dx + self.dy = dy + def what_length(self): + return self.l + def what_x(self): + return self.dx + def what_y(self): + return self.dy + +class horizontal_line(line): + def __init__(self,dx): + line.__init__(self,dx,dx,0) + +class vertical_line(line): + def __init__(self,dy): + line.__init__(self,dy,0,dy) + +class diagonal_line(line): + def __init__(self,dx,dy): + line.__init__(self,dy+dx,dx,dy) + +""" +contact_point: It's another rather simple storage of information, +it could named 'label', it helps to know where we can join one +class with any other. + +""" + +class contact_point: + def __init__(self,name): + self.name = name + + def what_name(self): + return self.name + def what_x(self): + return self.x + def what_y(self): + return self.y + def do_x(self,x): + self.x = x + def do_y(self,y): + self.y = y + +""" +a_simple_class: +This must generate code for a class, if we say : + clase frutas, attributes: perecedera , dulce, seca, carnosa, +del tiempo, tropical, + +it must generate code that shows: + + +__________ +| fruits | +|--------| +|cheap | +|sweet | +|dry | +|.... | +|________| + +or even : + +__________ +| fruits | +|--------| +|cheap | +|sweet | +|dry | +| | +| | +---------- +|eat | +|buy | +|take | +| / | +|_____/_3| + +Where the first section has got the name of the class, +the second one , the types of operations of the class 'fruits', +and the number 3, means that this draw of the class fruit is +the third one that can be seen in the documentation. + +This class is the base for building more complex drawings as +derivations an associations. + +""" + +class a_simple_class(scale): + def __init__(self): + scale.__init__(self,2) + # it holds all the lines and contact points that make the + # drawing + self.list_of_lines = [] + # in the example of the fruit, they'd be : sweet, dry, cheap + self.list_of_atributes = [] + # in the example of the fruit, they'd be : eat, buy, take + self.list_of_functions = [] + self.x = 0 + self.y = 0 + # x and y are attributes for calculating where we are , + # when we draw 'virtually' the lines, so we can calculate + # every contact point. + # self.origin_x an self_origin_y are useful when actually + # drawing the class, they're the absolute positioning + # that are set by the topology all the whole drawing. + self.origin_x = 0 + self.origin_y = 0 + self.the_contact_points = {} + # this in the drawing of the fruit would be 3 + self._index_of_class = 0 + + def do_origin_x(self, x): + self.origin_x = x + + def do_origin_y(self, y): + self.origin_y = y + + ''' propagate_origin are functions useful when we have several + levels of nesting, for example in an union-derivation, in + that case and when we start to say to lower drawings which + are their absolute positions. Then they propagate those + absolute positions, in a simple class they have no much + sense. But they are needed !! + ''' + def propagate_origin_x(self,x): + self.do_origin_x(x) + + def propagate_origin_y(self,y): + self.do_origin_y(y) + + def do_name_clase(self,name_clase): + ''' in the example of the fruit, this would set self.name_clase + to fruit ''' + self.name_clase = string.replace(name_clase,"_","\_") + self.calculate_width() + + def do_attributes(self, list_of_atributes): + for i in list_of_atributes: + self.list_of_atributes.append(string.replace(i,"_","\_")) + self.calculate_width() + + def calculate_width(self): + " \ + calculate_width has the responsability of set the width \ + of the class, so it must guess which of the words is the \ + longest one \ + " + j = len(self.name_clase) + for i in self.list_of_atributes+self.list_of_functions : + if len(i) > j: + j = len(i) + if j>30: + self.width_of_the_box = j /2.5 + else: + self.width_of_the_box = j /2.2 + + def do_functions(self, list_of_functions): + for i in list_of_functions: + self.list_of_functions.append(string.replace(i,"_","\_")) + self.calculate_width() + + def index_of_class(self, n): + self._index_of_class = n + + ''' virtually_drawing, only calculates where we are moving to so we can decide on which position we set the contact points ''' + def virtually_drawing(self,l): + for i in l: + if isinstance(i,vertical_line): + self.y = self.y + i.what_y() + elif isinstance(i, horizontal_line): + self.x = self.x + i.what_x() + elif isinstance(i, contact_point): + i.do_x(self.x) + i.do_y(self.y) + self.the_contact_points[i.what_name()] = i + self.list_of_lines.append(i) + + def do_lines(self): + " this draw the lines of the drawing, but ... virtually!" + self.do_upwards_line() + self.do_lines_of_the_right() + self.do_downwards_line() + self.do_lines_of_the_left() + + def do_upwards_line(self): + j = self.width_of_the_box + parte_uno = j * self.what_scale() / 2 + self.virtually_drawing([horizontal_line(parte_uno), + contact_point('superior'), + horizontal_line(parte_uno)]) + + + def do_lines_of_the_left(self): + " really it draws one single line!" + j = len(self.list_of_atributes+self.list_of_functions) + 4 + if len(self.list_of_atributes) <2 : + j = j + 3 + adding = [] + + self.virtually_drawing([vertical_line(j), + contact_point('leftsided'), + vertical_line(j)] + adding) + + + def do_lines_of_the_right(self): + " really it draws one single line!" + j = len(self.list_of_atributes+self.list_of_functions) + 4 + if len(self.list_of_atributes) <2 : + j = j + 3 + # at the end of this line is the place where we can + # insert the index of the class + adding = [] + if self._index_of_class != 0: + adding = [a_placed_line(-3.5,0,3.5,3.5), + a_placed_text(-2.5,1, `self._index_of_class`)] + self.virtually_drawing([vertical_line(-j), + contact_point('rightsided'), + vertical_line(-j)]+ adding) + + + def do_downwards_line(self): + j = self.width_of_the_box + parte_uno = j * self.what_scale() / 2 + self.virtually_drawing([horizontal_line(-parte_uno), + contact_point('inferior'), + horizontal_line(-parte_uno)]) + + def give_me_contact_point(self,i): + return self.the_contact_points[i] + + def imprime_list_of_lines(self): + " This function is really useful for debugging purposes !!" + self.x = 0 + self.y = 0 + print self.list_of_lines + for i in self.list_of_lines: + if isinstance(i,vertical_line): + self.y = self.y + i.what_y() + print "vertical_line", self.y + elif isinstance(i, horizontal_line): + self.x = self.x + i.what_x() + print "horizontal_line", self.x + else: # it's a contact point + print "contact point ", i.what_name(), i.what_x(), i.what_y() + + def generate_headings(self,f): + " this function is only needed when the simple class is the \ + only one drawing, so it must generate the latex command of \ + the preface of the drawing! " + global sscale, typeofletter + fi = open(f,'w') + fi.write( "\\begin{center}\n"+ "\\begin{texdraw}\n"+ typeofletter+" \\drawdim {cm}\n \setunitscale "+sscale + " \\linewd 0.02\n" ) + return fi + + def generate_latex_code(self,f): + " This function is only needed when the simple class is the \ + only one drawing, then it generates latex heading , footnote,\ + and the class itself" + fi =self.generate_headings(f) + self.core_generate_latex_code(fi) + self.generate_footnote(fi) + + def core_generate_latex_code(self,fi): + " Draw the lines, and all the words of the drawing \ + of the simple class " + self.genera_labels(fi) + for i in self.list_of_lines: + if isinstance(i,vertical_line): + fi.write("\\rlvec(0 "+`i.what_y()`+" )\n") + elif isinstance(i, horizontal_line): + fi.write( "\\rlvec( "+`i.what_x()`+" 0)\n") + elif isinstance(i, a_placed_text): + i.generate_move(fi) + elif isinstance(i, a_placed_line): + i.generate_move(fi) + + + def generate_footnote(self,fi): + fi.write( "\\end{texdraw}\n"+ "\\end{center}\n") + fi.close() + + def adjusted_text(self,f, x, y ,e): + " It's a higher level way of placing an object in x,y" + f.write("\\htext("+`x`+" "+`y`+" ) { "+e+" }\n ") + + def genera_labels(self,f): + " this function really draws the simple class" + self.generate_label_name_of_class(f) + self.generate_atributes(f) + self.generate_functions(f) + self.draw_line_of_the_box_of_the_name_of_the_class(f) + self.draw_line_of_the_box_of_the_functions_of_the_class(f) + + def generate_label_name_of_class(self, f): + generate_move(f,self.origin_x, self.origin_y ) + f.write("\\rlvec(0 0) \\textref h:L v:C ") + self.adjusted_text(f, 0.5 + self.origin_x, -1 + self.origin_y, self.name_clase) + + def generate_atributes(self,f): + generate_move(f,self.origin_x, self.origin_y ) + f.write("\\rlvec(0 0) \\textref h:L v:C ") + counter = -2.8 + for i in self.list_of_atributes: + counter = counter - 1.7 + self.adjusted_text(f,0.5 + self.origin_x, counter + -1 + self.origin_y, i) + + def generate_functions(self,f): + " generate the functions of the class, in the example of fruits \ + they'd be eat,take, buy " + generate_move(f,self.origin_x, self.origin_y ) + f.write("\\rlvec(0 0) \\textref h:L v:C ") + counter = -self.poor_adjustment() + for i in self.list_of_functions: + counter = counter - 1.6 + self.adjusted_text(f,0.5 + self.origin_x, counter + -1 + self.origin_y, i) + + def draw_line_of_the_box_of_the_name_of_the_class(self,f): + " this line is the one below the name of the class" + j = self.width_of_the_box + j = j * self.what_scale() + generate_move(f, self.origin_x, self.origin_y - 2.4) + f.write("\\rlvec("+`j` +" 0 )") + generate_move(f, self.origin_x, self.origin_y ) + + def draw_line_of_the_box_of_the_functions_of_the_class(self,f): + " this line is the one above the functions of the class" + if self.list_of_functions == []: + return + j = self.width_of_the_box + j = j * self.what_scale() + yoffset = self.poor_adjustment() + generate_move(f, self.origin_x, self.origin_y - yoffset) + print self.name_clase,yoffset + f.write("\\rlvec("+`j` +" 0 )") + generate_move(f, self.origin_x, self.origin_y ) + + def poor_adjustment(self): + yoffset = len(self.list_of_atributes)* 2.9 + if yoffset < 10 : + yoffset = 10 + return yoffset + +''' +union_derivation is intended to do things like : + + ------ + | | + | a | + |----| + | + | + d + ---------- + | | + | | + --- --- + |b| |c| + --- --- + +where : a,b,c are simple classes or another union_derivationes. + +d is a triangle :) +''' + + +''' +See the comments of simple_class first , because I won t repeat +them here again . + +''' +''' +Terminology, the mother class is sometimes called part_a, +the first daughter class is sometimes called part_b, and +the rest of daughter classes are called parts_c +''' + +class union_derivation(scale): + def __init__(self): + scale.__init__(self,2) + self.x = 0 + self.y = 0 + self.the_contact_points={} + self.parts_c = [] + self.groups_of_lines=[] + + def give_me_contact_point(self,i): + return self.the_contact_points[i] + + def do_origin_x(self, x): + self.origin_x = x + + def do_origin_y(self, y): + self.origin_y = y + + ''' + Here the propagations are more serious than in a simple_class \ + the require absolute positioning of the class involved in the\ + drawing ''' + def propagate_origin_x(self,x): + print "propagating x at",x + self.part_a.do_origin_x(x) + cp = self.part_a.give_me_contact_point('inferior') + self.do_origin_x ( cp.what_x() + self.part_a.origin_x ) + + def propagate_origin_y(self,y): + self.part_a.do_origin_y(y) + cp = self.part_a.give_me_contact_point('inferior') + self.do_origin_y ( cp.what_y() + self.part_a.origin_y ) + + def virtually_drawing(self,l, list_of_lines): + for i in l: + if isinstance(i,vertical_line): + self.y = self.y + i.what_y() + elif isinstance(i, horizontal_line): + self.x = self.x + i.what_x() + elif isinstance(i, diagonal_line): + self.y = self.y + i.what_y() + self.x = self.x + i.what_x() + elif isinstance(i, a_placed_text): + pass + elif isinstance(i, a_placed_line): + pass + elif isinstance(i, contact_point) : + i.do_x(self.x) + i.do_y(self.y) + self.the_contact_points[i.what_name()] = i + list_of_lines.append(i) + + def add_a_new_derivation(self,c): + " This function adds a derivation to a compound class-derived\ + class" + self.parts_c.append(c) + cp = self.give_me_contact_point(`2*len(self.parts_c) - 1`+' next_derivation') + print "Adding new derivation at ", cp.what_x(), cp.what_y() + j = self.what_scale() / 2 + k = [] + # all this draws the arm the joins a daughter with the + # rest of the family + # besides, notice, that odd (1,3,5) contact points are + # places for new daughters of the family, and even (0,2,4) + # are places where the 'current' daughter is actually + # placed + self.virtual_move(self.give_me_contact_point(`2*len(self.parts_c) -1`+' next_derivation')) + self.virtually_drawing([horizontal_line( j * self.last_width), + contact_point(`2*len(self.parts_c) +1`+' next_derivation'), + vertical_line( -j * 2), + contact_point(`2*len(self.parts_c)`+' next_derivation')], k) + self.groups_of_lines.append(list(k)) + self.last_width = c.width_of_the_box * 2 + 2 + + def virtual_move(self,c): + self.x = c.what_x() + self.y = c.what_y() + + def add_union(self, a, b): + " a is the union_derivation or the class mother and\ + b is the derived class " + if isinstance(a, union_derivation): + self.add_a_new_derivation(b) + else: + self.part_a = a + self.part_b = b + self.last_width = self.part_b.width_of_the_box *1.5 + 2 + self.width_of_the_box = self.last_width + self.create_the_derivation(a,b) + + def create_the_derivation(self,a,b): + cp = a.give_me_contact_point('inferior') + self.do_origin_x ( cp.what_x() ) + self.do_origin_y ( cp.what_y() ) + print "line 269, consdiag",self.x, self.y + j = self.what_scale() / 2 + k = [] + # here it's drawn the arm that joins the mother class + # and the first daughter. Besides we stablish some contact + # points, 0 next_derivation, is the place of the first daughter + # 1 next_derivation the place where the next daughter could + # join the family + self.virtually_drawing([vertical_line(- j * 7), + diagonal_line(j,-j), + contact_point('1 next_derivation'), + horizontal_line(-2*j), + diagonal_line(j,j), + diagonal_line(-j,-j), + horizontal_line(-12*j), + vertical_line( -j * 2), + contact_point('0 next_derivation')],k) + self.groups_of_lines.append(list(k)) + + + def generate_headings(self,f): + global sscale + fi = open(f,'w') + fi.write( "\\begin{center}\n"+ "\\begin{texdraw}\n"+ typeofletter+ " \\drawdim {cm}\n \setunitscale "+sscale+ " \\linewd 0.02\n" ) + return fi + + + def generate_latex_lines(self, lines,fi): + for i in lines: + if isinstance(i,vertical_line): + fi.write("\\rlvec(0 "+`i.what_y()`+" )\n") + elif isinstance(i, horizontal_line): + fi.write("\\rlvec( "+`i.what_x()`+" 0)\n") + elif isinstance(i,diagonal_line): + fi.write("\\rlvec( "+`i.what_x()`+" "+ `i.what_y()`+")\n") + elif isinstance(i, a_placed_text): + i.generate_move(fi) + + + + def generate_latex_code(self,fo): + fi = self.generate_headings(fo) + + self.core_generate_latex_code(fi) + + self.generate_latex_foot(fi) + + def core_generate_latex_code(self,fi): + self.part_a.core_generate_latex_code(fi) + generate_move(fi, self.origin_x, self.origin_y) + self.generate_latex_lines(self.groups_of_lines[0],fi) + + cp = self.give_me_contact_point('0 next_derivation') + # once we've drawn part_a , then we can know where part_b + # should lie... + self.part_b.propagate_origin_x ( cp.what_x() + self.origin_x - 3) + self.part_b.propagate_origin_y ( cp.what_y() + self.origin_y ) + self.part_b.core_generate_latex_code(fi) + self.generate_rest_derivations(fi) + + def generate_latex_foot(self,fi): + fi.write( "\\end{texdraw}\n"+ "\\end{center}\n") + fi.close() + + def generate_rest_derivations(self,f): + j = 1 + for i in self.parts_c: + # the even next derivations (1,3,5,...) mark the + # place where new daughters will be placed + cp = self.give_me_contact_point(`2*j -1 `+' next_derivation') + generate_move(f,cp.what_x() + self.origin_x, cp.what_y() + self.origin_y ) + self.generate_latex_lines(self.groups_of_lines[j],f) + cp = self.give_me_contact_point(`2*j `+' next_derivation') + i.propagate_origin_x ( cp.what_x() + self.origin_x - 3) + i.propagate_origin_y ( cp.what_y() + self.origin_y ) + i.core_generate_latex_code(f) + j = j + 1 + + +''' +this is the class that intends to do : + +--------| |----- +| |1:1 1:2| | +| a |---------- b | +| | | | +|-------| |_____| + +where a and b are simple classes !! + +I have done not much else in this class, and you should understand +this one if you have understood the previous ones. + +''' + +class union_association(scale): + def __init__(self): + scale.__init__(self,2) + self.x = 0 + self.y = 0 + self.the_contact_points={} + self.united = [] + self.parts_c = [] + self.groups_of_lines=[] + + def give_me_contact_point(self,i): + return self.the_contact_points[i] + + def do_origin_x(self, x): + self.origin_x = x + + def do_origin_y(self, y): + self.origin_y = y + + def propagate_origin_x(self,x): + print "propagating x at",x + self.part_a.do_origin_x(x) + cp = self.part_a.give_me_contact_point('inferior') + self.do_origin_x ( cp.what_x() + self.part_a.origin_x ) + + def propagate_origin_y(self,y): + self.part_a.do_origin_y(y) + cp = self.part_a.give_me_contact_point('inferior') + self.do_origin_y ( cp.what_y() + self.part_a.origin_y ) + + def virtually_drawing(self,l, list_of_lines): + for i in l: + if isinstance(i,vertical_line): + self.y = self.y + i.what_y() + elif isinstance(i, horizontal_line): + self.x = self.x + i.what_x() + elif isinstance(i, diagonal_line): + self.y = self.y + i.what_y() + self.x = self.x + i.what_x() + elif isinstance(i, a_placed_text ): + # this sort doesn't affects internal positioning + pass + elif isinstance(i, contact_point): + # it's a contact point + i.do_x(self.x) + i.do_y(self.y) + self.the_contact_points[i.what_name()] = i + # otherwise it doesn't affect to the positioning + list_of_lines.append(i) + + def add_a_new_association(self,c): + pass + + def virtual_move(self,c): + self.x = c.what_x() + self.y = c.what_y() + + def add_union(self, a, b, texta= None, textb = None): + " a is the union_derivation or the class mother and\ + b is the derived class " + if isinstance(a, union_association): + self.add_a_new_association(b) + else: + self.part_a = a + self.part_b = b + self.create_the_association(a,b,texta, textb) + + def create_the_association(self,a,b,texta,textb): + j = self.what_scale() / 2 + cp = a.give_me_contact_point('rightsided') + self.do_origin_x ( cp.what_x() ) + self.do_origin_y ( cp.what_y() ) + print "line 269, consdiag",self.x, self.y + k = [] + f = (len(texta) + len(textb)) * 1.6 + self.virtually_drawing([ a_placed_text(0.1*j,j,texta), + horizontal_line(f*j), + a_placed_text(-j*1.3*len(textb),j,textb), + contact_point("rightsided") + ], k) + self.groups_of_lines.append(list(k)) + + + def generate_headings(self,f): + global sscale + fi = open(f,'w') + fi.write( "\\begin{center}\n"+ "\\begin{texdraw}\n"+ typeofletter+ " \\drawdim {cm}\n \setunitscale "+sscale+ " \\linewd 0.02\n" ) + return fi + + + def generate_latex_lines(self, lines,fi): + for i in lines: + if isinstance(i,vertical_line): + fi.write("\\rlvec(0 "+`i.what_y()`+" )\n") + elif isinstance(i, horizontal_line): + fi.write("\\rlvec( "+`i.what_x()`+" 0)\n") + elif isinstance(i,diagonal_line): + fi.write("\\rlvec( "+`i.what_x()`+" "+ `i.what_y()`+")\n") + elif isinstance(i, a_placed_text): + i.generate_move(fi) + + def generate_latex_code(self,fo): + fi = self.generate_headings(fo) + + self.core_generate_latex_code(fi) + + self.generate_latex_foot(fi) + + def core_generate_latex_code(self,fi): + self.part_a.core_generate_latex_code(fi) + generate_move(fi, self.origin_x, self.origin_y) + self.generate_latex_lines(self.groups_of_lines[0],fi) + + cp = self.give_me_contact_point('rightsided') + self.part_b.propagate_origin_x ( cp.what_x() + self.origin_x ) + self.part_b.propagate_origin_y ( cp.what_y() + self.origin_y + 4) + self.part_b.core_generate_latex_code(fi) + self.generate_rest_derivations(fi) + + def generate_latex_foot(self,fi): + fi.write( "\\end{texdraw}\n"+ "\\end{center}\n") + fi.close() + + def generate_rest_derivations(self,f): + pass + + +class union_aggregation(union_derivation): + def __init__(self): + union_derivation.__init__(self) + + def create_the_derivation(self,a,b): + " This creates another kind of derivation" + cp = a.give_me_contact_point('inferior') + self.do_origin_x ( cp.what_x() ) + self.do_origin_y ( cp.what_y() ) + print "line 269, consdiag",self.x, self.y + j = self.what_scale() / 2 + k = [] + # here it's drawn the arm that joins the mother class + # and the first daughter. Besides we stablish some contact + # points, 0 next_derivation, is the place of the first daughter + # 1 next_derivation the place where the next daughter could + # join the family + self.virtually_drawing([ + diagonal_line(j,-j), # we draw \ + diagonal_line(-j,-j), # / + diagonal_line(j,j), # now we return back + diagonal_line(-j,j), + diagonal_line(-j,-j), # we draw the another / + diagonal_line(j,-j), # \ + vertical_line(- j * 8), + contact_point('1 next_derivation'), + horizontal_line(-12*j), # a bit of adjustment here + vertical_line( -j * 2), + contact_point('0 next_derivation') + ],k) + self.groups_of_lines.append(list(k)) + + + +def test(): + " this test creates several levels of inheritances" + c = a_simple_class() + c.do_name_clase('fruta') + c.do_attributes(['perecedera' , 'dulce', 'seca', 'carnosa', + 'del tiempo', 'tropical']) + c.do_lines() + #c.imprime_list_of_lines() + c.generate_latex_code('result') + + d = a_simple_class() + d.do_name_clase('empleado') + d.do_attributes(['paga por horas' , 'sueldo']) + d.do_lines() + #d.imprime_list_of_lines() + d.generate_latex_code('result2') + e = union_derivation() + e.add_union(c,d) + f = a_simple_class() +# f.do_name_clase('employee') +# f.do_attributes(['weekly wage' , 'social insecurity']) +# f.do_lines() +# e.add_union(e,f) + g= a_simple_class() + g.do_name_clase('python') + g.do_attributes(['easily workable', 'non strict typing']) + g.do_lines() + e.add_union(e,g) + h = a_simple_class() + h.do_name_clase('fruta') + h.do_attributes(['perecedera' , 'dulce', 'seca', 'carnosa', + 'del tiempo', 'tropical']) + h.do_lines() + j = a_simple_class() + j.do_name_clase('empleado') + j.do_attributes(['paga por horas' , 'sueldo']) + j.do_lines() + i = union_derivation() + i.add_union(j,h) + e.add_union(e,i) + e.generate_latex_code('result3') + + +def test1(): + " This test make an association" + c = a_simple_class() + c.do_name_clase('enterprise') + c.do_attributes(['name' , 'profits', 'established', 'fiscal paradises', + 'frauds', 'bad tricks']) + c.do_lines() + #c.imprime_list_of_lines() + c.generate_latex_code('result') + + d = a_simple_class() + d.do_name_clase('worker') + d.do_attributes(['wage' , 'timetable', 'seniority']) + d.do_lines() + #d.imprime_list_of_lines() + #d.generate_latex_code('result2') + e = union_association() + e.add_union(c,d,"0:n","0:1") + e.generate_latex_code('drawing7.tex') + +def test2(): + " This tests uses the section of functions in every class, and the marks of repeated-class" + c = a_simple_class() + c.do_name_clase('frutas') + c.do_attributes(['name' , 'dulce', 'seca', 'carnosa', + 'del tiempo', 'tropical']) + c.do_functions(['comer','tirar','vender']) + c.index_of_class(3) + c.do_lines() + #c.imprime_list_of_lines() + c.generate_latex_code('result3') + +def _generate_single_class(): + c = a_simple_class() + c.do_name_clase('enterprise') + c.do_attributes(['name' , 'benefits', 'money', 'health', + 'hobbies', 'dreams', 'under_score.']) + c.do_lines() + + c.generate_latex_code('drawing1.tex') + +def _generate_single_class_long_names(): + c = a_simple_class() + c.do_name_clase('person') + c.do_attributes(['name' , 'sex', 'money', 'health', + 'hobbies', 'dreams', 'opinion about latest polls', + 'position when playing soccer', + 'favourite scripting language']) + c.do_lines() + c.generate_latex_code('drawing2.tex') + +def _generate_single_class_function_and_mark(): + c = a_simple_class() + c.do_name_clase('person') + c.do_attributes(['name' , 'sex', 'money', 'health', + 'hobbies', 'dreams']) + c.do_functions(['dream', 'love', 'play soccer', 'diving']) + c.index_of_class(3) + + c.do_lines() + c.generate_latex_code('drawing3.tex') + +def _generate_simple_inheritance(): + c = a_simple_class() + c.do_name_clase('person') + c.do_attributes(['name' , 'sex', 'money', 'health', + 'hobbies', 'dreams']) + c.do_functions(['dream', 'love', 'play soccer', 'diving']) + + c.do_lines() + d = a_simple_class() + d.do_name_clase('work') + d.do_attributes(['salary' , 'post', + 'labor union', 'productivity', 'qualifications', + 'capabilities']) + d.do_functions(['work', 'strike', 'be ill', 'be fired']) + + d.do_lines() + e = union_derivation() + e.add_union(c,d) + e.generate_latex_code('drawing4.tex') + +def _generate_multiple_inheritance(): + c = a_simple_class() + c.do_name_clase('person') + c.do_attributes(['name' , 'sex', 'money', 'health', + 'hobbies', 'dreams']) + + c.do_lines() + d = a_simple_class() + d.do_name_clase('worker') + d.do_attributes(['salary' , 'post', + 'labor union', 'productivity', 'qualifications', + 'capabilities']) + + d.do_lines() + f = a_simple_class() + f.do_name_clase('father') + f.do_attributes(['busy' , 'tenderness', + 'stubornness', 'caress', 'kisses', 'capabilities']) + + f.do_lines() + g = a_simple_class() + g.do_name_clase('chess player') + g.do_attributes(['elo' , 'cruelty', + 'stubornness', 'bad tricks', 'intelligence', 'openings knowledge']) + + g.do_lines() + e = union_derivation() + e.add_union(c,d) + e.add_union(e,f) + e.add_union(e,g) + e.generate_latex_code('drawing5.tex') + +def _generate_multiple_inheritance_with_multiple_levels(): + d = a_simple_class() + d.do_name_clase('worker') + d.do_attributes(['salary' , 'post', + 'labor union', 'productivity', 'qualifications', + 'capabilities']) + + + d.do_lines() + f = a_simple_class() + f.do_name_clase('computer scientist') + f.do_attributes(['languages' , 'preferred OS', + 'preferred editor', 'hackerism', 'ATBB']) + + f.do_lines() + + h = union_derivation() + h.add_union(d,f) + + c = a_simple_class() + c.do_name_clase('person') + c.do_attributes(['name' , 'sex', 'money', 'health', + 'hobbies', 'dreams']) + c.do_lines() + + e = union_derivation() + e.add_union(c,h) + e.generate_latex_code('drawing6.tex') + +def _generate_associations(): + test1() + + +def _generate_multiple_aggregation(): + c = a_simple_class() + c.do_name_clase('person') + c.do_attributes(['name' , 'sex', 'money', 'health', + 'hobbies', 'dreams']) + + c.do_lines() + d = a_simple_class() + d.do_name_clase('worker') + d.do_attributes(['salary' , 'post', + 'labor union', 'productivity', 'qualifications', + 'capabilities']) + + d.do_lines() + f = a_simple_class() + f.do_name_clase('father') + f.do_attributes(['busy' , 'tenderness', + 'stubornness', 'caress', 'kisses', 'capabilities']) + + f.do_lines() + g = a_simple_class() + g.do_name_clase('chess player') + g.do_attributes(['elo' , 'cruelty', + 'stubornness', 'bad tricks', 'intelligence', 'openings knowledge']) + + g.do_lines() + e = union_aggregation() + e.add_union(c,d) + e.add_union(e,f) + e.add_union(e,g) + e.generate_latex_code('drawing8.tex') + + +if __name__=='__main__': + _generate_single_class() + _generate_single_class_long_names() + _generate_single_class_function_and_mark() + _generate_simple_inheritance() + _generate_multiple_inheritance() + _generate_multiple_inheritance_with_multiple_levels() + _generate_associations() + _generate_multiple_aggregation() + + + + + |