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 |
Initial commit
Diffstat (limited to 'support/consdiag')
-rw-r--r-- | support/consdiag/README | 60 | ||||
-rw-r--r-- | support/consdiag/consdiag.ps | 1342 | ||||
-rw-r--r-- | support/consdiag/consdiag.py | 1099 | ||||
-rw-r--r-- | support/consdiag/consdiag.tex | 289 | ||||
-rw-r--r-- | support/consdiag/drawing1.tex | 22 | ||||
-rw-r--r-- | support/consdiag/drawing2.tex | 24 | ||||
-rw-r--r-- | support/consdiag/drawing3.tex | 26 | ||||
-rw-r--r-- | support/consdiag/drawing4.tex | 51 | ||||
-rw-r--r-- | support/consdiag/drawing5.tex | 77 | ||||
-rw-r--r-- | support/consdiag/drawing6.tex | 64 | ||||
-rw-r--r-- | support/consdiag/drawing7.tex | 36 | ||||
-rw-r--r-- | support/consdiag/drawing8.tex | 79 |
12 files changed, 3169 insertions, 0 deletions
diff --git a/support/consdiag/README b/support/consdiag/README new file mode 100644 index 0000000000..714c41977c --- /dev/null +++ b/support/consdiag/README @@ -0,0 +1,60 @@ +Readme of consdiag.py + +What is 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. + +Things like this: +__________ +| fruits | +|--------| +|cheap | +|sweet | +|dry | +| | +| | +---------- +|eat | +|buy | +|take | +| / | +|_____/_3| + + ------ + | | + | a | + |----| + | + | + d + ---------- + | | + | | + --- --- + |b| |c| + --- --- + +where : a,b,c are simple classes or another union_derivations. + +d is a triangle :) + +How to run it. +--------------- + +Take a look at the end of consdiag.py, there you'll see good examples. + +How to make the documentation. +------------------------------ + +Run "latex consdiag.tex" several times , because it needs to update +the crossreferences and such. + +Or use a ghostscript visor to view consdiag.ps. + diff --git a/support/consdiag/consdiag.ps b/support/consdiag/consdiag.ps new file mode 100644 index 0000000000..e5f9a3e27c --- /dev/null +++ b/support/consdiag/consdiag.ps @@ -0,0 +1,1342 @@ +%!PS-Adobe-2.0 +%%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software +%%Pages: 10 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Roman Times-Bold Courier Times-Italic +%%DocumentPaperSizes: Letter +%%EndComments +%DVIPSCommandLine: dvips -D 300 -f -e 0 +%DVIPSParameters: dpi=300, comments removed +%DVIPSSource: TeX output 1999.01.03:2314 +%%BeginProcSet: tex.pro +/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N +/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 +mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} +ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale +isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div +hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul +TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} +forall round exch round exch]setmatrix}N /@landscape{/isls true N}B +/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B +/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ +/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N +string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N +end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ +/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] +N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup +length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ +128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub +get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data +dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N +/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup +/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx +0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff +setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff +.1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} +if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup +length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ +cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin +0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul +add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict +/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook +known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X +/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for +65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 +0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V +{}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 +getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} +ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false +RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 +false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform +round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg +rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail +{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} +B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ +4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ +p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p +a}B /bos{/SS save N}B /eos{SS restore}B end +%%EndProcSet +%%BeginFont: Times-Roman +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def +%%EndFont +%%BeginProcSet: texps.pro +TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 +index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont /setfont load]cvx def}def +/ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def +/ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def +end +%%EndProcSet +%%BeginProcSet: special.pro +TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N +/vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen +false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B +/@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit +div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ +/CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ +10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B +/@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale +true def end /@MacSetUp{userdict /md known{userdict /md get type +/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup +length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} +N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath +clippath mark{transform{itransform moveto}}{transform{itransform lineto} +}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ +itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ +closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 +0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N +/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 +scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get +ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip +not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 +TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR +pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 +-1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg +TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg +sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr +0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add +2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp +{pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 +div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} +N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict +maxlength dict begin /magscale true def normalscale currentpoint TR +/psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts +/psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx +psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy +scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR +/showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict +begin /SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial +{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath +}N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ +end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} +N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ +/SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX +SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X +/startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad +yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end +%%EndProcSet +TeXDict begin 40258431 52099146 1000 300 300 () @start +/Fa 136[33 2[14 19 19 1[25 25 25 36 14 2[14 25 25 14 +22 1[22 25 25 12[28 4[36 33 31[12 4[17 17 40[{ + TeXBase1Encoding ReEncodeFont }23 50.000001 /Times-Italic +rf /Fb 134[18 3[21 12 1[16 5[12 2[12 1[21 12 18 17[21 +25 8[14 28[10 44[{ TeXBase1Encoding ReEncodeFont }13 +41.666669 /Times-Italic rf /Fc 134[19 19 27 19 19 10 +15 12 19 19 19 19 29 10 19 1[10 19 19 12 17 19 17 19 +17 12[23 21 3[27 12[25 27 6[10 6[19 1[19 19 1[9 43[21 +2[{ TeXBase1Encoding ReEncodeFont }35 37.500000 /Times-Roman +rf /Fd 134[25 25 36 1[28 17 19 22 1[28 25 28 41 14 28 +1[14 28 25 17 22 28 22 28 25 11[36 1[28 9[19 7[36 10[25 +25 25 25 25 25 2[12 12[17 33[{ TeXBase1Encoding ReEncodeFont }34 +50.000001 /Times-Bold rf /Fe 130[25 1[25 1[25 25 25 25 +25 25 25 25 25 25 25 25 25 25 25 1[25 25 25 25 25 25 +25 25 25 1[25 1[25 25 25 6[25 25 3[25 12[25 25 3[25 2[25 +3[25 1[25 25 3[25 25 1[25 2[25 25 25 39[{ + TeXBase1Encoding ReEncodeFont }46 41.666669 /Courier +rf /Ff 1 16 df<03C00FF01FF83FFC7FFE7FFEFFFFFFFFFFFFFFFF7FFE7FFE3FFC1FF8 +0FF003C010107E9115>15 D E /Fg 107[18 18 24[18 21 21 30 +21 21 12 16 14 21 21 21 21 32 12 21 12 12 21 21 14 18 +21 18 21 18 7[30 30 39 2[25 23 28 2[30 1[37 25 1[16 14 +1[30 23 25 30 1[28 30 1[18 4[12 21 21 21 21 21 21 21 +21 21 21 12 10 14 10 1[21 14 14 14 5[14 30[23 2[{ + TeXBase1Encoding ReEncodeFont }67 41.666669 /Times-Roman +rf /Fh 134[30 30 43 30 33 20 23 27 1[33 30 33 50 17 2[17 +33 30 20 27 33 27 33 30 13[33 9[23 47 4[43 40 11[30 30 +30 30 30 30 49[{ TeXBase1Encoding ReEncodeFont }33 59.999974 +/Times-Bold rf /Fi 133[22 3[25 25 14 19 17 3[25 39 14 +2[14 1[25 1[22 1[22 25 22 19[44 5[36 2[36 2[36 46 6[25 +25 6[25 2[12 1[12 44[{ TeXBase1Encoding ReEncodeFont }25 +50.000001 /Times-Roman rf /Fj 134[36 36 1[36 36 20 28 +24 1[36 36 36 56 20 2[20 1[36 24 32 36 32 1[32 28[52 +18[36 36 1[18 46[{ TeXBase1Encoding ReEncodeFont }23 +71.999998 /Times-Roman rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin +%%PaperSize: Letter + +%%EndSetup +%%Page: 1 1 +1 0 bop 290 440 a Fj(Documen)o(tation)18 b(an)o(d)g(e)o(xamp)o(les)g +(of)g(co)o(nsdiag.p)o(y)777 531 y(v)o(ersio)o(n)g(1.0)525 +652 y Fi(M)q(anuel)12 b(Gutier)o(rez)h(Al)o(gaba,)g(irm)o(ina@ctv)m +(.es)778 749 y(December)f(1998)220 917 y Fh(1)60 b(Copyr)o(ight)15 +b(issues)220 1010 y Fg(consdi)o(a)q(g.p)o(y)c(and)f(it)o(s)h(do)o(c)q +(umentati)o(on)f(\()h(t)o(hi)o(s)g(tex)o(t)f(a)q(nd)g(t)o(he)h(source)q +(s)f(of)g(tex)g(dra)o(wing)o(s)h(in)o(c)q(l)o(uded)220 +1059 y(in)d(it)o(\))h(are)g(c)q(o)o(py)o(rig)o(hted)g(b)o(y)g(Manuel)f +(Guti)o(e)q(rr)o(e)q(z)h(Al)o(gaba)g(1999)f(a)q(n)o(d)h(yo)o(u)g(are)g +(free)g(to)f(use)q(,)h(m)q(o)o(dif)o(y)220 1109 y(,)i(cop)o(y)f(a)q(nd) +g(d)o(istri)o(b)o(ut)o(e)h(it)f(u)o(nder)g(the)h(cond)o(it)o(ion)f(t)o +(ha)q(t)f(you)h(in)o(c)q(l)o(ude)h(t)o(hi)o(s)g(not)o(ice)g(ad)f(in)g +(it)o(.)220 1247 y Fh(2)60 b(Intr)o(o)o(d)q(uc)o(tion)220 +1340 y Fg(When)11 b(I)g(wrot)o(e)h(th)o(is)f(pro)o(gra)q(m)g(th)o(e)q +(re)g(wasn')o(t)g(an)o(y)g(a)q(u)o(toma)q(t)o(ed)g(uti)o(li)o(ty)g(fo)o +(r)g(drawi)o(ng)g(Ru)o(m)q(b)o(a)q(ug)o(h)220 1390 y(OO)f(box)o(es)q(.) +j(Of)d(course,)h(you)f(can)h(u)o(se)g(x\002g)f(or)g(a)q(n)o(y)g(ot)o +(her)g(drawi)o(ng)g(prog)o(ra)q(m)g(for)g(th)o(is)g(purp)o(ose)q(.)220 +1440 y(Bu)o(t)g(th)o(is)g(ut)o(il)o(ity)f(ha)q(s)h(t)o(wo)g(major)g +(adv)o(ant)o(a)q(g)o(e)q(s,)h(I)o(t')m(s)g(ea)q(si)o(e)q(r)f(t)o(o)g +(use)g(a)q(n)o(d)g(it)o(')n(s)g(faster)g(to)f(')n(dra)o(w'.)k(On)220 +1489 y(th)o(e)e(ot)o(he)q(r)f(hand)o(,)h(the)f(kin)o(ds)h(o)o(f)g(a)o +(v)o(ail)o(a)q(bl)o(e)g(dra)o(wing)o(s)g(are)g(li)o(mit)o(e)q(d)f(to)o +(:)282 1563 y Ff(\017)21 b Fg(i)o(solated)10 b(c)q(l)o(a)q(sses)282 +1642 y Ff(\017)21 b Fg(t)o(re)q(es)11 b(\()o(a)q(nd)f(j)o(ust)g(tr)o(e) +q(es,)h(no)f(graphs)g(:\()g(\))g(of)g(clas)q(ses)h(r)o(e)q(l)o(a)q(t)o +(e)q(d)f(by)g(t)o(he)q(i)o(r)g(inh)o(e)q(ri)o(tance)q(s)282 +1720 y Ff(\017)21 b Fg(si)o(m)q(pl)o(e)11 b(ass)q(o)o(c)q(i)o(a)q(t)o +(ion)o(s)g(of)f(class)q(es)282 1794 y(It')m(s)h(n)o(ot)f(muc)q(h)g(,)h +(b)n(ut...)282 1844 y(And)f(th)o(is)g(is)h(an)f(ut)o(il)o(ity)g(wri)o +(tt)o(e)q(n)g(i)o(n)g(py)o(thon)o(.)220 1917 y Fe(http:/)o(/www.python) +o(.org)282 1991 y Fg(I)15 b(imagin)o(e)h(t)o(ha)q(t)e(it)g(c)q(ou)o(ld) +h(b)o(e)h(wri)o(tt)o(e)q(n)e(in)h(T)935 2000 y(E)955 +1991 y(X)g(b)o(ut)g(It)o(')n(s)g(10)f(ti)o(m)q(es)h(e)q(asier)g(to)f +(use)i(p)o(yt)o(hon.)220 2041 y(And)d(what')m(s)h(more)g(impo)o(rtant)f +(T)720 2050 y(E)740 2041 y(X)g(prog)o(ra)q(mme)q(r)o(s)h(hav)o(e)g(a)g +(model)f(,)i(if)e(th)o(ey)g(want)g(to)g(do)g(the)220 +2091 y(tr)o(a)q(nsl)o(a)q(t)o(ion)o(.)220 2141 y(Ano)o(ther)j(po)o(int) +o(,)i(t)o(he)e(pyt)o(hon)f(c)q(o)o(de)h(c)q(ou)o(ld)g(b)o(e)h(i)o(mpro) +o(v)o(e)q(d)o(,)h(I')n(v)o(e)e(dup)o(li)o(c)q(ated)g(code)g(in)f(sev)o +(era)q(l)220 2190 y(parts,)g(bec)q(ause)g(I)f(th)o(ough)o(t)g(th)o(e)h +(clas)q(ses)g(were)f(re)q(all)o(y)g(dif)n(fe)q(r)o(e)q(nt)f(e)q(ac)q(h) +h(o)o(ther)n(,)i(.)7 b(.)f(.)h(,)15 b(in)f(t)o(he)h(end,)220 +2240 y(th)o(ey')n(v)o(e)c(r)o(e)q(sul)o(ted)f(to)g(be)h(v)o(ery)f +(simil)o(a)q(r)g(i)o(n)g(the)h(w)o(a)q(y)f(t)o(hey)g(w)o(ork.)282 +2290 y(And,)i(i)o(t)f(genera)q(t)o(es)h(t)o(ex)f(c)q(o)o(de)q(.)k(So)c +(if)g(you)f(want)h(it)f(in)h(po)o(stsc)q(r)o(ipt)o(,)h(gi)o(f)f(or)g +(whate)o(v)o(e)q(r)n(,)h(use)f(the)220 2340 y(pro)o(gram)q(s)f(dvi)o(,) +h(gs)f(or)g(grab)g(dir)o(e)q(ctl)o(y)h(f)o(rom)g(a)f(wind)o(o)o(w!)220 +2478 y Fh(3)75 b(H)o(o)o(w)16 b(t)o(o)f(us)q(e)f(it)220 +2579 y Fd(3.1)50 b(Using)12 b(it)g(in)g(a)h(p)o(yth)o(on)g(cod)o(e)220 +2657 y Fg(Just)e(use)h(a)g(\223from)g(consd)o(iag)g(i)o(m)q(p)o(ort)f +(*)g(\223)h(a)q(n)o(d)g(t)o(hi)o(s)g(pi)o(e)q(ce)g(of)f(py)o(thon)g +(code)h(\()f(for)g(example\).)17 b(I)o(n)220 2707 y(dra)o(wing)o(3.)q +(t)o(ex)10 b(is)g(k)o(e)q(pt)g(t)o(he)h(f)o(oll)o(o)o(win)o(g)f(T)817 +2716 y(E)837 2707 y(X)21 b(i)o(nstru)o(c)q(t)o(ion)o(s)11 +b(t)o(ha)q(t)f(g)o(e)q(n)o(e)q(rates)h(t)o(he)g(d)o(rawin)o(g)21 +b(2:)926 2831 y(1)p eop +%%Page: 2 2 +2 1 bop 747 294 a Fg(F)q(i)o(gur)o(e)11 b(1:)h(Singl)o(e)f(\002gu)o(re) +774 869 y @beginspecial 0 @llx -125 @lly 78 @urx 0 @ury +780 @rwi @setspecial +%%BeginDocument: consdiag.ps1 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +323 -57 lv +0 0 mv +162 0 lv +324 0 lv +324 -260 lv +324 -520 lv +162 -520 lv +0 -520 lv +0 -260 lv +0 0 lv +stroke end showpage +%%EndDocument + @endspecial 795 382 a Fc(en)o(t)q(e)o(r)q(p)o(r)q(ise)795 +488 y(na)o(me)795 532 y(be)o(ne)o(\002t)q(s)795 564 y(mon)o(e)o(y)795 +612 y(he)o(alt)q(h)795 653 y(ho)o(bbies)795 693 y(drea)o(ms)795 +733 y(un)o(der)p 882 733 12 2 v 13 w(sco)o(r)q(e)o(.)220 +1036 y Fe(c)25 b(=)g(a_)o(simple_clas)o(s\(\))220 1085 +y(c.do_n)o(ame_clase\(')o(person'\))220 1135 y(c.do_a)o(ttributes\([)o +('name')g(,)g(')o(sex',)g('mone)o(y',)g('health)o(',)320 +1185 y('h)o(obbies',)g('d)o(reams']\))220 1235 y(c.do_f)o(unctions\([') +o(dream',)g('l)o(ove',)g('play)f(soccer',)h(')o(diving']\))220 +1285 y(c.inde)o(x_of_class\()o(3\))220 1384 y(c.do_l)o(ines\(\))220 +1434 y(c.gene)o(rate_latex_)o(code\('draw)o(ing3.tex'\))220 +1603 y Fd(3.2)50 b(Sou)o(rces)13 b(of)f(h)o(elp)220 1680 +y Fg(W)m(ell)o(,)j(the)f(best)g(y)o(ou)g(can)g(do)f(is)h(t)o(o)g(t)o(a) +q(k)o(e)g(a)h(l)o(ook)e(a)q(t)g(t)o(he)h(e)q(nd)f(of)g(c)q(on)o(s)q(d)o +(iag.py)g(where)h(you)g(can)220 1730 y(se)q(e)f(h)o(o)o(w)g(i)o(t)f +(gene)q(r)o(a)q(t)o(e)q(s)h(t)o(he)g(dr)o(aw)m(.)20 b(Se)q(cond)o(ly)m +(,)14 b(y)o(ou)e(s)q(h)o(oul)o(d)h(t)o(a)q(k)o(e)g(a)g(l)o(ook)f(a)q(t) +g(t)o(he)h(source)g(of)f(th)o(is)220 1780 y(document,)e(that)g(is:)i +(less)f(consdi)o(a)q(g)o(.)q(t)o(ex)f(T)m(wo)g(impo)o(rtant)g(detail)o +(s:)282 1863 y Ff(\017)21 b Fg(Don)o(')o(t)11 b(for)o(g)o(e)q(t)f(to)h +(i)o(nc)q(l)o(ude)g(th)o(e)h(comm)q(and:)i Fe(\\)o(usepackage{)o +(texdraw})d Fg(at)g(t)o(he)h(st)o(a)q(rt)324 1913 y(of)e(y)o(our)g +(docume)q(n)o(t)282 1996 y Ff(\017)21 b Fg(The)11 b(\002gu)o(re)q(s)f +(a)q(r)o(e)h(in)o(c)q(l)o(uded)f(using)g(a)h(si)o(m)q(p)o(le)g +Fe(\\in)o(put)g Fg(comma)q(n)o(d.)282 2079 y(And)f(th)o(a)q(t)o(')n(s)g +(a)q(l)o(l.)220 2219 y Fh(4)60 b(Some)14 b(ex)o(amples)h(of)g(i)o(t)220 +2320 y Fd(4.1)63 b(A)12 b(sim)q(p)o(le)h(class)220 2398 +y Fg(The)h(m)q(o)o(s)q(t)f(basic)h(\002gur)o(e)h(y)o(ou)f(ca)q(n)f +(face)i(wh)o(e)q(n)e(de)q(ali)o(ng)g(wit)o(h)h(OO)g(classe)q(s)g(i)o(s) +g(a)h(si)o(m)q(p)o(le)f(clas)q(s,)220 2448 y(wit)o(h)c(some)h(a)q(t)o +(tri)o(b)o(ut)o(e)q(s.)i(And)d(th)o(a)q(t)o(')n(s)g(what)g(you)g(ca)q +(n)g(se)q(e)g(in)g(\002gur)o(e)h(1.)220 2567 y Fd(4.2)63 +b(A)12 b(sim)q(p)o(le)h(class)g(wit)o(h)f(long)g(names)220 +2644 y Fg(Le)q(t)o(')n(s)f(se)q(e)g(what)g(happens)g(t)o(o)g(\002gure)g +(1)g(when)g(yo)o(u)g(want)f(to)h(i)o(nclud)o(e)h(a)f(re)q(all)o(y)g(l)o +(ong)g(att)o(rib)o(u)o(te.)k(If)220 2694 y(you)c(were)h(work)o(ing)f +(wit)o(h)h(a)g(t)o(radit)o(ion)o(a)q(l)f(dra)o(wing)g(ut)o(ili)o(ty)m +(,)h(you)f(wo)o(uld)g(hav)o(e)h(t)o(o)g(redra)o(w)g(a)q(l)o(l)f(the)926 +2831 y(2)p eop +%%Page: 3 3 +3 2 bop 605 294 a Fg(Fig)o(ure)11 b(2:)h(Sin)o(gle)e(\002)q(g)o(ure)h +(wi)o(th)f(l)o(ong)g(nam)q(es)588 961 y @beginspecial +0 @llx -147 @lly 167 @urx 0 @ury 1670 @rwi @setspecial +%%BeginDocument: consdiag.ps2 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +696 -57 lv +0 0 mv +348 0 lv +696 0 lv +696 -307 lv +696 -614 lv +348 -614 lv +0 -614 lv +0 -307 lv +0 0 lv +stroke end showpage +%%EndDocument + @endspecial 609 376 a Fc(perso)o(n)609 485 y(name)609 +525 y(se)o(x)609 562 y(m)q(o)o(ne)o(y)609 610 y(hea)o(l)q(th)609 +651 y(hobb)o(i)q(e)o(s)609 691 y(dr)q(e)o(ams)609 727 +y(opinion)f(ab)o(out)g(l)q(a)o(t)q(e)o(st)h(p)o(oll)q(s)609 +767 y(pos)o(i)q(ti)q(o)o(n)f(whe)o(n)h(p)o(l)q(a)o(ying)f(s)o(occ)o(er) +609 807 y(f)q(a)n(v)o(ouri)q(te)g(s)o(cri)q(p)o(t)q(ing)g(lang)o(uag)o +(e)220 1125 y Fg(box)o(.)16 b(But)10 b(with)h(t)o(hi)o(s)h(ut)o(il)o +(it)o(y)f(no.)16 b(That')m(s)c(what)f(yo)o(u)g(got)g(\(\002g)o(ure)h(2) +o(\).)k(So,)c(t)o(his)f(ut)o(ili)o(ty)g(i)o(s)h(st)o(a)q(rt)o(in)o(g) +220 1175 y(to)e(p)o(a)q(y)m(,)h(i)o(sn')o(t)f(it)o(?)220 +1293 y Fd(4.3)63 b(A)12 b(sim)q(p)o(le)h(class)g(wit)o(h)f(attri)o(b)o +(ut)o(e)q(s)g(and)g(m)q(ark)g(of)g(cardi)o(nalit)o(y)220 +1371 y Fg(W)m(ell)o(,)h(i)o(t')n(s)f(t)o(ime)g(to)f(se)q(e)h(a)g(c)q(l) +o(a)q(ss)g(at)g(i)o(ts)g(fu)o(ll)f(ext)o(e)q(n)o(t.)18 +b(A)11 b(c)q(l)o(a)q(ss)h(ma)q(y)f(hav)o(e)h(fun)o(c)q(t)o(ion)o(s,)h +(and)f(i)o(t)g(may)220 1421 y(be)h(in)o(c)q(l)o(uded)g(i)o(n)g(more)g +(t)o(ha)q(n)f(one)h(dra)o(wing)o(.)21 b(In)12 b(th)o(a)q(t)g(c)q(ase)h +(a)h(mark)f(of)f(c)q(ardi)o(nali)o(ty)g(\()h(a)g(number)220 +1471 y(th)o(a)q(t)d(sa)q(y)o(s)h(ho)o(w)g(many)f(ti)o(m)q(es)h(t)o(ha)q +(t)f(clas)q(s)h(h)o(a)q(s)g(b)o(e)q(en)g(dr)o(awn)g(\))g(i)o(s)g(sho)o +(wn)o(.)k(An)c(e)o(xa)q(mpl)o(e)g(of)g(such)g(a)220 1520 +y(clas)q(s)g(is)h(what)f(you)g(c)q(an)h(see)g(a)q(t)f(\002gur)o(e)i(3)o +(.)18 b(I)o(n)12 b(t)o(his)g(cas)q(e)g(t)o(he)g(c)q(ardi)o(nali)o(ty)f +(is)h(3.)17 b(This)11 b(is)h(\002gu)o(re)g(is)220 1570 +y(don)o(e)f(wit)o(h)f(the)g(py)o(thon)g(code:)220 1651 +y Fe(c)25 b(=)g(a_)o(simple_clas)o(s\(\))220 1701 y(c.do_n)o +(ame_clase\(')o(person'\))220 1751 y(c.do_a)o(ttributes\([)o('name')g +(,)g(')o(sex',)g('mone)o(y',)g('health)o(',)320 1801 +y('h)o(obbies',)g('d)o(reams']\))220 1850 y(c.do_f)o(unctions\([')o +(dream',)g('l)o(ove',)g('play)f(soccer',)h(')o(diving']\))220 +1900 y(c.inde)o(x_of_class\()o(3\))220 2000 y(c.do_l)o(ines\(\))220 +2050 y(c.gene)o(rate_latex_)o(code\('draw)o(ing3.tex'\))220 +2249 y Fd(4.4)63 b(Inh)o(er)q(i)o(tances)13 b(examples)220 +2327 y Fg(W)m(ell)o(,)j(til)o(l)e(no)o(w)m(,)i(it)o(')n(s)e(a)h(very)f +(simpl)o(e)i(p)o(rogr)o(a)q(m,)g(let')m(s)f(f)o(a)q(ce)g(a)g(m)q(o)o +(re)g(int)o(e)q(r)o(e)q(sti)o(ng)f(example.)26 b(A)220 +2377 y(in)o(herit)o(a)q(nce)11 b(of)f(classe)q(s.)j(\002gure)e(4)282 +2426 y(T)q(h)o(is)f(is)h(achie)o(v)o(e)q(d)f(t)o(ypese)q(t)o(ti)o(ng)g +(:)320 2507 y Fe(c)24 b(=)h(a_simple_)o(class\(\))320 +2557 y(c.)o(do_name_cla)o(se\('person)o('\))320 2607 +y(c.)o(do_attribut)o(es\(['name')f(,)h('sex',)g(')o(money',)g('he)o +(alth',)320 2657 y('h)o(obbies',)g('d)o(reams']\))320 +2707 y(c.)o(do_function)o(s\(['dream')o(,)g('love',)g(')o(play)g +(soccer)o(',)g('diving)o(']\))926 2831 y Fg(3)p eop +%%Page: 4 4 +4 3 bop 427 294 a Fg(Figu)o(re)11 b(3:)h(Sing)o(le)f(\002gu)o(re)g(wi)o +(th)f(a)q(t)o(tr)o(ib)o(ut)o(ion)o(s,)h(funct)o(ions)f(and)g(m)q(arks) +799 1011 y @beginspecial 0 @llx -159 @lly 66 @urx 0 @ury +660 @rwi @setspecial +%%BeginDocument: consdiag.ps3 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +274 -57 lv +0 -368 mv +274 -368 lv +0 0 mv +137 0 lv +274 0 lv +274 -331 lv +274 -662 lv +191 -662 mv +274 -579 lv +191 -662 lv +215 -638 mv +215 -638 lv +274 -662 mv +137 -662 lv +0 -662 lv +0 -331 lv +0 0 lv +stroke end showpage +%%EndDocument + @endspecial 820 378 a Fc(pe)o(r)q(s)o(on)820 487 y(na)o(me)820 +527 y(s)o(e)o(x)820 564 y(mon)o(e)o(y)820 612 y(he)o(alt)q(h)820 +653 y(ho)o(bbies)820 693 y(drea)o(ms)820 792 y(drea)o(m)820 +830 y(lo)o(ve)820 863 y(play)f(s)o(oc)o(cer)820 901 y(di)o(ving)1023 +1000 y(3)320 1227 y Fe(c.)o(do_lines\(\))320 1277 y(d)24 +b(=)h(a_simple_)o(class\(\))320 1327 y(d.)o(do_name_cla)o(se\('work'\)) +320 1376 y(d.)o(do_attribut)o(es\(['salar)o(y')g(,)g('post')o(,)320 +1426 y('l)o(abor)g(union')o(,)g('product)o(ivity',)g('qu)o(alification) +o(s',)345 1476 y(')o(capabilitie)o(s']\))320 1526 y(d.)o(do_function)o +(s\(['work',)f('strike',)g('be)h(ill',)g(')o(be)g(fired'])o(\))320 +1625 y(d.)o(do_lines\(\))320 1675 y(e)f(=)h(union_der)o(ivation\(\))320 +1725 y(e.)o(add_union\(c)o(,d\))320 1775 y(e.)o(generate_la)o +(tex_code\(')o(drawing4.te)o(x'\))220 1908 y Fg(Ea)q(sy)m(,)11 +b(uh)f(?)j(:)o(\))282 1958 y(But)c(m)q(u)o(c)q(h)h(more)g(c)q(ompl)o +(ex)g(dr)o(awing)o(s)h(are)g(also)f(eas)q(y)g(t)o(o)g(do)g(as)h(sh)o(o) +o(ws)21 b(5)10 b(,)g(th)o(is)g(is)g(a)h(pi)o(c)q(t)o(ure)220 +2007 y(of)f(a)h(mot)o(he)q(r)f(class)h(t)o(ha)q(t)e(ha)q(s)h(sev)o(era) +q(l)f(da)q(u)o(ght)o(e)q(r)h(c)q(l)o(as)q(ses.)292 2057 +y Fb(R)q(e)o(g)o(r)o(etf)o(ull)o(y)n(,)h(it)e(IS)h Fa(NO)n(T)i(poss)q +(i)o(ble)h(\()o(right)f(now\))g(to)g(inheritate)g(fr)n(om)g(mor)n(e)h +(t)o(han)220 2107 y(one)f(c)q(l)o(as)q(s.)29 b Fg(In)o(s)q(t)o(ea)q(d) +10 b(,)h(yo)o(u)f(c)q(an)g(use)h(in)o(dice)q(s)f(to)g(ma)q(r)o(k)g(s)q +(e)o(v)o(e)q(r)o(a)q(l)g(i)o(nherit)o(a)q(n)o(c)q(es.)282 +2157 y(And)j(,)i(well)o(,)g(you)e(ca)q(n)g(use)h(sev)o(eral)f(le)o(vel) +o(s)h(of)f(inh)o(e)q(ri)o(tance)q(s,)i(j)o(ust)e(be)h(a)g(bi)o(t)f(c)q +(areful)g(about)220 2207 y(ho)n(w)e(yo)o(u)f(b)o(uil)o(d)g(the)g(c)q +(od)o(e)q(,)h(t)o(a)q(k)o(e)g(t)o(his)f(\(i)o(t)g(m)q(ak)o(e)q(s)g +(\002gure)21 b(6\))10 b(as)h(ex)o(a)q(mpl)o(e)q(:)320 +2290 y Fe(d)24 b(=)h(a_simple_)o(class\(\))320 2339 y(d.)o(do_name_cla) +o(se\('worker)o('\))320 2389 y(d.)o(do_attribut)o(es\(['salar)o(y')g(,) +g('post')o(,)320 2439 y('l)o(abor)g(union')o(,)g('product)o(ivity',)g +('qu)o(alification)o(s',)345 2489 y(')o(capabilitie)o(s']\))320 +2638 y(d.)o(do_lines\(\))320 2688 y(f)f(=)h(a_simple_)o(class\(\))926 +2831 y Fg(4)p eop +%%Page: 5 5 +5 4 bop 693 696 a Fg(Fi)o(gure)10 b(4:)j(Si)o(m)q(p)o(le)e(i)o(nheri)o +(tanc)q(e)763 2263 y @beginspecial -12 @llx -363 @lly +71 @urx 0 @ury 830 @rwi @setspecial +%%BeginDocument: consdiag.ps4 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +274 -57 lv +0 -368 mv +274 -368 lv +0 0 mv +137 0 lv +274 0 lv +274 -331 lv +274 -662 lv +137 -662 lv +0 -662 lv +0 -331 lv +0 0 lv +137 -661 mv +137 -779 lv +161 -803 lv +114 -803 lv +138 -779 lv +114 -803 lv +20 -803 lv +20 -850 lv +-52 -850 mv +-52 -850 lv +-52 -850 mv +-52 -850 lv +-52 -850 mv +-52 -850 lv +-52 -907 mv +296 -907 lv +-52 -1219 mv +296 -1219 lv +-52 -850 mv +122 -850 lv +296 -850 lv +296 -1181 lv +296 -1512 lv +122 -1512 lv +-52 -1512 lv +-52 -1181 lv +-52 -850 lv +stroke end showpage +%%EndDocument + @endspecial 836 779 a Fc(perso)o(n)836 889 y(name)836 +929 y(se)o(x)836 965 y(m)q(o)o(ne)o(y)836 1014 y(hea)o(l)q(th)836 +1055 y(hobb)o(i)q(e)o(s)836 1095 y(dr)q(e)o(ams)836 1194 +y(dr)q(e)o(am)836 1232 y(l)q(o)o(v)o(e)836 1265 y(pl)q(a)o(y)e(so)o +(cce)o(r)836 1303 y(div)o(i)q(n)o(g)784 1638 y(work)784 +1740 y(salary)784 1778 y(pos)o(t)784 1825 y(l)q(a)o(bor)h(u)o(nion)784 +1861 y(pr)q(o)o(duc)o(t)q(i)o(vit)q(y)784 1901 y(qua)o(l)q(i\002ca)o(t) +q(ion)o(s)784 1941 y(cap)o(abili)q(ti)q(e)o(s)784 2044 +y(work)784 2082 y(str)q(ike)784 2120 y(be)f(il)q(l)784 +2158 y(be)g(\002red)926 2831 y Fg(5)p eop +%%Page: 6 6 +6 5 bop 682 886 a Fg(Fig)o(ure)11 b(5:)h(Se)o(veral)e(in)o(he)q(r)o +(itance)q(s)359 2073 y @beginspecial -24 @llx -272 @lly +253 @urx 0 @ury 2770 @rwi @setspecial +%%BeginDocument: consdiag.ps5 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +174 -57 lv +0 0 mv +87 0 lv +174 0 lv +174 -236 lv +174 -472 lv +87 -472 lv +0 -472 lv +0 -236 lv +0 0 lv +87 -472 mv +87 -590 lv +111 -614 lv +64 -614 lv +88 -590 lv +64 -614 lv +-30 -614 lv +-30 -661 lv +-102 -661 mv +-102 -661 lv +-102 -661 mv +-102 -661 lv +-102 -661 mv +-102 -661 lv +-102 -718 mv +246 -718 lv +-102 -661 mv +72 -661 lv +246 -661 lv +246 -897 lv +246 -1133 lv +72 -1133 lv +-102 -1133 lv +-102 -897 lv +-102 -661 lv +111 -614 mv +332 -614 lv +332 -661 lv +261 -661 mv +261 -661 lv +261 -661 mv +261 -661 lv +261 -661 mv +261 -661 lv +261 -718 mv +559 -718 lv +261 -661 mv +410 -661 lv +559 -661 lv +559 -897 lv +559 -1133 lv +410 -1133 lv +261 -1133 lv +261 -897 lv +261 -661 lv +332 -614 mv +678 -614 lv +678 -661 lv +607 -661 mv +607 -661 lv +607 -661 mv +607 -661 lv +607 -661 mv +607 -661 lv +607 -718 mv +1055 -718 lv +607 -661 mv +831 -661 lv +1055 -661 lv +1055 -897 lv +1055 -1133 lv +831 -1133 lv +607 -1133 lv +607 -897 lv +607 -661 lv +stroke end showpage +%%EndDocument + @endspecial 482 969 a Fc(perso)o(n)482 1079 y(name)482 +1119 y(se)o(x)482 1155 y(mone)o(y)482 1203 y(hea)o(l)q(th)482 +1244 y(hob)o(bies)482 1284 y(dreams)380 1638 y(work)o(er)380 +1740 y(sa)o(l)q(a)o(r)q(y)380 1778 y(pos)o(t)380 1825 +y(l)q(a)o(bor)f(union)380 1861 y(produ)o(ctivity)380 +1901 y(qua)o(l)q(i\002c)o(ati)q(o)o(ns)380 1941 y(cap)o(ab)o(i)q(li)q +(ties)743 1638 y(father)743 1740 y(b)o(us)o(y)743 1784 +y(t)q(e)o(nde)o(r)q(n)o(ess)743 1825 y(stubo)o(r)q(n)o(nes)o(s)743 +1861 y(cares)o(s)743 1905 y(kiss)o(es)743 1941 y(cap)o(ab)o(i)q(li)q +(ties)1089 1634 y(che)o(ss)g(p)o(l)q(a)o(yer)1089 1744 +y(elo)1089 1780 y(cruelty)1089 1825 y(stubo)o(r)q(n)o(nes)o(s)1089 +1865 y(bad)g(tri)q(c)o(ks)1089 1901 y(i)q(n)o(t)q(e)o(l)q(li)q(g)o(en)o +(ce)1089 1941 y(ope)o(nings)g(k)o(no)o(wled)o(ge)926 +2831 y Fg(6)p eop +%%Page: 7 7 +7 6 bop 320 266 a Fe(f.)o(do_name_cla)o(se\('comput)o(er)25 +b(scientis)o(t'\))320 315 y(f.)o(do_attribut)o(es\(['langu)o(ages')g(,) +g('pr)o(eferred)g(OS')o(,)320 365 y('p)o(referred)g(ed)o(itor',)g('ha)o +(ckerism',)g(')o(ATBB']\))320 465 y(f.)o(do_lines\(\))320 +565 y(h)f(=)h(union_der)o(ivation\(\))320 614 y(h.)o(add_union\(d)o +(,f\))320 714 y(c)f(=)h(a_simple_)o(class\(\))320 764 +y(c.)o(do_name_cla)o(se\('person)o('\))320 814 y(c.)o(do_attribut)o +(es\(['name')f(,)h('sex',)g(')o(money',)g('he)o(alth',)320 +863 y('h)o(obbies',)g('d)o(reams']\))320 913 y(c.)o(do_lines\(\))320 +1013 y(e)f(=)h(union_der)o(ivation\(\))320 1063 y(e.)o(add_union\(c)o +(,h\))320 1112 y(e.)o(generate_la)o(tex_code\(')o(drawing6.te)o(x'\)) +282 1245 y Fg(Finall)o(y)13 b(a)h(rema)q(i)o(nder:)k(Y)-5 +b(ou)13 b(ca)q(n)g(combin)o(e)h(th)o(is)f(fea)q(t)o(ures)h(so)f(yo)o(u) +g(c)q(an)g(get)g(se)o(veral)g(l)o(ev)o(els)220 1295 y(and)d(wit)o(h)h +(se)o(v)o(e)q(r)o(a)q(l)f(son)o(s)q(,)g(b)o(ut...)k(w)o(a)q(t)o(c)q(h)c +(t)o(he)h(spac)q(e!)i(The)e(p)o(iec)q(e)g(o)o(f)f(pa)q(p)o(e)q(r)g(has) +h(i)o(ts)f(li)o(m)q(i)o(tati)o(ons.)220 1414 y Fd(4.5)63 +b(Associati)o(ons)13 b(examples)220 1492 y Fg(W)m(ell)o(,)f(I)f(got)f +(a)i(bi)o(t)f(up)o(s)q(et)g(wh)o(e)q(n)g(I)g(reali)o(z)q(e)g(that)g(f)o +(a)q(ct)g(of)g(mul)o(ti)o(ple)g(in)o(he)q(r)o(itance)q(s,)g(s)q(o)g +(associati)o(ons)220 1542 y(ha)o(v)o(e)q(n')o(t)g(g)o(ot)g(so)g(compli) +o(c)q(ated,)h(and)f(i)o(n)g(fac)q(t)f(,)i(you)f(can)g(do)g(onl)o(y)g(a) +q(ssociati)o(ons)g(between)g(s)q(i)o(mple)220 1591 y(clas)q(ses)e(and)f +(a)q(ssociati)o(ons,)h(s)q(o)f(yo)o(u)h(ca)q(n)o(')o(t)g(mi)o(x)g(ass)q +(o)o(c)q(i)o(a)q(t)o(ion)o(s)g(a)q(n)o(d)g(d)o(e)q(ri)n(v)o(ati)o(ons,) +g(that)f(wou)o(ld)g(hav)o(e)220 1641 y(bee)q(n)i(\002ne.)j(\002gure)d +(7)220 1760 y Fd(4.6)50 b(Aggr)o(egati)o(ons)13 b(t)o(oo!)220 +1838 y Fg(Y)-5 b(ou)11 b(can)g(do)f(a)q(g)o(greg)o(a)q(t)o(io)o(ns,)i +(j)o(ust)e(replac)q(e)h(\223deri)o(v)n(a)q(t)o(ion)o(\224)h(i)o(n)e +(the)h(pr)o(evi)o(ous)g(e)o(xa)q(mpl)o(e)q(s)f(for)g(\223)q(agre-)220 +1888 y(gati)o(on\224)g(a)q(nd)g(t)o(hat')n(s)g(all.)j(As)d(exam)q(p)o +(le)h(l)o(ook)f(at)g(\002gure)21 b(8.)220 2028 y Fh(5)75 +b(Ca)n(v)o(eats)15 b(and)g(b)o(u)q(g)o(s)220 2121 y Fg(If)10 +b(you)g(w)o(a)q(n)o(t)g(to)g(do)g(v)o(ery)g(c)q(ompl)o(ex)g(draw)o +(ings)g(as)q(:)282 2204 y Ff(\017)21 b Fg(se)o(v)o(e)q(ral)10 +b(le)o(v)o(e)q(l)o(s)h(o)o(f)g(i)o(nheri)o(tanc)q(es/agreg)o(atio)o(ns) +g(and)f(ea)q(ch)g(oth)o(e)q(r)g(wit)o(h)g(lot)o(s)h(o)o(f)g(so)o(ns,) +282 2287 y Ff(\017)21 b Fg(really)10 b(d)o(e)q(ep)g(tree)q(s)g(of)g(in) +o(he)q(r)o(itance)q(s,)g(m)q(or)o(e)h(th)o(a)q(n)f(fou)o(r)h(are)g(p)o +(robabl)o(y)g(a)f(re)q(all)o(y)g(bad)h(i)o(dea)q(,)282 +2370 y Ff(\017)21 b Fg(se)o(v)o(e)q(ral)10 b(nested)g(a)q(ssociati)o +(ons,)220 2453 y(th)o(e)q(n)o(,)j(pro)o(ba)q(b)o(ly)f(y)o(ou')o(ll)f +(get)h(a)g(shi)o(t)g(as)g(out)o(c)q(ome.)18 b(This)12 +b(u)o(ti)o(lit)o(y)g(i)o(s)g(not)f(c)q(l)o(ev)o(er)n(,)i(j)o(ust)f(t)o +(ry)g(t)o(o)g(t)o(o)g(se)q(t)220 2502 y(th)o(e)f(c)q(l)o(a)q(sses)g(i)o +(n)f(a)h(log)o(ica)q(l)o(,)g(predetermined)f(way)m(.)282 +2552 y(Apart)h(fr)o(om)h(t)o(hi)o(s)g(cav)o(ea)q(t)o(,)g(t)o(here)q(')o +(ll)e(be)h(s)q(o)o(m)q(e)g(b)o(ugs,)g(.)c(.)f(.)h(,)12 +b(o)o(r)f(perhaps)g(not)o(.)16 b(p)o(yt)o(hon)11 b(i)o(s)g(ra)q(t)o +(her)220 2602 y(rob)o(u)o(st!)926 2831 y(7)p eop +%%Page: 8 8 +8 7 bop 607 577 a Fg(Fi)o(gure)11 b(6)o(:)i(Se)o(v)o(e)q(ral)d(l)o(ev)o +(els)g(of)g(inh)o(e)q(ri)o(tance)q(s)713 2382 y @beginspecial +-28 @llx -420 @lly 79 @urx 0 @ury 1070 @rwi @setspecial +%%BeginDocument: consdiag.ps6 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +174 -57 lv +0 0 mv +87 0 lv +174 0 lv +174 -236 lv +174 -472 lv +87 -472 lv +0 -472 lv +0 -236 lv +0 0 lv +87 -472 mv +87 -590 lv +111 -614 lv +64 -614 lv +88 -590 lv +64 -614 lv +-30 -614 lv +-30 -661 lv +-102 -661 mv +-102 -661 lv +-102 -661 mv +-102 -661 lv +-102 -661 mv +-102 -661 lv +-102 -718 mv +246 -718 lv +-102 -661 mv +72 -661 lv +246 -661 lv +246 -897 lv +246 -1133 lv +72 -1133 lv +-102 -1133 lv +-102 -897 lv +-102 -661 lv +72 -1134 mv +72 -1252 lv +96 -1276 lv +49 -1276 lv +73 -1252 lv +49 -1276 lv +-45 -1276 lv +-45 -1323 lv +-117 -1323 mv +-117 -1323 lv +-117 -1323 mv +-117 -1323 lv +-117 -1323 mv +-117 -1323 lv +-117 -1379 mv +331 -1379 lv +-117 -1323 mv +107 -1323 lv +331 -1323 lv +331 -1536 lv +331 -1749 lv +107 -1749 lv +-117 -1749 lv +-117 -1536 lv +-117 -1323 lv +stroke end showpage +%%EndDocument + @endspecial 851 661 a Fc(perso)o(n)851 771 y(name)851 +811 y(se)o(x)851 847 y(m)q(o)o(ne)o(y)851 895 y(hea)o(l)q(th)851 +936 y(hobb)o(i)q(e)o(s)851 976 y(dr)q(e)o(ams)749 1330 +y(worke)o(r)749 1432 y(salary)749 1471 y(pos)o(t)749 +1517 y(l)q(a)o(bor)g(u)o(nion)749 1553 y(pr)q(o)o(duc)o(t)q(i)o(vit)q +(y)749 1593 y(qua)o(l)q(i\002ca)o(t)q(ion)o(s)749 1633 +y(cap)o(abili)q(ti)q(e)o(s)734 1988 y(compu)o(t)q(e)o(r)g(s)o(cientist) +734 2095 y(l)q(a)o(ngua)o(ge)o(s)734 2135 y(pr)q(e)o(f)q(e)o(r)q(red)f +(OS)734 2175 y(pr)q(e)o(f)q(e)o(r)q(red)g(e)o(dit)q(o)o(r)734 +2218 y(hac)o(ke)o(r)q(ism)734 2258 y(A)l(TBB)926 2831 +y Fg(8)p eop +%%Page: 9 9 +9 8 bop 693 416 a Fg(Fi)o(gure)10 b(7:)j(Si)o(m)q(p)o(le)e(assoc)q(i)o +(a)q(t)o(io)o(n)511 941 y @beginspecial 0 @llx -113 @lly +204 @urx 0 @ury 2040 @rwi @setspecial +%%BeginDocument: consdiag.ps7 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +398 -57 lv +0 0 mv +199 0 lv +398 0 lv +398 -236 lv +398 -472 lv +199 -472 lv +0 -472 lv +0 -236 lv +0 0 lv +400 -212 mv +400 -212 lv +398 -236 mv +625 -236 lv +533 -212 mv +533 -212 lv +625 -142 mv +625 -142 lv +625 -142 mv +625 -142 lv +625 -142 mv +625 -142 lv +625 -198 mv +849 -198 lv +625 -142 mv +737 -142 lv +849 -142 lv +849 -307 lv +849 -472 lv +737 -472 lv +625 -472 lv +625 -307 lv +625 -142 lv +stroke end showpage +%%EndDocument + @endspecial 532 502 a Fc(enterpri)q(s)o(e)532 608 y(name)532 +648 y(pr)q(o)o(\002ts)532 692 y(estab)o(l)q(is)o(hed)532 +728 y(\002sc)o(al)f(p)o(aradise)o(s)532 773 y(f)q(raud)o(s)532 +813 y(bad)f(tr)q(ick)o(s)920 694 y(0:n)85 b(0:1)1156 +647 y(work)o(er)1156 746 y(wag)o(e)1156 794 y(t)q(imetable)1156 +830 y(sen)o(i)q(o)o(r)q(it)q(y)675 1330 y Fg(Fi)o(gure)10 +b(8:)j(M)o(ult)o(ipl)o(e)e(aggreg)o(a)q(t)o(io)o(n)359 +2543 y @beginspecial -30 @llx -278 @lly 247 @urx 0 @ury +2770 @rwi @setspecial +%%BeginDocument: consdiag.ps8 +50 dict begin +/mv {stroke moveto} def +/lv {lineto} def +/st {currentpoint stroke moveto} def +/sl {st setlinewidth} def +/sd {st 0 setdash} def +/sg {st setgray} def +/bs {gsave} def /es {stroke grestore} def +/fl {gsave setgray fill grestore + currentpoint newpath moveto} def +/fp {gsave setgray fill grestore st} def +/cv {curveto} def +/cr {gsave currentpoint newpath 3 -1 roll 0 360 arc + stroke grestore} def +/fc {gsave setgray currentpoint newpath + 3 -1 roll 0 360 arc fill grestore} def +/ar {gsave currentpoint newpath 5 2 roll arc stroke grestore} def +/el {gsave /svm matrix currentmatrix def + currentpoint translate scale newpath 0 0 1 0 360 arc + svm setmatrix stroke grestore} def +/fe {gsave setgray currentpoint translate scale newpath + 0 0 1 0 360 arc fill grestore} def +/av {/hhwid exch 2 div def /hlen exch def + /ah exch def /tipy exch def /tipx exch def + currentpoint /taily exch def /tailx exch def + /dx tipx tailx sub def /dy tipy taily sub def + /alen dx dx mul dy dy mul add sqrt def + /blen alen hlen sub def + gsave tailx taily translate dy dx atan rotate + (V) ah ne {blen 0 gt {blen 0 lineto} if} {alen 0 lineto} ifelse + stroke blen hhwid neg moveto alen 0 lineto blen hhwid lineto + (T) ah eq {closepath} if + (W) ah eq {gsave 1 setgray fill grestore closepath} if + (F) ah eq {fill} {stroke} ifelse + grestore tipx tipy moveto} def +0.24 0.24 scale +1 setlinecap 1 setlinejoin +3 setlinewidth [] 0 setdash +0 0 moveto +0 sl +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 0 mv +0 0 lv +0 -57 mv +174 -57 lv +0 0 mv +87 0 lv +174 0 lv +174 -236 lv +174 -472 lv +87 -472 lv +0 -472 lv +0 -236 lv +0 0 lv +87 -472 mv +111 -496 lv +87 -520 lv +111 -496 lv +87 -472 lv +63 -496 lv +87 -520 lv +87 -638 lv +-55 -638 lv +-55 -685 lv +-126 -685 mv +-126 -685 lv +-126 -685 mv +-126 -685 lv +-126 -685 mv +-126 -685 lv +-126 -742 mv +222 -742 lv +-126 -685 mv +48 -685 lv +222 -685 lv +222 -921 lv +222 -1157 lv +48 -1157 lv +-126 -1157 lv +-126 -921 lv +-126 -685 lv +87 -638 mv +308 -638 lv +308 -685 lv +237 -685 mv +237 -685 lv +237 -685 mv +237 -685 lv +237 -685 mv +237 -685 lv +237 -742 mv +535 -742 lv +237 -685 mv +386 -685 lv +535 -685 lv +535 -921 lv +535 -1157 lv +386 -1157 lv +237 -1157 lv +237 -921 lv +237 -685 lv +308 -638 mv +654 -638 lv +654 -685 lv +583 -685 mv +583 -685 lv +583 -685 mv +583 -685 lv +583 -685 mv +583 -685 lv +583 -742 mv +1031 -742 lv +583 -685 mv +807 -685 lv +1031 -685 lv +1031 -921 lv +1031 -1157 lv +807 -1157 lv +583 -1157 lv +583 -921 lv +583 -685 lv +stroke end showpage +%%EndDocument + @endspecial 506 1414 a Fc(perso)o(n)506 1524 y(name)506 +1564 y(se)o(x)506 1600 y(mone)o(y)506 1648 y(hea)o(l)q(th)506 +1689 y(hob)o(bies)506 1729 y(dreams)380 2108 y(work)o(er)380 +2210 y(sa)o(l)q(a)o(r)q(y)380 2248 y(pos)o(t)380 2294 +y(l)q(a)o(bor)e(union)380 2330 y(produ)o(ctivity)380 +2371 y(qua)o(l)q(i\002c)o(ati)q(o)o(ns)380 2411 y(cap)o(ab)o(i)q(li)q +(ties)743 2108 y(father)743 2210 y(b)o(us)o(y)743 2254 +y(t)q(e)o(nde)o(r)q(n)o(ess)743 2294 y(stubo)o(r)q(n)o(nes)o(s)743 +2329 y(cares)o(s)743 2375 y(kiss)o(es)743 2411 y(cap)o(ab)o(i)q(li)q +(ties)1089 2104 y(che)o(ss)g(p)o(l)q(a)o(yer)1089 2214 +y(elo)1089 2250 y(cruelty)1089 2294 y(stubo)o(r)q(n)o(nes)o(s)1089 +2334 y(bad)g(tri)q(c)o(ks)1089 2371 y(i)q(n)o(t)q(e)o(l)q(li)q(g)o(en)o +(ce)1089 2411 y(ope)o(nings)g(k)o(no)o(wled)o(ge)926 +2831 y Fg(9)p eop +%%Page: 10 10 +10 9 bop 220 266 a Fh(6)60 b(By)o(e)14 b(b)q(y)o(e)220 +358 y Fg(I)g(hope)h(t)o(hi)o(s)g(docume)q(n)o(tati)o(on)g(h)o(e)q(l)o +(ps)g(y)o(ou)g(t)o(o)f(use)h(thi)o(s)g(ut)o(il)o(it)o(y)m(.)26 +b(It')m(s)15 b(no)o(t)f(dif)n(\002)q(cul)o(t)g(a)q(nd)g(gr)o(e)q(atl)o +(y)220 408 y(pro)o(\002table.)h(And)10 b(if)h(yo)o(u)g(want)f(to)g(ge)q +(t)g(simil)o(a)q(r)g(drawi)o(ngs)h(or)f(impro)o(v)o(e)h(s)q(o)o(m)q(e)g +(of)g(t)o(hem)g(just)f(take)220 458 y(a)h(l)o(ook)f(at)g(the)g(c)q(od)o +(e)q(,)h(o)o(nc)q(e)f(you)g(get)g(a)q(ccostumed)g(to)g(it)g(,)g(you')o +(ll)f(\002)q(n)o(d)h(it)g(qu)o(it)o(e)h(log)o(ica)q(l)o(.)915 +2831 y(10)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF 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() + + + + + diff --git a/support/consdiag/consdiag.tex b/support/consdiag/consdiag.tex new file mode 100644 index 0000000000..a4a7c4e9af --- /dev/null +++ b/support/consdiag/consdiag.tex @@ -0,0 +1,289 @@ +% If you don't know how to handle a .tex file, do this : +% latex consdiag.tex +% xdvi consdiag.dvi +% See dvips man page if you want it in postscript +% I don't supply postscripts because they're usually huge. + +\documentclass[10pt,a4paper]{article} +\usepackage{times} +\usepackage{texdraw} +\begin{document} +\title{Documentation and examples of consdiag.py version 1.0} +\author{ Manuel Gutierrez Algaba, irmina@ctv.es } +\date{ December 1998 } +\maketitle + +\section{Copyright issues} +consdiag.py and its documentation ( this text and the sources +of tex drawings included in it) are copyrighted by Manuel +Gutierrez Algaba 1999 and you are free +to use, modify , copy and distribute it under the +condition that +you include this notice ad in it. + +\section{Introduction} +When I wrote this program there wasn't any automated utility for +drawing Rumbaugh OO boxes. Of course, you can use xfig or any +other drawing program for this purpose. But this utility has +two major advantages, It's easier to use and it's faster to 'draw'. +On the other hand, the kinds of available drawings are limited to: +\begin{itemize} +\item isolated classes +\item trees (and just trees, no graphs :( ) of classes related by their inheritances +\item simple associations of classes +\end{itemize} + +It's not much , but... + + +And this is an utility written in python. +\begin{verbatim} +http://www.python.org +\end{verbatim} + +I imagine that it could be written in \TeX { }but It's 10 times easier +to use python. And what's more important \TeX{ }programmers have a +model , if they want to do the translation. \\ Another point, the +python code could be improved, I've duplicated code in several +parts, because I thought the classes were really different each other, +\ldots, in the end, they've resulted to be very similar in the +way they work. + + +And, it generates tex code. So if you want it in postscript, gif +or whatever, use the programs dvi, gs or grab directly from a +window! + +\section{ How to use it} +\subsection{Using it in a python code } +Just use a ``from consdiag import * `` +and this piece of python code ( for example). +In drawing3.tex is kept the following \TeX { } instructions that generates the +drawing ~\ref{fig:second}: +\begin{verbatim} +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') + +\end{verbatim} +\subsection{Sources of help} +Well, the best you can do is to take a look at the end of consdiag.py +where you can see how it generates the draw. +Secondly, you should take a look at the source of this document, +that is: less consdiag.tex +Two important details: +\begin{itemize} +\item + Don't forget to include the command: \verb|\usepackage{texdraw}| +at the start of your document +\item +The figures are included using a simple \verb|\input| + command. +\end{itemize} + + +And that's all. + +\section{Some examples of it} +\subsection{ A simple class} +The most basic figure you can face when dealing with OO classes is +a simple class, with some attributes. And that's what you can see +in figure~\ref{fig:first}. +\begin{figure} +%\vspace{3in} +\caption{Single figure} +\label{fig:first} +\input{drawing1.tex} +\end{figure} + +\subsection{ A simple class with long names} +Let's see what happens to figure~\ref{fig:first} when you want to +include a really long attribute. If you were working with a +traditional drawing utility, you would have to redraw all the box. +But with this utility no. That's what you got (figure~\ref{fig:second}). +So, this utility is starting to pay, isn't it? + +\begin{figure} +%\vspace{3in} +\caption{Single figure with long names} +\label{fig:second} +\input{drawing2.tex} +\end{figure} + +\subsection{ A simple class with attributes and mark of cardinality } +Well, it's time to see a class at its full extent. A class may have +functions, and it may be included in more than one drawing. In + that case a mark of cardinality ( a number that says how many +times that class has been drawn ) is shown. An example of such +a class is what you can see at figure~\ref{fig:third}. In this case +the cardinality is 3. +This is figure is done with the python code: +\begin{verbatim} +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') + +\end{verbatim} + + +\begin{figure} +%\vspace{3in} +\caption{Single figure with attributions, functions and marks} +\label{fig:third} +\input{drawing3.tex} +\end{figure} + +\subsection{ Inheritances examples} +Well, till now, it's a very simple program, let's face a more +interesting example. A inheritance of classes. figure~\ref{fig:fourth} + +\begin{figure} +%\vspace{3in} +\caption{Simple inheritance } +\label{fig:fourth} +\input{drawing4.tex} +\end{figure} +This is achieved typesetting : +\begin{verbatim} + 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') + +\end{verbatim} +Easy, uh ? :) + +But much more complex drawings are also easy to do as shows ~\ref{fig:fifth} , this is a picture of a mother class that has several +daughter classes. + +\emph{ Regretfully, it IS \large NOT possible (right now) to inheritate +from more than one class. } +Instead , you can use indices to mark several inheritances. + +\begin{figure} +%\vspace{3in} +\caption{Several inheritances } +\label{fig:fifth} +\input{drawing5.tex} +\end{figure} + +And , well, you can use several levels of inheritances, just be +a bit careful about how you build the code, take this (it makes figure ~\ref{fig:sixth}) as example: +\begin{verbatim} + 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') + +\end{verbatim} +\begin{figure} +%\vspace{3in} +\caption{Several levels of inheritances } +\label{fig:sixth} +\input{drawing6.tex} +\end{figure} + +Finally a remainder: You can combine this features so you can get + several levels and with several sons, but... watch the space! The +piece of paper has its limitations. + +\subsection{ Associations examples} +Well, I got a bit upset when I realize that fact of multiple inheritances, so +associations haven't got so complicated, and in fact , you can +do only associations between simple classes and associations, + so you can't mix associations and derivations, that would have been +fine. figure~\ref{fig:seventh} + +\begin{figure} +%\vspace{3in} +\caption{Simple association } +\label{fig:seventh} +\input{drawing7.tex} +\end{figure} + + +\subsection{Aggregations too!} + +You can do aggregations, just replace ``derivation'' in the +previous examples for ``agregation'' and that's all. As example look +at figure ~\ref{fig:eighth}. + +\begin{figure} +%\vspace{3in} +\caption{Multiple aggregation } +\label{fig:eighth} +\input{drawing8.tex} +\end{figure} + +\section{ Caveats and bugs} +If you want to do very complex drawings as: +\begin{itemize} +\item several levels of inheritances/agregations and each other +with lots of sons, +\item really deep trees of inheritances, more than four are probably +a really bad idea, +\item several nested associations, +\end{itemize} +then, probably you'll get a shit as outcome. This utility is not +clever, just try to to set the classes in a logical, predetermined +way. + +Apart from this caveat, there'll be some bugs, \ldots, or perhaps not. python is rather robust! + +\section{Bye bye} +I hope this documentation helps you to use this utility. It's not +difficult and greatly profitable. +And if you want to get similar drawings or improve some of them +just take a look at the code, once you get accostumed to it , you'll +find it quite logical. + +\end{document} diff --git a/support/consdiag/drawing1.tex b/support/consdiag/drawing1.tex new file mode 100644 index 0000000000..71046597e0 --- /dev/null +++ b/support/consdiag/drawing1.tex @@ -0,0 +1,22 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { enterprise } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { benefits } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \htext(0.5 -15.7 ) { under\_score. } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \move(0 -2.4 )\rlvec(11.8181818182 0 ) \move(0 0 )\rlvec( 5.90909090909 0) +\rlvec( 5.90909090909 0) +\rlvec(0 -11 ) +\rlvec(0 -11 ) +\rlvec( -5.90909090909 0) +\rlvec( -5.90909090909 0) +\rlvec(0 11 ) +\rlvec(0 11 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing2.tex b/support/consdiag/drawing2.tex new file mode 100644 index 0000000000..f3b58520c7 --- /dev/null +++ b/support/consdiag/drawing2.tex @@ -0,0 +1,24 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { person } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { sex } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \htext(0.5 -15.7 ) { opinion about latest polls } + \htext(0.5 -17.4 ) { position when playing soccer } + \htext(0.5 -19.1 ) { favourite scripting language } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \move(0 -2.4 )\rlvec(25.4545454545 0 ) \move(0 0 )\rlvec( 12.7272727273 0) +\rlvec( 12.7272727273 0) +\rlvec(0 -13 ) +\rlvec(0 -13 ) +\rlvec( -12.7272727273 0) +\rlvec( -12.7272727273 0) +\rlvec(0 13 ) +\rlvec(0 13 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing3.tex b/support/consdiag/drawing3.tex new file mode 100644 index 0000000000..7653189a40 --- /dev/null +++ b/support/consdiag/drawing3.tex @@ -0,0 +1,26 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { person } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { sex } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -20.0 ) { dream } + \htext(0.5 -21.6 ) { love } + \htext(0.5 -23.2 ) { play soccer } + \htext(0.5 -24.8 ) { diving } + \move(0 -2.4 )\rlvec(10.0 0 ) \move(0 0 ) \move(0 -17.4 )\rlvec(10.0 0 ) \move(0 0 )\rlvec( 5.0 0) +\rlvec( 5.0 0) +\rlvec(0 -14 ) +\rlvec(0 -14 ) + \rmove(-3.5 0 )\rlvec (3.5 3.5) \rlvec (-3.5 -3.5) \rmove(3.5 0 ) \rmove(-2.5 1 )\rlvec (0 0) \htext { 3 } + \rmove(2.5 -1 )\rlvec( -5.0 0) +\rlvec( -5.0 0) +\rlvec(0 14 ) +\rlvec(0 14 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing4.tex b/support/consdiag/drawing4.tex new file mode 100644 index 0000000000..204967e400 --- /dev/null +++ b/support/consdiag/drawing4.tex @@ -0,0 +1,51 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { person } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { sex } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -20.0 ) { dream } + \htext(0.5 -21.6 ) { love } + \htext(0.5 -23.2 ) { play soccer } + \htext(0.5 -24.8 ) { diving } + \move(0 -2.4 )\rlvec(10.0 0 ) \move(0 0 ) \move(0 -17.4 )\rlvec(10.0 0 ) \move(0 0 )\rlvec( 5.0 0) +\rlvec( 5.0 0) +\rlvec(0 -14 ) +\rlvec(0 -14 ) +\rlvec( -5.0 0) +\rlvec( -5.0 0) +\rlvec(0 14 ) +\rlvec(0 14 ) + \move(5.0 -28 )\rlvec(0 -7 ) +\rlvec( 1 -1) +\rlvec( -2 0) +\rlvec( 1 1) +\rlvec( -1 -1) +\rlvec( -12 0) +\rlvec(0 -2 ) + \move(-11.0 -38 )\rlvec(0 0) \textref h:L v:C \htext(-10.5 -39 ) { work } + \move(-11.0 -38 )\rlvec(0 0) \textref h:L v:C \htext(-10.5 -43.5 ) { salary } + \htext(-10.5 -45.2 ) { post } + \htext(-10.5 -46.9 ) { labor union } + \htext(-10.5 -48.6 ) { productivity } + \htext(-10.5 -50.3 ) { qualifications } + \htext(-10.5 -52.0 ) { capabilities } + \move(-11.0 -38 )\rlvec(0 0) \textref h:L v:C \htext(-10.5 -58.0 ) { work } + \htext(-10.5 -59.6 ) { strike } + \htext(-10.5 -61.2 ) { be ill } + \htext(-10.5 -62.8 ) { be fired } + \move(-11.0 -40.4 )\rlvec(12.7272727273 0 ) \move(-11.0 -38 ) \move(-11.0 -55.4 )\rlvec(12.7272727273 0 ) \move(-11.0 -38 )\rlvec( 6.36363636364 0) +\rlvec( 6.36363636364 0) +\rlvec(0 -14 ) +\rlvec(0 -14 ) +\rlvec( -6.36363636364 0) +\rlvec( -6.36363636364 0) +\rlvec(0 14 ) +\rlvec(0 14 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing5.tex b/support/consdiag/drawing5.tex new file mode 100644 index 0000000000..d3fbf860db --- /dev/null +++ b/support/consdiag/drawing5.tex @@ -0,0 +1,77 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { person } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { sex } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \move(0 -2.4 )\rlvec(6.36363636364 0 ) \move(0 0 )\rlvec( 3.18181818182 0) +\rlvec( 3.18181818182 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -3.18181818182 0) +\rlvec( -3.18181818182 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(3.18181818182 -20 )\rlvec(0 -7 ) +\rlvec( 1 -1) +\rlvec( -2 0) +\rlvec( 1 1) +\rlvec( -1 -1) +\rlvec( -12 0) +\rlvec(0 -2 ) + \move(-12.8181818182 -30 )\rlvec(0 0) \textref h:L v:C \htext(-12.3181818182 -31 ) { worker } + \move(-12.8181818182 -30 )\rlvec(0 0) \textref h:L v:C \htext(-12.3181818182 -35.5 ) { salary } + \htext(-12.3181818182 -37.2 ) { post } + \htext(-12.3181818182 -38.9 ) { labor union } + \htext(-12.3181818182 -40.6 ) { productivity } + \htext(-12.3181818182 -42.3 ) { qualifications } + \htext(-12.3181818182 -44.0 ) { capabilities } + \move(-12.8181818182 -30 )\rlvec(0 0) \textref h:L v:C \move(-12.8181818182 -32.4 )\rlvec(12.7272727273 0 ) \move(-12.8181818182 -30 )\rlvec( 6.36363636364 0) +\rlvec( 6.36363636364 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -6.36363636364 0) +\rlvec( -6.36363636364 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(4.18181818182 -28 )\rlvec( 11.5454545455 0) +\rlvec(0 -2 ) + \move(12.7272727273 -30 )\rlvec(0 0) \textref h:L v:C \htext(13.2272727273 -31 ) { father } + \move(12.7272727273 -30 )\rlvec(0 0) \textref h:L v:C \htext(13.2272727273 -35.5 ) { busy } + \htext(13.2272727273 -37.2 ) { tenderness } + \htext(13.2272727273 -38.9 ) { stubornness } + \htext(13.2272727273 -40.6 ) { caress } + \htext(13.2272727273 -42.3 ) { kisses } + \htext(13.2272727273 -44.0 ) { capabilities } + \move(12.7272727273 -30 )\rlvec(0 0) \textref h:L v:C \move(12.7272727273 -32.4 )\rlvec(10.9090909091 0 ) \move(12.7272727273 -30 )\rlvec( 5.45454545455 0) +\rlvec( 5.45454545455 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -5.45454545455 0) +\rlvec( -5.45454545455 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(15.7272727273 -28 )\rlvec( 12.9090909091 0) +\rlvec(0 -2 ) + \move(25.6363636364 -30 )\rlvec(0 0) \textref h:L v:C \htext(26.1363636364 -31 ) { chess player } + \move(25.6363636364 -30 )\rlvec(0 0) \textref h:L v:C \htext(26.1363636364 -35.5 ) { elo } + \htext(26.1363636364 -37.2 ) { cruelty } + \htext(26.1363636364 -38.9 ) { stubornness } + \htext(26.1363636364 -40.6 ) { bad tricks } + \htext(26.1363636364 -42.3 ) { intelligence } + \htext(26.1363636364 -44.0 ) { openings knowledge } + \move(25.6363636364 -30 )\rlvec(0 0) \textref h:L v:C \move(25.6363636364 -32.4 )\rlvec(16.3636363636 0 ) \move(25.6363636364 -30 )\rlvec( 8.18181818182 0) +\rlvec( 8.18181818182 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -8.18181818182 0) +\rlvec( -8.18181818182 0) +\rlvec(0 10 ) +\rlvec(0 10 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing6.tex b/support/consdiag/drawing6.tex new file mode 100644 index 0000000000..2dfebb6dec --- /dev/null +++ b/support/consdiag/drawing6.tex @@ -0,0 +1,64 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { person } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { sex } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \move(0 -2.4 )\rlvec(6.36363636364 0 ) \move(0 0 )\rlvec( 3.18181818182 0) +\rlvec( 3.18181818182 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -3.18181818182 0) +\rlvec( -3.18181818182 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(3.18181818182 -20 )\rlvec(0 -7 ) +\rlvec( 1 -1) +\rlvec( -2 0) +\rlvec( 1 1) +\rlvec( -1 -1) +\rlvec( -12 0) +\rlvec(0 -2 ) + \move(-12.8181818182 -30 )\rlvec(0 0) \textref h:L v:C \htext(-12.3181818182 -31 ) { worker } + \move(-12.8181818182 -30 )\rlvec(0 0) \textref h:L v:C \htext(-12.3181818182 -35.5 ) { salary } + \htext(-12.3181818182 -37.2 ) { post } + \htext(-12.3181818182 -38.9 ) { labor union } + \htext(-12.3181818182 -40.6 ) { productivity } + \htext(-12.3181818182 -42.3 ) { qualifications } + \htext(-12.3181818182 -44.0 ) { capabilities } + \move(-12.8181818182 -30 )\rlvec(0 0) \textref h:L v:C \move(-12.8181818182 -32.4 )\rlvec(12.7272727273 0 ) \move(-12.8181818182 -30 )\rlvec( 6.36363636364 0) +\rlvec( 6.36363636364 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -6.36363636364 0) +\rlvec( -6.36363636364 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(-6.45454545455 -50 )\rlvec(0 -7 ) +\rlvec( 1 -1) +\rlvec( -2 0) +\rlvec( 1 1) +\rlvec( -1 -1) +\rlvec( -12 0) +\rlvec(0 -2 ) + \move(-22.4545454545 -60 )\rlvec(0 0) \textref h:L v:C \htext(-21.9545454545 -61 ) { computer scientist } + \move(-22.4545454545 -60 )\rlvec(0 0) \textref h:L v:C \htext(-21.9545454545 -65.5 ) { languages } + \htext(-21.9545454545 -67.2 ) { preferred OS } + \htext(-21.9545454545 -68.9 ) { preferred editor } + \htext(-21.9545454545 -70.6 ) { hackerism } + \htext(-21.9545454545 -72.3 ) { ATBB } + \move(-22.4545454545 -60 )\rlvec(0 0) \textref h:L v:C \move(-22.4545454545 -62.4 )\rlvec(16.3636363636 0 ) \move(-22.4545454545 -60 )\rlvec( 8.18181818182 0) +\rlvec( 8.18181818182 0) +\rlvec(0 -9 ) +\rlvec(0 -9 ) +\rlvec( -8.18181818182 0) +\rlvec( -8.18181818182 0) +\rlvec(0 9 ) +\rlvec(0 9 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing7.tex b/support/consdiag/drawing7.tex new file mode 100644 index 0000000000..ef17e73ccb --- /dev/null +++ b/support/consdiag/drawing7.tex @@ -0,0 +1,36 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { enterprise } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { profits } + \htext(0.5 -8.9 ) { established } + \htext(0.5 -10.6 ) { fiscal paradises } + \htext(0.5 -12.3 ) { frauds } + \htext(0.5 -14.0 ) { bad tricks } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \move(0 -2.4 )\rlvec(14.5454545455 0 ) \move(0 0 )\rlvec( 7.27272727273 0) +\rlvec( 7.27272727273 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -7.27272727273 0) +\rlvec( -7.27272727273 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(14.5454545455 -10 ) \rmove(0.1 1 )\rlvec (0 0) \htext { 0:n } + \rmove(-0.1 -1 )\rlvec( 9.6 0) + \rmove(-3.9 1 )\rlvec (0 0) \htext { 0:1 } + \rmove(3.9 -1 ) \move(24.1454545455 -6 )\rlvec(0 0) \textref h:L v:C \htext(24.6454545455 -7 ) { worker } + \move(24.1454545455 -6 )\rlvec(0 0) \textref h:L v:C \htext(24.6454545455 -11.5 ) { wage } + \htext(24.6454545455 -13.2 ) { timetable } + \htext(24.6454545455 -14.9 ) { seniority } + \move(24.1454545455 -6 )\rlvec(0 0) \textref h:L v:C \move(24.1454545455 -8.4 )\rlvec(8.18181818182 0 ) \move(24.1454545455 -6 )\rlvec( 4.09090909091 0) +\rlvec( 4.09090909091 0) +\rlvec(0 -7 ) +\rlvec(0 -7 ) +\rlvec( -4.09090909091 0) +\rlvec( -4.09090909091 0) +\rlvec(0 7 ) +\rlvec(0 7 ) +\end{texdraw} +\end{center} diff --git a/support/consdiag/drawing8.tex b/support/consdiag/drawing8.tex new file mode 100644 index 0000000000..fff7ec52c5 --- /dev/null +++ b/support/consdiag/drawing8.tex @@ -0,0 +1,79 @@ +\begin{center} +\begin{texdraw} +\small \drawdim {cm} + \setunitscale 0.2 \linewd 0.02 + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -1 ) { person } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \htext(0.5 -5.5 ) { name } + \htext(0.5 -7.2 ) { sex } + \htext(0.5 -8.9 ) { money } + \htext(0.5 -10.6 ) { health } + \htext(0.5 -12.3 ) { hobbies } + \htext(0.5 -14.0 ) { dreams } + \move(0 0 )\rlvec(0 0) \textref h:L v:C \move(0 -2.4 )\rlvec(6.36363636364 0 ) \move(0 0 )\rlvec( 3.18181818182 0) +\rlvec( 3.18181818182 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -3.18181818182 0) +\rlvec( -3.18181818182 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(3.18181818182 -20 )\rlvec( 1 -1) +\rlvec( -1 -1) +\rlvec( 1 1) +\rlvec( -1 1) +\rlvec( -1 -1) +\rlvec( 1 -1) +\rlvec(0 -5 ) +\rlvec( -6 0) +\rlvec(0 -2 ) + \move(-5.81818181818 -29 )\rlvec(0 0) \textref h:L v:C \htext(-5.31818181818 -30 ) { worker } + \move(-5.81818181818 -29 )\rlvec(0 0) \textref h:L v:C \htext(-5.31818181818 -34.5 ) { salary } + \htext(-5.31818181818 -36.2 ) { post } + \htext(-5.31818181818 -37.9 ) { labor union } + \htext(-5.31818181818 -39.6 ) { productivity } + \htext(-5.31818181818 -41.3 ) { qualifications } + \htext(-5.31818181818 -43.0 ) { capabilities } + \move(-5.81818181818 -29 )\rlvec(0 0) \textref h:L v:C \move(-5.81818181818 -31.4 )\rlvec(12.7272727273 0 ) \move(-5.81818181818 -29 )\rlvec( 6.36363636364 0) +\rlvec( 6.36363636364 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -6.36363636364 0) +\rlvec( -6.36363636364 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(3.18181818182 -27 )\rlvec( 11.5454545455 0) +\rlvec(0 -2 ) + \move(11.7272727273 -29 )\rlvec(0 0) \textref h:L v:C \htext(12.2272727273 -30 ) { father } + \move(11.7272727273 -29 )\rlvec(0 0) \textref h:L v:C \htext(12.2272727273 -34.5 ) { busy } + \htext(12.2272727273 -36.2 ) { tenderness } + \htext(12.2272727273 -37.9 ) { stubornness } + \htext(12.2272727273 -39.6 ) { caress } + \htext(12.2272727273 -41.3 ) { kisses } + \htext(12.2272727273 -43.0 ) { capabilities } + \move(11.7272727273 -29 )\rlvec(0 0) \textref h:L v:C \move(11.7272727273 -31.4 )\rlvec(10.9090909091 0 ) \move(11.7272727273 -29 )\rlvec( 5.45454545455 0) +\rlvec( 5.45454545455 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -5.45454545455 0) +\rlvec( -5.45454545455 0) +\rlvec(0 10 ) +\rlvec(0 10 ) + \move(14.7272727273 -27 )\rlvec( 12.9090909091 0) +\rlvec(0 -2 ) + \move(24.6363636364 -29 )\rlvec(0 0) \textref h:L v:C \htext(25.1363636364 -30 ) { chess player } + \move(24.6363636364 -29 )\rlvec(0 0) \textref h:L v:C \htext(25.1363636364 -34.5 ) { elo } + \htext(25.1363636364 -36.2 ) { cruelty } + \htext(25.1363636364 -37.9 ) { stubornness } + \htext(25.1363636364 -39.6 ) { bad tricks } + \htext(25.1363636364 -41.3 ) { intelligence } + \htext(25.1363636364 -43.0 ) { openings knowledge } + \move(24.6363636364 -29 )\rlvec(0 0) \textref h:L v:C \move(24.6363636364 -31.4 )\rlvec(16.3636363636 0 ) \move(24.6363636364 -29 )\rlvec( 8.18181818182 0) +\rlvec( 8.18181818182 0) +\rlvec(0 -10 ) +\rlvec(0 -10 ) +\rlvec( -8.18181818182 0) +\rlvec( -8.18181818182 0) +\rlvec(0 10 ) +\rlvec(0 10 ) +\end{texdraw} +\end{center} |