Проектирование АИС. С аратовский госуниверситет м еханико математический факультет проектирование информационных систем Составил
Скачать 3.17 Mb.
|
except db.DatabaseError, x: 120 print x 121 conn. rollback () 122 else: 123 conn. commit () 124 125 sql = """ 126 SELECT 127 кодТелефонаТип, 128 название 129 FROM 130 ТелефоновТипы""" 131 telephoneTypes = {} 132 try: 133 curs. execute (sql) 134 for rec in curs. fetchall (): 135 telephoneTypes[rec[ 0 ]] = telephonedir. TelephoneType (rec[ 1 ]) 136 except db.DatabaseError, x: 137 print x 138 conn. rollback () 139 else: 140 conn. commit () 141 142 sql = """ 143 SELECT 144 кодТелефона, 145 кодТелефонаТип, 146 номер 147 FROM 148 Телефоны""" 149 telephones = {} 150 try: 151 curs. execute (sql) 152 for rec in curs. fetchall (): 153 telephones[rec[ 0 ]] = telephonedir. Telephone (rec[ 2 ], telephoneTypes[rec[ 1 ]]) 154 except db.DatabaseError, x: 155 print x 156 conn. rollback () 157 else: 158 conn. commit () 159 160 telephoneDir = telephonedir. TelephoneDir (telephonedir. Telephones (telephonedir. TelephoneTypes ()), subdivision) 161 for t in telephoneTypes. itervalues (): 162 telephoneDir.telephones.telephoneTypes. add (t) 163 for t in telephones. itervalues (): 164 telephoneDir.telephones. add (t) 165 166 sql = """ 167 SELECT 168 кодТелефона, 169 кодСотрудника 170 FROM 171 ТелефонныйСправочник""" 172 try: 173 curs. execute (sql) 174 for rec in curs. fetchall (): 175 telephoneDir. add (telephonedir. TelephoneRecord (telephones[rec[ 0 ]], collaborators[rec[ 1 ]])) 176 except db.DatabaseError, x: 177 print x 178 conn. rollback () 179 else: 180 conn. commit () 181 182 closeConn (db, conn, curs) 183 184 return telephoneDir XML Структура XML файла представлена ниже Т елефон кодТелефона номер Т елефоны t elephonedir1 Запись Т елефонаТ ип кодТелефонаТип название Т елефоновТ ипы Сот рудник кодСотрудника фамилия имя отчество Подразделение название Т елефонныйСправочник Для заполнения файла telephonedir.xml можно применять kxmleditor. Для усвоения материала необходимо ознакомится с 7 лекцией “Учебный курс - Язык программи- рования Python” [ 10 ] Сузи Романа Арвиевича. Сузи Романа Арвиевича. При чтении из файла telephonedir.xml функция load из файла tdxml.py использует технологию SAX, а при сохранении в XML функция save технологию DOM. Web Модуль tdweb.py предоставляет web-интерфейс для быстрого поиска по подразделениям, сотруд- никам и телефонам. Командная строка для запуска:python tdweb.py Просмотр на своем компьютере http://localhost:8080. Просмотр на удаленном компьютере http://"ip адрес":8080 Для выключения web-сервера необходимо нажать в консоли запуска "Ctrl-C"или перегрузить/вы- ключить компьютер. Web-справочник базируется на двух дополнительных модулей языка Python: Cheetah и CherryPy. Файл index.tmpl представляет собой шаблон основной html-страницы. Это страница в коде html содержит передаваемые шаблону переменные начинаюшиеся со знака $ или внутри конструкций $() или ${}. Управляющие конструкции начинаются с #. 1 #encoding utf- 8 2 < html> 3 < head><meta http-equiv=’Content-Type’ content=’text/html; charset=utf- 8 ’ > 4 < title>Телефоный справочник</title> 5 < link rel=stylesheet type=text/css href=’/style.css’> 6 < /head> 7 < body> 8 < hr size= 1 color=# 000066 > 9 < p>Телефонных номеров: <b>${len($telephoneDir)}</b></p> 10 < form action=’/index’ method=get> 11 < table cellspacing= 8 cellpadding= 0 > 12 < tr> 13 < td align=center> 14 По подразделению 15 < /td> 16 < td align=center> 17 По сотруднику 18 < /td> 19 < td align=center> 20 По номеру 21 < /td> 22 < td align=center> 23 По типу 24 < /td> 25 < td align=center rowspan= 2 valign=bottom > 26 < input type=submit value = "Задать фильтр" > 27 < /td> 28 < /tr> 29 < tr> 30 < td align=center> 31 < select name=subdivision class=inp> 32 #if $subdivision == ’ 0 ’ 33 < option value=’ 0 ’ selected >все< /option> 34 #else 35 < option value=’ 0 ’ >все< /option> 36 #end if 37 #for $i in range( 1 , len($subdivisions)) 38 #if $i == $subdivision 39 < option value=’$i’ selected>$(subdivisions[$i].name)</option> 40 #else 41 < option value=’$i’>$(subdivisions[$i].name)</option> 42 #end if 43 #end for 44 < /select> 45 < /td> 46 < td align=center> 47 < input class=inp type=text name=collaborator value=’${collaborator}’ size= 12 maxlength= 13 > 48 < /td> 49 < td align=center> 50 < input class=inp type=text name=number value=’${number}’ size= 12 maxlength= 13 > 51 < /td> 52 < td align=center> 53 < select name=telephoneType class=inp> 54 #if $telephoneType == ’ 0 ’ 55 < option value=’ 0 ’ selected >все< /option> 56 #else 57 < option value=’ 0 ’ >все< /option> 58 #end if 59 #for $i in range( 1 , len($telephoneTypes)) 60 #if $i == $telephoneType 61 < option value=’$i’ selected>$(telephoneTypes[$i].name)</option> 62 #else 63 < option value=’$i’>$(telephoneTypes[$i].name)</option> 64 #end if 65 #end for 66 < /select> 67 < /tr> 68 < /table> 69 < /form> 70 71 #set $pageSize = 20 72 < table border= 0 cellspacing= 1 cellpadding= 2 > 73 < tr class=rowhead align=center> 74 < td align=center rowspan= 2 >< b>#</b></td> 75 < td align=center rowspan= 2 >< b>ФИО</b></td> 76 < td align=center colspan= 2 >< b>Телефон</b></td> 77 < /tr> 78 < tr class=rowhead align=center> 79 < td align=center><b>Номер</b></td> 80 < td align=center><b>Тип</b></td> 81 < /tr> 82 #set $r= 2 83 #for i in range($page*$pageSize, min(($page+ 1 )*$pageSize, len($telephoneDir))) 84 < tr class=row${r}> 85 < td align=right>${i+ 1 } < /td> 86 < td align=left>${telephoneDir[i].collaborator}</td> 87 < td align=left>${telephoneDir[i].telephone.number}</td> 88 < td align=center>${telephoneDir[i].telephone.type.name}</td> 89 < /tr> 90 #if $r == 1 91 #set $r = 2 92 #else 93 #set $r = 1 94 #end if 95 #end for 96 < /table> 97 98 #if $page == 0 99 #set $prevPage = "Предыдушая страница" 100 #else 101 #set $prevPage = " >Предыдушая страница " % \ 102 ($page - 1 , $subdivision, $collaborator, $number, $telephoneType) 103 #end if 104 #if ($page + 1 )*$pageSize >= len($telephoneDir) 105 #set $nextPage = "Следующая страница" 106 #else 107 #set $nextPage = " >Следующая страница " % \ 108 ($page + 1 , $subdivision, $collaborator, $number, $telephoneType) 109 #end if 110 < br>${prevPage} | ${nextPage} 111 < p><hr size= 1 color=# 000066 >< a href = "/" >вернутся на главную страницу< /a> 112 < /body> 113 < /html> В модуле tdweb.py на строке 21 описан декоратор cherrypy.expose, показывающий что сле- дующая функция будет представлять собой страницу на сайте с аргументами соответствующими входным переменным функции. 1 # -*- coding: utf-8 -*- 2 3 """ 4 Web интерфейс телефонной книги 5 """ 6 7 import os 8 from Cheetah.Template import Template 9 import cherrypy 10 11 class Root: 12 @ staticmethod 13 def prepare (telephoneDir): 14 Root.collaborators = list ( sorted (telephoneDir.subdivision)) 15 Root.subdivisions = list ( sorted (telephoneDir.subdivision. iterSubdivision ())) 16 Root.subdivisions. insert ( 0 , ’все’ ) 17 Root.telephoneTypes = list ( sorted (telephoneDir.telephones.telephoneTypes)) 18 Root.telephoneTypes. insert ( 0 , ’все’ ) 19 Root.telephoneDir = list ( sorted (telephoneDir)) 20 21 @cherrypy.expose 22 def index (self, page= ’0’ , subdivision= ’0’ , collaborator= ’’ , number= ’’ , telephoneType= ’0’ ): 23 page = int (page) 24 subdivision = int (subdivision) 25 telephoneType = int (telephoneType) ODF Экспорт данных в модуле tdods.py в формате ods 3 очень похож на сохранения данных в формате CSV. Для экспорта используется модуль odf языка Python, а точнее набор функций и классов описанных ниже в строках 3–6. 1 # -*- coding: utf-8 -*- 2 3 from odf.opendocument import OpenDocumentSpreadsheet 4 from odf.style import Style, TextProperties, ParagraphProperties, TableColumnProperties 5 from odf.text import P 6 from odf.table import Table, TableColumn, TableRow, TableCell Сохранение запроса в формате odt 4 в модуле tdodt.py с точки зрения запроса похож на разра- ботанный модуль tdweb.py , а в смысле сохранения на предедущий tdods.py 3 ODF документ “электронная таблица” с расширением ods 4 ODF документ “текстовый документ” с расширением odt 0.2.3 Развитие постановки задачи Диаграмма прецедентов остается без изменений. Диаграмму классов лучше разбить на две. « d a t a t y p e » s e t G r o u p s T e l e p h o n e T y p e s T e l e p h o n e s S u i t e a d d ( ) T e l e p h o n e T y p e n a m e _ _ h a s h _ _ ( ) _ _ e q _ _ ( ) G r o u p n a m e _ _ h a s h _ _ ( ) _ _ e q _ _ ( ) C o l l a b o r a t o r s C o l l a b o r a t o r c o d e f a m i l y n a m e p a t r o n y m _ _ h a s h _ _ ( ) _ _ e q _ _ ( ) T e l e p h o n e n u m b e r t y p e _ _ h a s h _ _ ( ) _ _ e q _ _ ( ) Поскольку сотрудники могут одновременно входить в разные подразделения, заменим Subdivision на Group. Также Subdivision образовывали иерархическую структуру, а Group нет, поэтому для организации хранения введем множество групп Groups. Из предыдущего решения задачи видно, что Collaborators, TelephoneTypes, Telephones и теперь и Groups обладают общими свойствами и поведением, а именно все они множества с запретом на добавление элемента если он уже там есть. Поэтому они могут быть порождены от общего класса Suite (Набор), который в свою очередь порожден от стандартного типа языка Python set. Атрибуты и операции классов уже описаны в предыдущей задаче. T e l e p h o n e D i r t e l e p h o n e s : i n t c o l l a b o r a t o r s : i n t g r o u p s : i n t + a d d ( ) « d a t a t y p e » s e t T e l e p h o n e s T e l e p h o n e n u m b e r : i n t t y p e : i n t + _ _ h a s h _ _ ( ) + _ _ e q _ _ ( ) G r o u p s T e l e p h o n e T y p e s T e l e p h o n e T y p e n a m e : i n t + _ _ h a s h _ _ ( ) + _ _ e q _ _ ( ) G r o u p n a m e : i n t + _ _ h a s h _ _ ( ) + _ _ e q _ _ ( ) C o l l a b o r a t o r s C o l l a b o r a t o r c o d e : i n t f a m i l y : i n t n a m e : i n t p a t r o n y m : i n t + _ _ h a s h _ _ ( ) + _ _ e q _ _ ( ) T e l e p h o n e R e c o r d t e l e p h o n e : i n t c o l l a b o r a t o r : i n t g r o u p : i n t + _ _ h a s h _ _ ( ) + _ _ e q _ _ ( ) Объектная модель и её реализация Изменения, по сравнению с предыдущей задачей, коснулись в основном классов TelephoneRecord, TelephoneDir. Это связано с тем, что теперь запись в телефоном справочнике представляет собой набор из телефона, сотрудника и группы. Соответственно TelephoneDir содержит Telephones, Collaborators и Groups. 1 # -*- coding: utf-8 -*- 2 3 """ 4 Телефонная книга организации 5 """ 6 7 class Suite ( set ): 8 """ 9 Множество с запретом на добавление элементов 10 уже содержащихся в нём 11 """ 12 def add (self, elt): 13 assert elt not in self 14 set add (self, elt) 15 16 class Collaborator: 17 """ 18 Сотрудник 19 """ 20 def __init__ (self, code, family, name, patronym): 21 self.code = code 22 self.family = family 23 self.name = name 24 self.patronym = patronym 25 26 def __hash__ (self): 27 return hash (self.code) 28 29 def __eq__ (self, other): 30 return self.code == other.code 31 32 class Collaborators (Suite): 33 """ 34 Сотрудники 35 """ 36 pass 37 38 class Group: 39 """ 40 Группа сотрудников 41 """ 42 def __init__ (self, name): 43 self.name = name 44 45 def __hash__ (self): 46 return hash (self.name) 47 48 def __eq__ (self, other): 49 return self.name == other.name 50 51 class Groups (Suite): 52 """ 53 Группы 54 """ 55 pass 56 57 class TelephoneType: 58 """ 59 Тип телефона 60 """ 61 def __init__ (self, name): 62 self.name = name 63 64 def __hash__ (self): 65 return hash (self.name) 66 67 def __eq__ (self, other): 68 return self.name == other.name 69 70 class TelephoneTypes (Suite): 71 """ 72 Типы телефонов 73 """ 74 pass 75 76 class Telephone: 77 """ 78 Телефон 79 """ 80 def __init__ (self, telephone, telephoneType): 81 self.number = telephone 82 self. type = telephoneType 83 84 def __hash__ (self): 85 return hash (self.number) 86 87 def __eq__ (self, other): 88 return self.number == other.number 89 90 class Telephones ( set ): 91 """ 92 Телефоны 93 """ 94 def __init__ (self, telephoneTypes): 95 set __init__ (self) 96 self.telephoneTypes = telephoneTypes 97 98 def add (self, telephone): 99 assert telephone not in self 100 assert telephone. type in self.telephoneTypes 101 set add (self, telephone) |