]> Softwares of Agnibho - ddstorm.git/blob - ddstorm.py
Added documentation
[ddstorm.git] / ddstorm.py
1 #! /usr/bin/python3
2
3 '''
4 DDStorm is a python application for finding differential diagnosis for
5 a given list of symptoms.
6 '''
7 '''
8 Copyright (c) 2015 Agnibho Mondal
9 All rights reserved
10
11 This file is part of DDStorm.
12
13 DDStorm is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 DDStorm is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with DDStorm. If not, see <http://www.gnu.org/licenses/>.
25 '''
26
27 import sys
28 import os
29
30 from compile import Compile
31 from conf import Conf
32 from index import Index
33
34 class DDStorm:
35 ''' Provides the class for finding differential diagnosis. '''
36 conf=False
37
38 def __init__(self, comp=False, conf=False):
39 '''
40 Initiate the diagnosis finder.
41
42 Parameters:
43 comp - Recompiles the data files if set to True
44 conf - Supply a Conf object
45 '''
46 if(conf):
47 self.conf=conf
48 else:
49 self.conf=Conf()
50 self.compiler=Compile(conf)
51 if(comp):
52 self.compiler.compile()
53 self.index=Index(conf)
54
55 def dd(self, symptoms):
56 '''
57 Find the differential diagnosis list.
58
59 Parameter:
60 symptom - list of strings containing symptoms
61
62 Return value:
63 List of strings containing the differential diagnosis
64 '''
65
66 # Return empty list if symptom list is empty
67 if(not symptoms):
68 return
69
70 # Find DD of first symptom and discard it
71 diff1=self._getDiff(symptoms.pop(0))
72
73 # Loop through the rest of the list
74 for s in symptoms:
75
76 # Find DD of the current item in the list
77 diff2=self._getDiff(s)
78
79 # List for temporary holding the DDs
80 temp=[]
81
82 # Make both lists the same length by appending empty strings to the end
83 if(len(diff1)>len(diff2)):
84 diff2+=[""]*(len(diff1)-len(diff2))
85 elif(len(diff2)>len(diff1)):
86 diff1+=[""]*(len(diff2)-len(diff1))
87
88 # Loop over both lists
89 for (s1, s2) in zip(diff1, diff2):
90
91 # Add s1 to temp if s1 or any of its upstream ancestor is common to both list
92 if((s1 not in temp) and (len(s1)>0)):
93 if(s1 in diff2):
94 temp.append(s1)
95 else:
96 us=self.index.upstream(s1)
97 for i in us:
98 if(i in diff2):
99 temp.append(i)
100
101 # Add s2 to temp if s2 or any of its upstream ancestor is common to both list
102 if((s2 not in temp) and (len(s2)>0)):
103 if(s2 in diff1):
104 temp.append(s2)
105 else:
106 us=self.index.upstream(s2)
107 for i in us:
108 if(i in diff1):
109 temp.append(i)
110
111 # Copy temp to first list
112 diff1=list(temp)
113
114 return diff1
115
116 def _getDiff(self, symptom):
117 ''' Return differential diagnosis for a single symptom '''
118 diff=[]
119 symptom=symptom.lower().replace("_"," ").replace("-", " ")
120 if(os.path.isfile(self.conf.get("module_path")+symptom+".module")):
121 with open(self.conf.get("module_path")+symptom+".module", "r") as mf:
122 for line in mf:
123 diff.append(line.strip())
124 return diff
125
126 def symptoms(self):
127 '''
128 Return a full list of available symptoms
129
130 Return value:
131 List of string containing symptoms
132 '''
133 symp=[]
134 for n in os.listdir(self.conf.get("module_path")):
135 symp.append(os.path.splitext(os.path.basename(n))[0].capitalize())
136 return symp
137
138 def main():
139 '''
140 Find differential diagnosis in command line mode.
141 Accepts symptoms as command line arguments. Prints a list of
142 avialable symptoms if called without any argument.
143
144 Command line arguments:
145 A list of symptoms separated by space
146 '''
147 s=DDStorm()
148 if(len(sys.argv)>1):
149 for d in s.dd(sys.argv[1:]):
150 print(d)
151 else:
152 for s in s.symptoms():
153 print(s)
154
155 if(__name__=="__main__"):
156 main()