comparison V5/synastry.py @ 23:11d4e438045e

make version 5
author DaveM
date Mon, 09 Apr 2018 15:07:21 +0100
parents
children d2bd074d9284
comparison
equal deleted inserted replaced
22:a5b8e2b91d8f 23:11d4e438045e
1 import random
2 import csv
3 import re
4 import requests
5 import time
6 from bs4 import BeautifulSoup
7
8 import pdb
9
10 class compatibility:
11 def __init__(self):
12 self.rules = []
13 self.uniqueID = 0
14 print 'Warning, need to fix [Vertex, Ascendant House, South Node, IC/MC and None Location] issues'
15
16 def addRule(self,planetTuple,aspectList,score):
17 rule = compatibilityRule(self.uniqueID,planetTuple,aspectList,score)
18 self.rules.append(rule)
19 self.uniqueID += 1
20
21 def findRule(self,planet):
22 ruleList = [r for r in self.rules if r.planet == planet]
23 print ruleList
24 return ruleList
25
26 def readFile(self,filename):
27 text = []
28 with open(filename) as fp:
29 line = fp.readline()
30 text.append(line.strip())
31 while line:
32 line = fp.readline()
33 text.append(line.strip())
34 return text
35
36 def parseCompatRules(self,filename):
37 comList = self.readFile(filename)
38 for com in comList:
39 # print com
40 planetTuple = None
41 aspectList = None
42 score = None
43 c = com.split(',')
44 if len(c) == 4:
45 if len(c[1]) > 1:
46 aspectList = []
47 planetTuple = tuple((c[0].lower(),c[2].lower()))
48 score = int(c[3])
49 for subset in c[1].lower().split(' '):
50 aspectList.append(subset)
51 elif len(c[1]) == 0 :
52 if 'house' not in c[2]:
53 print 'some error where rule is not house'
54 planetTuple = (c[0].lower(),'house')
55 houseNo = re.findall('\d+', c[2])
56 if len(houseNo) != 1:
57 print 'multiple house numbers found - ERROR'
58 aspectList = int(houseNo[0])
59 score = int(c[3])
60 self.addRule(planetTuple,aspectList,score)
61
62 def calcCompatibility(self, horiscope):
63 score = 0
64 for r in sorted(self.rules):
65 if 'vertex' in r.planet:
66 # print 'ERROR - catch Vertex issue'
67 pass
68 elif 'southnode' in r.planet:
69 # print 'ERROR - catch South Node issue'
70 pass
71 elif 'ic/mc' in r.planet:
72 # print 'ERROR - catch IC/MC issue'
73 pass
74 elif r.planet[1] == 'house' and r.planet[0] == 'asc':
75 # print 'ERROR - catch Ascendant House issue'
76 pass
77 elif horiscope.planets[r.planet[0]].angleA is None:
78 # print 'Error - None Location'
79 return None
80 elif r.planet[1] == 'house':
81 if horiscope.isInHouse(r.planet[0],r.aspect):
82 score += r.score
83 print r.planet[0] +' '+ r.planet[1] +' '+ str(aspect)+' '+str(r.score)
84 elif r.planet[0] == r.planet[1]:
85 aspect,variance = horiscope.calcAspect(r.planet[0],r.planet[1])
86 if aspect is not None:
87 if aspect in r.aspect:
88 score += r.score
89 print r.planet[0]+' '+aspect +' '+ r.planet[1] +' '+ str(r.score)
90 else:
91 for order in [0,1]:
92 aspect,variance = horiscope.calcAspect(r.planet[order],r.planet[not order])
93 if aspect is not None:
94 # print aspect
95 # currentR = r
96 # pdb.set_trace()
97 if aspect in r.aspect:
98 score += r.score
99 print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' '+ str(r.score)
100 else:
101 print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' 0'
102 print score
103 return score
104
105
106
107
108 class compatibilityRule:
109 def __init__(self,uniqueId,planetTuple,aspectList,score):
110 self.id = uniqueId
111 self.planet = planetTuple
112 self.aspect = aspectList
113 self.score = score
114
115
116 class Person:
117 url = 'https://horoscopes.astro-seek.com/calculate-love-compatibility/'
118 def __init__(self,personDict):
119 # self. = planetPositions()
120 self.id = personDict['ID']
121 self.dob = personDict['DOB']
122 self.tob = personDict['TOB']
123 self.cob = personDict['COB']
124 self.p_dob = personDict['pDOB']
125 self.p_tob = personDict['pTOB']
126 self.p_cob = personDict['pCOB']
127 self.horiscope = None
128 self.resp = None
129 self.issue = 'INCOMPLETE'
130
131 def identifyIssues(self):
132 if self.id is None:
133 self.issue = 'id'
134 elif self.dob is None:
135 self.issue = 'dob'
136 elif self.tob is None:
137 self.issue = 'tob'
138 elif self.cob is None:
139 self.issue = 'cob'
140 elif self.p_dob is None:
141 self.issue = 'p_dob'
142 elif self.p_tob is None:
143 self.issue = 'p_tob'
144 elif self.p_cob is None:
145 self.issue = 'p_cob'
146 else:
147 self.issue = None
148 return self.issue
149
150 def makePayload(self):
151 if type(self.cob) is str:
152 cob_0 = float(self.cob.split(',')[0][1:])
153 cob_1 = float(self.cob.split(',')[1])
154 self.cob = (cob_0,cob_1)
155 if type(self.p_cob) is str:
156 pcob_0 = float(self.p_cob.split(',')[0][1:])
157 pcob_1 = float(self.p_cob.split(',')[1])
158 self.p_cob = (pcob_0,pcob_1)
159 if type(self.dob) is str:
160 self.dob = self.dob[1:-1].split(',')
161 if type(self.p_dob) is str:
162 self.p_dob = self.p_dob[1:-1].split(',')
163 if type(self.tob) is str:
164 self.tob = self.tob[1:-1].split(',')
165 if type(self.p_tob) is str:
166 self.p_tob = self.p_tob[1:-1].split(',')
167
168 self.payload = {'send_calculation':'1', #Req
169 'muz_narozeni_den':self.dob[0],
170 'muz_narozeni_mesic':self.dob[1],
171 'muz_narozeni_rok':self.dob[2],
172 'muz_narozeni_hodina':self.tob[0],
173 'muz_narozeni_minuta':self.tob[1],
174 'muz_narozeni_city':'',
175 'muz_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',#auto
176 'muz_narozeni_stat_hidden':'XX',
177 'muz_narozeni_podstat_kratky_hidden':'',
178 'muz_narozeni_podstat_hidden':'',
179 'muz_narozeni_podstat2_kratky_hidden':'',
180 'muz_narozeni_podstat3_kratky_hidden':'',
181 'muz_narozeni_input_hidden':'',
182 'muz_narozeni_sirka_stupne':str(abs(self.cob[0])).split('.')[0],
183 'muz_narozeni_sirka_minuty':str(float('0.'+str(self.cob[0]).split('.')[1])*60).split('.')[0],
184 'muz_narozeni_sirka_smer': '1' if self.cob[0]<0 else '0', #address N Dir (0':'N',1':'S)
185 'muz_narozeni_delka_stupne':str(abs(self.cob[1])).split('.')[0], #address E - Main
186 'muz_narozeni_delka_minuty':str(float('0.'+str(self.cob[1]).split('.')[1])*60).split('.')[0],
187 'muz_narozeni_delka_smer': '1' if self.cob[1]<0 else '0', #address E Dir (0':'E',1':'W)
188 'muz_narozeni_timezone_form':'auto',
189 'muz_narozeni_timezone_dst_form':'auto',
190 'send_calculation':'1',
191 'zena_narozeni_den':self.p_dob[0],
192 'zena_narozeni_mesic':self.p_dob[1],
193 'zena_narozeni_rok':self.p_dob[2],
194 'zena_narozeni_hodina':self.p_tob[0],
195 'zena_narozeni_minuta':self.p_tob[1],
196 'zena_narozeni_city':'',
197 'zena_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',
198 'zena_narozeni_stat_hidden':'XX',
199 'zena_narozeni_podstat_kratky_hidden':'',
200 'zena_narozeni_podstat_hidden':'',
201 'zena_narozeni_podstat2_kratky_hidden':'',
202 'zena_narozeni_podstat3_kratky_hidden':'',
203 'zena_narozeni_input_hidden':'',
204 'zena_narozeni_sirka_stupne':str(abs(self.p_cob[0])).split('.')[0],
205 'zena_narozeni_sirka_minuty':str(float('0.'+str(self.p_cob[0]).split('.')[1])*60).split('.')[0],
206 'zena_narozeni_sirka_smer': '1' if self.p_cob[0]<0 else '0',
207 'zena_narozeni_delka_stupne':str(abs(self.p_cob[1])).split('.')[0],
208 'zena_narozeni_delka_minuty':str(float('0.'+str(self.p_cob[1]).split('.')[1])*60).split('.')[0],
209 'zena_narozeni_delka_smer': '1' if self.p_cob[1]<0 else '0',
210 'zena_narozeni_timezone_form':'auto',
211 'zena_narozeni_timezone_dst_form':'auto',
212 'switch_interpretations':'0',
213 'house_system':'placidus',
214 'uhel_orbis':'#tabs_redraw'}
215
216 def requestURL(self):
217 self.resp = requests.get(self.url, params=self.payload)
218 time.sleep(5)
219 return self.resp
220
221 def parsePage(self):
222 self.horiscope = None
223 if('Please use valid date.' in self.resp.content):
224 self.issue = 'dob'
225 return self.horiscope
226 elif('Please use valid time.' in self.resp.content):
227 self.issue = 'tob'
228 return self.horiscope
229 gotLocation = 0
230 self.horiscope = planetPositions()
231 soup = BeautifulSoup(self.resp.content, 'lxml')
232 tcCell = soup.find_all('div', attrs={'class':'right-sedy-banner-svetlejsi'})
233 for cell in tcCell:
234 if "Planets in partner's house" in cell.get_text():
235 gotLocation = 1
236 divList = cell.find_all('div')
237 for i in range(len(divList)):
238 planetName = divList[i].getText().lower().strip().replace(':','').split(' ')[0]
239 if planetName in planetPositions.planetNames:
240 if gotLocation and not '/' in planetName:
241 self.horiscope.planets[planetName].setHouse(divList[i+2].getText(),divList[i+4].getText())
242 else:
243 self.horiscope.planets[planetName].setLocation(divList[i+2].getText(),divList[i+1].img.attrs['alt'],0)
244 self.horiscope.planets[planetName].setLocation(divList[i+4].getText(),divList[i+3].img.attrs['alt'],1)
245 return self.horiscope
246
247
248
249 class planetRelation:
250 noHouseList = ['asc','ic','dsc','mc','asc/mc','sun/moon']
251 zodiacAngle = {'aries':0,'taurus':30,'gemini':60,'cancer':90,'leo':120,'virgo':150,'libra':180,'scorpio':210,'sagittarius':240,'capricorn':270,'aquarius':300,'pisces':330}
252
253 def __init__(self,planetName):
254 self.name = planetName
255 self.angleA = None
256 self.angleB = None
257 if planetName not in planetRelation.noHouseList:
258 self.houseA = None
259 self.houseB = None
260
261 def setLocation(self,value,sign,isB):
262 signVal = planetRelation.zodiacAngle[sign.lower()]
263 signVal+= float('.'.join(value.encode('ascii','replace').split('?'))[:-1])
264 # print self.name,sign.lower(),planetRelation.zodiacAngle[sign.lower()],value,signVal
265 if not isB:
266 self.angleA = signVal
267 else:
268 self.angleB = signVal
269
270 def setHouse(self,A,B):
271 self.houseA = int(A.encode('ascii','ignore'))
272 self.houseB = int(B.encode('ascii','ignore'))
273
274 def test_random(self):
275 self.angleA = random.random()*360
276 self.angleB = random.random()*360
277
278
279 class planetPositions:
280 aspectDict = {'conjunction':0,'semi-square':45,'sextile':60,'square':90,'trine':120,'opposition':180}
281 # zodiacAngle = {'aries':0,'taurus':30,'gemini':60,'cancer':90,'leo':120,'virgo':150,'libra':180,'scorpio':210,'sagittarius':240,'capricorn':270,'aquarius':300,'pisces':330}
282 # Taken from https://en.wikipedia.org/wiki/Astrological_sign, with reference from https://en.wikipedia.org/wiki/Astrological_symbols#Signs_of_the_zodiac
283 planetNames = ['sun','moon','mercury','venus','mars','jupiter','saturn','uranus','neptune','pluto','node','lilith','chiron','asc','ic','dsc','mc','asc/mc','sun/moon']
284 def __init__(self):
285 self.planets = {}
286 for p in planetPositions.planetNames:
287 self.planets[p] = planetRelation(p)
288 self.aspect = {}
289
290 def test_random(self):
291 for planet in self.planets:
292 self.planets[planet].test_random()
293
294 def calcAngle(self,componentA,componentB):
295 print componentA,componentB
296 self.angle = abs(self.planets[componentA].angleA - self.planets[componentB].angleB)
297 self.angleRange = self.angle-10,self.angle+10
298
299 def calcAspect(self,componentA,componentB):
300 self.calcAngle(componentA,componentB)
301 # print componentA,componentB,self.angle,self.planets[componentA].angleA,self.planets[componentB].angleB
302 for aspect in planetPositions.aspectDict:
303 if self.angleRange[0] < planetPositions.aspectDict[aspect] and self.angleRange[1] > planetPositions.aspectDict[aspect]:
304 # print aspect#,componentA,componentB,self.angle
305 aspectDiff = round(abs(self.angle - planetPositions.aspectDict[aspect]),2)
306 self.aspect[componentA,componentB] = (aspect,aspectDiff)
307 print componentA,componentB,self.angle,aspect,aspectDiff
308 return aspect,aspectDiff
309 return None,None
310
311 def isInHouse(self,component,houseNo):
312 # print (self.planets[component].houseA,self.planets[component].houseB,houseNo)
313 if (self.planets[component].houseA == houseNo) or (self.planets[component].houseB == houseNo):
314 return True
315 return False
316
317 def makeAllAspectTreple(self):
318 self.aspectTreple = {}
319 for p1 in planetPositions.planetNames:
320 for p2 in planetPositions.planetNames:
321 aspect = self.calcAspect(p1,p2)[0]
322 if aspect is not None:
323 self.aspectTreple[(p1,p2,aspect)] = 1
324
325 def calcAllAspects(self):
326 for p1 in planetPositions.planetNames:
327 for p2 in planetPositions.planetNames:
328 self.calcAspect(p1,p2)
329
330 def printPositions(self):
331 for p in planetPositions.planetNames:
332 if p in planetRelation.noHouseList:
333 print p,self.planets[p].angleA,self.planets[p].angleB
334 else:
335 print p,self.planets[p].angleA,self.planets[p].angleB,self.planets[p].houseA,self.planets[p].houseB
336
337
338
339
340