diff V5/synastry.py @ 23:11d4e438045e

make version 5
author DaveM
date Mon, 09 Apr 2018 15:07:21 +0100
parents
children d2bd074d9284
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/V5/synastry.py	Mon Apr 09 15:07:21 2018 +0100
@@ -0,0 +1,340 @@
+import random
+import csv
+import re
+import requests
+import time
+from bs4 import BeautifulSoup
+
+import pdb
+
+class compatibility:
+	def __init__(self):
+		self.rules = []
+		self.uniqueID = 0
+		print 'Warning, need to fix [Vertex, Ascendant House, South Node, IC/MC and None Location] issues'
+
+	def addRule(self,planetTuple,aspectList,score):
+		rule = compatibilityRule(self.uniqueID,planetTuple,aspectList,score)
+		self.rules.append(rule)
+		self.uniqueID += 1
+
+	def findRule(self,planet):
+		ruleList = [r for r in self.rules if r.planet == planet]
+		print ruleList
+		return ruleList
+
+	def readFile(self,filename):
+		text = []
+		with open(filename) as fp:
+			line = fp.readline()
+			text.append(line.strip())
+			while line:
+				line = fp.readline()
+				text.append(line.strip())
+		return text	
+
+	def parseCompatRules(self,filename):
+		comList = self.readFile(filename)
+		for com in comList:
+			# print com
+			planetTuple = None
+			aspectList = None
+			score = None
+			c = com.split(',')
+			if len(c) == 4:
+				if len(c[1]) > 1:
+					aspectList = []
+					planetTuple = tuple((c[0].lower(),c[2].lower()))
+					score = int(c[3])
+					for subset in c[1].lower().split(' '):
+						aspectList.append(subset)
+				elif len(c[1]) == 0 :
+					if 'house' not in c[2]:
+						print 'some error where rule is not house'
+					planetTuple = (c[0].lower(),'house')
+					houseNo = re.findall('\d+', c[2])
+					if len(houseNo) != 1:
+						print 'multiple house numbers found - ERROR'
+					aspectList = int(houseNo[0])
+					score = int(c[3])
+				self.addRule(planetTuple,aspectList,score)
+
+	def calcCompatibility(self, horiscope):
+		score = 0
+		for r in sorted(self.rules):
+			if 'vertex' in r.planet:
+				# print 'ERROR - catch Vertex issue'
+				pass
+			elif 'southnode' in r.planet:
+				# print 'ERROR - catch South Node issue'
+				pass
+			elif 'ic/mc' in r.planet:
+				# print 'ERROR - catch IC/MC issue'
+				pass
+			elif r.planet[1]  == 'house' and r.planet[0] == 'asc':
+				# print 'ERROR - catch Ascendant House issue'
+				pass
+			elif horiscope.planets[r.planet[0]].angleA is None:
+				# print 'Error - None Location'
+				return None
+			elif r.planet[1] == 'house':
+				if horiscope.isInHouse(r.planet[0],r.aspect):
+					score += r.score
+					print r.planet[0] +' '+ r.planet[1] +' '+ str(aspect)+' '+str(r.score)
+			elif r.planet[0] == r.planet[1]:
+				aspect,variance = horiscope.calcAspect(r.planet[0],r.planet[1])
+				if aspect is not None:
+					if aspect in r.aspect:
+						score += r.score
+						print r.planet[0]+' '+aspect +' '+ r.planet[1] +' '+ str(r.score)
+			else:
+				for order in [0,1]:
+					aspect,variance = horiscope.calcAspect(r.planet[order],r.planet[not order])
+					if aspect is not None:
+						# print aspect
+						# currentR = r
+						# pdb.set_trace()
+						if aspect in r.aspect:
+							score += r.score
+							print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' '+ str(r.score)
+						else:
+							print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' 0'
+		print score
+		return score
+
+	
+
+
+class compatibilityRule:
+	def __init__(self,uniqueId,planetTuple,aspectList,score):
+		self.id = uniqueId
+		self.planet = planetTuple
+		self.aspect = aspectList
+		self.score = score
+
+
+class Person:
+	url = 'https://horoscopes.astro-seek.com/calculate-love-compatibility/'
+	def __init__(self,personDict):
+		# self. = planetPositions()
+		self.id = personDict['ID']
+		self.dob = personDict['DOB']
+		self.tob = personDict['TOB']
+		self.cob = personDict['COB']
+		self.p_dob = personDict['pDOB']
+		self.p_tob = personDict['pTOB']
+		self.p_cob = personDict['pCOB']
+		self.horiscope = None
+		self.resp = None
+		self.issue = 'INCOMPLETE'
+
+	def identifyIssues(self):
+		if self.id is None:
+			self.issue = 'id'
+		elif self.dob is None:
+			self.issue = 'dob'
+		elif self.tob is None:
+			self.issue = 'tob'
+		elif self.cob is None:
+			self.issue = 'cob'
+		elif self.p_dob is None:
+			self.issue = 'p_dob'
+		elif self.p_tob is None:
+			self.issue = 'p_tob'
+		elif self.p_cob is None:
+			self.issue = 'p_cob'
+		else:
+			self.issue = None
+		return self.issue
+
+	def makePayload(self):
+		if type(self.cob) is str:
+			cob_0 = float(self.cob.split(',')[0][1:])
+			cob_1 = float(self.cob.split(',')[1])
+			self.cob = (cob_0,cob_1)
+		if type(self.p_cob) is str:
+			pcob_0 = float(self.p_cob.split(',')[0][1:])
+			pcob_1 = float(self.p_cob.split(',')[1])
+			self.p_cob = (pcob_0,pcob_1)
+		if type(self.dob) is str:
+			self.dob = self.dob[1:-1].split(',')
+		if type(self.p_dob) is str:
+			self.p_dob = self.p_dob[1:-1].split(',')
+		if type(self.tob) is str:
+			self.tob = self.tob[1:-1].split(',')
+		if type(self.p_tob) is str:
+			self.p_tob = self.p_tob[1:-1].split(',')
+		
+		self.payload = {'send_calculation':'1', #Req
+			'muz_narozeni_den':self.dob[0],
+			'muz_narozeni_mesic':self.dob[1],
+			'muz_narozeni_rok':self.dob[2],
+			'muz_narozeni_hodina':self.tob[0],
+			'muz_narozeni_minuta':self.tob[1],
+			'muz_narozeni_city':'',
+			'muz_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',#auto
+			'muz_narozeni_stat_hidden':'XX',
+			'muz_narozeni_podstat_kratky_hidden':'',
+			'muz_narozeni_podstat_hidden':'',
+			'muz_narozeni_podstat2_kratky_hidden':'',
+			'muz_narozeni_podstat3_kratky_hidden':'',
+			'muz_narozeni_input_hidden':'',
+			'muz_narozeni_sirka_stupne':str(abs(self.cob[0])).split('.')[0],
+			'muz_narozeni_sirka_minuty':str(float('0.'+str(self.cob[0]).split('.')[1])*60).split('.')[0],
+			'muz_narozeni_sirka_smer': '1' if self.cob[0]<0 else '0', #address N Dir (0':'N',1':'S)
+			'muz_narozeni_delka_stupne':str(abs(self.cob[1])).split('.')[0], #address E - Main
+			'muz_narozeni_delka_minuty':str(float('0.'+str(self.cob[1]).split('.')[1])*60).split('.')[0],
+			'muz_narozeni_delka_smer': '1' if self.cob[1]<0 else '0', #address E Dir (0':'E',1':'W)
+			'muz_narozeni_timezone_form':'auto',
+			'muz_narozeni_timezone_dst_form':'auto',
+			'send_calculation':'1',
+			'zena_narozeni_den':self.p_dob[0],
+			'zena_narozeni_mesic':self.p_dob[1],
+			'zena_narozeni_rok':self.p_dob[2],
+			'zena_narozeni_hodina':self.p_tob[0],
+			'zena_narozeni_minuta':self.p_tob[1],
+			'zena_narozeni_city':'',
+			'zena_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',
+			'zena_narozeni_stat_hidden':'XX',
+			'zena_narozeni_podstat_kratky_hidden':'',
+			'zena_narozeni_podstat_hidden':'',
+			'zena_narozeni_podstat2_kratky_hidden':'',
+			'zena_narozeni_podstat3_kratky_hidden':'',
+			'zena_narozeni_input_hidden':'',
+			'zena_narozeni_sirka_stupne':str(abs(self.p_cob[0])).split('.')[0],
+			'zena_narozeni_sirka_minuty':str(float('0.'+str(self.p_cob[0]).split('.')[1])*60).split('.')[0],
+			'zena_narozeni_sirka_smer': '1' if self.p_cob[0]<0 else '0',
+			'zena_narozeni_delka_stupne':str(abs(self.p_cob[1])).split('.')[0],
+			'zena_narozeni_delka_minuty':str(float('0.'+str(self.p_cob[1]).split('.')[1])*60).split('.')[0],
+			'zena_narozeni_delka_smer': '1' if self.p_cob[1]<0 else '0',
+			'zena_narozeni_timezone_form':'auto',
+			'zena_narozeni_timezone_dst_form':'auto',
+			'switch_interpretations':'0',
+			'house_system':'placidus',
+			'uhel_orbis':'#tabs_redraw'}
+
+	def requestURL(self):
+		self.resp = requests.get(self.url, params=self.payload)
+		time.sleep(5)
+		return self.resp
+
+	def parsePage(self):
+		self.horiscope = None
+		if('Please use valid date.' in self.resp.content):
+			self.issue = 'dob'
+			return self.horiscope
+		elif('Please use valid time.' in self.resp.content):
+			self.issue = 'tob'
+			return self.horiscope
+		gotLocation = 0
+		self.horiscope = planetPositions()
+		soup = BeautifulSoup(self.resp.content, 'lxml')
+		tcCell = soup.find_all('div', attrs={'class':'right-sedy-banner-svetlejsi'})
+		for cell in tcCell:
+			if "Planets in partner's house" in cell.get_text():
+				gotLocation = 1
+			divList = cell.find_all('div')
+			for i in range(len(divList)):
+				planetName = divList[i].getText().lower().strip().replace(':','').split(' ')[0]
+				if planetName in planetPositions.planetNames:
+					if gotLocation and not '/' in planetName:
+						self.horiscope.planets[planetName].setHouse(divList[i+2].getText(),divList[i+4].getText())
+					else:
+						self.horiscope.planets[planetName].setLocation(divList[i+2].getText(),divList[i+1].img.attrs['alt'],0)
+						self.horiscope.planets[planetName].setLocation(divList[i+4].getText(),divList[i+3].img.attrs['alt'],1)
+		return self.horiscope
+
+
+
+class planetRelation:
+	noHouseList = ['asc','ic','dsc','mc','asc/mc','sun/moon']
+	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}
+
+	def __init__(self,planetName):
+		self.name = planetName
+		self.angleA = None
+		self.angleB = None
+		if planetName not in planetRelation.noHouseList:
+			self.houseA = None
+			self.houseB = None
+
+	def setLocation(self,value,sign,isB):
+		signVal = planetRelation.zodiacAngle[sign.lower()]
+		signVal+= float('.'.join(value.encode('ascii','replace').split('?'))[:-1])
+		# print self.name,sign.lower(),planetRelation.zodiacAngle[sign.lower()],value,signVal
+		if not isB:
+			self.angleA = signVal
+		else:
+			self.angleB = signVal
+		
+	def setHouse(self,A,B):
+		self.houseA = int(A.encode('ascii','ignore'))
+		self.houseB = int(B.encode('ascii','ignore'))
+
+	def test_random(self):
+		self.angleA = random.random()*360
+		self.angleB = random.random()*360
+
+
+class planetPositions:
+	aspectDict = {'conjunction':0,'semi-square':45,'sextile':60,'square':90,'trine':120,'opposition':180}
+	# 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}
+	# Taken from https://en.wikipedia.org/wiki/Astrological_sign, with reference from https://en.wikipedia.org/wiki/Astrological_symbols#Signs_of_the_zodiac
+	planetNames = ['sun','moon','mercury','venus','mars','jupiter','saturn','uranus','neptune','pluto','node','lilith','chiron','asc','ic','dsc','mc','asc/mc','sun/moon']
+	def __init__(self):
+		self.planets = {}
+		for p in planetPositions.planetNames:
+			self.planets[p] = planetRelation(p)
+		self.aspect = {}
+
+	def test_random(self):
+		for planet in self.planets:
+			self.planets[planet].test_random()
+
+	def calcAngle(self,componentA,componentB):
+		print componentA,componentB
+		self.angle = abs(self.planets[componentA].angleA - self.planets[componentB].angleB)
+		self.angleRange = self.angle-10,self.angle+10
+
+	def calcAspect(self,componentA,componentB):
+		self.calcAngle(componentA,componentB)
+		# print componentA,componentB,self.angle,self.planets[componentA].angleA,self.planets[componentB].angleB
+		for aspect in planetPositions.aspectDict:
+			if self.angleRange[0] < planetPositions.aspectDict[aspect] and self.angleRange[1] > planetPositions.aspectDict[aspect]:
+				# print aspect#,componentA,componentB,self.angle
+				aspectDiff = round(abs(self.angle - planetPositions.aspectDict[aspect]),2)
+				self.aspect[componentA,componentB] = (aspect,aspectDiff)
+				print componentA,componentB,self.angle,aspect,aspectDiff
+				return aspect,aspectDiff
+		return None,None
+
+	def isInHouse(self,component,houseNo):
+		# print (self.planets[component].houseA,self.planets[component].houseB,houseNo)
+		if (self.planets[component].houseA == houseNo) or (self.planets[component].houseB == houseNo):
+			return True
+		return False
+
+	def makeAllAspectTreple(self):
+		self.aspectTreple = {}
+		for p1 in planetPositions.planetNames:
+			for p2 in planetPositions.planetNames:
+				aspect = self.calcAspect(p1,p2)[0]
+				if aspect is not None:
+					self.aspectTreple[(p1,p2,aspect)] = 1
+		
+	def calcAllAspects(self):
+		for p1 in planetPositions.planetNames:
+			for p2 in planetPositions.planetNames:
+				self.calcAspect(p1,p2)
+
+	def printPositions(self):
+		for p in planetPositions.planetNames:
+			if p in planetRelation.noHouseList:
+				print p,self.planets[p].angleA,self.planets[p].angleB
+			else:
+				print p,self.planets[p].angleA,self.planets[p].angleB,self.planets[p].houseA,self.planets[p].houseB
+
+
+
+
+