├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── README.rst ├── contrib └── topical_almuten.py ├── docs ├── Makefile ├── README.md ├── make.bat └── source │ ├── _static │ ├── python-interpreter-osx.png │ ├── python-interpreter-win32.png │ └── xcode-command-line-tools.png │ ├── conf.py │ ├── faq.rst │ ├── index.rst │ ├── installation.rst │ └── tutorials │ ├── chart-properties.rst │ ├── create-chart.rst │ ├── index.rst │ └── intro-python.rst ├── flatlib ├── __init__.py ├── angle.py ├── aspects.py ├── chart.py ├── const.py ├── datetime.py ├── dignities │ ├── __init__.py │ ├── accidental.py │ ├── essential.py │ └── tables.py ├── ephem │ ├── __init__.py │ ├── eph.py │ ├── ephem.py │ ├── swe.py │ └── tools.py ├── geopos.py ├── lists.py ├── object.py ├── predictives │ ├── __init__.py │ ├── primarydirections.py │ ├── profections.py │ └── returns.py ├── props.py ├── protocols │ ├── __init__.py │ ├── almutem.py │ ├── behavior.py │ └── temperament.py ├── resources │ ├── README.md │ └── swefiles │ │ ├── fixstars.cat │ │ ├── seas_12.se1 │ │ ├── seas_18.se1 │ │ ├── seas_24.se1 │ │ ├── sefstars.txt │ │ ├── semo_12.se1 │ │ ├── semo_18.se1 │ │ ├── semo_24.se1 │ │ ├── sepl_12.se1 │ │ ├── sepl_18.se1 │ │ └── sepl_24.se1 ├── tools │ ├── __init__.py │ ├── arabicparts.py │ ├── chartdynamics.py │ └── planetarytime.py └── utils.py ├── recipes ├── README.md ├── accidentaldignities.py ├── almutem.py ├── arabicparts.py ├── aspects.py ├── behavior.py ├── chartdynamics.py ├── eclipses.py ├── essentialdignities.py ├── leapyears.py ├── planetarytime.py ├── primarydirections.py ├── profections.py ├── solarreturn.py ├── solaryears.py └── temperament.py ├── requirements.txt ├── scripts ├── build.py ├── clean.py └── utils.py ├── setup.py └── tests ├── test_angles.py └── test_chart.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse project files 2 | .pydevproject 3 | .project 4 | .settings 5 | 6 | # Pycharm project files 7 | .idea 8 | 9 | # Python cache files 10 | *.py[cdo] 11 | 12 | # Documentation build 13 | docs/build 14 | 15 | # Ignore specific files 16 | main.py 17 | 18 | # Virtual environment 19 | virtualenv/ 20 | venv/ 21 | 22 | # OSX files 23 | .DS_Store 24 | 25 | # Build 26 | build/ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 FlatAngle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flatlib 2 | 3 | Flatlib is a python library for Traditional Astrology. 4 | 5 | ```python 6 | 7 | >>> date = Datetime('2015/03/13', '17:00', '+00:00') 8 | >>> pos = GeoPos('38n32', '8w54') 9 | >>> chart = Chart(date, pos) 10 | 11 | >>> sun = chart.get(const.SUN) 12 | >>> print(sun) 13 | 14 | 15 | ``` 16 | 17 | ## Documentation 18 | 19 | Flatlib's documentation is available at [http://flatlib.readthedocs.org/](http://flatlib.readthedocs.org/). 20 | 21 | 22 | ## Installation 23 | 24 | Flatlib is a Python 3 package, make sure you have Python 3 installed on your system. 25 | 26 | You can install flatlib with `pip3 install flatlib` or download the latest stable version from [https://pypi.python.org/pypi/flatlib](https://pypi.python.org/pypi/flatlib) and install it with `python3 setup.py install`. 27 | 28 | 29 | ## Development 30 | 31 | You can clone this repository or download a zip file using the right side buttons. -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | flatlib 2 | ======= 3 | 4 | A Python 3 library for Traditional Astrology. 5 | 6 | 7 | Example 8 | ------- 9 | 10 | :: 11 | 12 | >>> date = Datetime('2015/03/10', '14:00', '+00:00') 13 | >>> pos = GeoPos('38n32', '8w54') 14 | >>> chart = Chart(date, pos) 15 | 16 | >>> sun = chart.get(const.SUN) 17 | >>> print(sun) 18 | 19 | 20 | 21 | Changelog 22 | --------- 23 | 24 | * 0.2.1 (released 06-05-2016) 25 | - Added Pars Horsemanship 26 | - Return accidental dignities that score more than zero 27 | - Added chartdynamics.disposits to return dignities where planet A disposes a planet B 28 | - Includes new Triplicity Faces 29 | 30 | * 0.2.0 (released 08-04-2015) 31 | - Many new features: 32 | - Planetary time 33 | - Arabic Parts 34 | - Chart Dynamics 35 | - Accidental dignities 36 | - Predictives (Profections, Solar Returns and Primary Directions) 37 | - Protocols (Almutem, Temperament and Behavior calculations) 38 | - Bug fixes 39 | 40 | * 0.1.1 (released 18-03-2015) 41 | - Changed threshold for stationary (1 arc-second) 42 | - Implementation of essential dignities 43 | - Added essential dignities recipe 44 | 45 | * 0.1.0 (released 14-03-2015) 46 | - Initial release 47 | - Implementation of core modules 48 | -------------------------------------------------------------------------------- /contrib/topical_almuten.py: -------------------------------------------------------------------------------- 1 | from flatlib import const 2 | from flatlib.tools import planetarytime 3 | from flatlib.dignities import essential 4 | from flatlib.tools import arabicparts 5 | 6 | # List of dignities 7 | DIGNITY_LIST = [ 8 | 'ruler', 9 | 'exalt', 10 | 'dayTrip', 11 | 'nightTrip', 12 | 'partTrip', 13 | 'term', 14 | 'face' 15 | ] 16 | 17 | # List of objects 18 | OBJECT_LIST = const.LIST_SEVEN_PLANETS 19 | 20 | def newRow(): 21 | """ Returns a new Almutem table row. """ 22 | row = {} 23 | for obj in OBJECT_LIST: 24 | row[obj] = { 25 | 'string': '', 26 | 'score': 0 27 | } 28 | return row 29 | 30 | # Computes the topical almuten (TA) table. 31 | def computeTA(chart, TA): 32 | 33 | almutems = {} 34 | 35 | 36 | # SECOND HOUSE, 37 | # source: Omar of Tiberias - Three Books on Nativities, p. 57; Persian Nativities II, p. 52 38 | if TA == "TA_2H": 39 | TA_LIST = [ 40 | chart.getHouse(const.HOUSE2) 41 | ] 42 | TA_LIST.extend( 43 | [v for k, v in chart.objects.getObjectsInHouse(chart.getHouse(const.HOUSE2)).content.items()]) 44 | TA_LIST.extend( 45 | [chart.getObject(essential.ruler(chart.getHouse(const.HOUSE2).sign)), 46 | arabicparts.getPart(arabicparts.PARS_SUBSTANCE, chart), 47 | chart.getObject(essential.ruler(arabicparts.getPart(arabicparts.PARS_SUBSTANCE, chart).sign)), 48 | chart.getObject(const.JUPITER), 49 | chart.getObject(const.PARS_FORTUNA), 50 | chart.getObject(essential.ruler(chart.getObject(const.PARS_FORTUNA).sign)) 51 | ]) 52 | 53 | # THIRD HOUSE, 54 | # source: Omar of Tiberias - Three Books on Nativities, p. 58-59; Persian Nativities II, p. 53 55 | if TA == "TA_3H": 56 | TA_LIST = [ 57 | chart.getHouse(const.HOUSE3) 58 | ] 59 | TA_LIST.extend( 60 | [v for k, v in chart.objects.getObjectsInHouse(chart.getHouse(const.HOUSE3)).content.items()]) 61 | TA_LIST.extend( 62 | [chart.getObject(essential.ruler(chart.getHouse(const.HOUSE3).sign)), 63 | arabicparts.getPart(arabicparts.PARS_BROTHERS, chart), 64 | chart.getObject(essential.ruler(arabicparts.getPart(arabicparts.PARS_BROTHERS, chart).sign)), 65 | chart.getObject(const.MARS), 66 | chart.getObject(essential.dayTrip(chart.getObject(const.MARS).sign)), 67 | chart.getObject(essential.nightTrip(chart.getObject(const.MARS).sign)), 68 | chart.getObject(essential.partTrip(chart.getObject(const.MARS).sign)) 69 | ]) 70 | 71 | 72 | # 4th HOUSE, 73 | # Status of father - source: Persian Nativities II, p. 204 74 | if TA == "TA_4H_Father_Status": 75 | TA_LIST = [ 76 | chart.getHouse(const.HOUSE4) 77 | ] 78 | TA_LIST.extend( 79 | [v for k, v in chart.objects.getObjectsInHouse(chart.getHouse(const.HOUSE4)).content.items()]) 80 | TA_LIST.extend( 81 | [chart.getObject(essential.ruler(chart.getHouse(const.HOUSE4).sign)), 82 | arabicparts.getPart(arabicparts.PARS_FATHER, chart), 83 | chart.getObject(essential.ruler(arabicparts.getPart(arabicparts.PARS_FATHER, chart).sign)), 84 | chart.getObject(const.SATURN), 85 | chart.getObject(const.SUN), 86 | chart.getObject(const.SYZYGY), 87 | ]) 88 | 89 | # Father - source: JOHANNES SCHOENER, p. 51 90 | if TA == "TA_4H_Father_SCHOENER": 91 | TA_LIST = [ 92 | chart.getHouse(const.HOUSE4) 93 | ] 94 | TA_LIST.extend( 95 | [chart.getObject(essential.ruler(chart.getHouse(const.HOUSE4).sign)), 96 | chart.getObject(const.SUN), 97 | chart.getObject(essential.ruler(chart.getObject(const.SUN))), 98 | arabicparts.getPart(arabicparts.PARS_FATHER, chart), 99 | chart.getObject(essential.ruler(arabicparts.getPart(arabicparts.PARS_FATHER, chart).sign)), 100 | ]) 101 | if chart.isDiurnal(): 102 | TA_LIST.extend([chart.getObject(essential.dayTrip(chart.getHouse(const.HOUSE4).sign]))) 103 | else: TA_LIST.extend([chart.getObject(essential.nightTrip(chart.getHouse(const.HOUSE4).sign]))) 104 | 105 | 106 | 107 | # 10th HOUSE, 108 | # Status of mother - source: Persian Nativities II, p. 51 109 | if TA == "TA_4H_Mother_Status": 110 | TA_LIST = [ 111 | chart.getHouse(const.HOUSE10) 112 | ] 113 | TA_LIST.extend( 114 | [v for k, v in chart.objects.getObjectsInHouse(chart.getHouse(const.HOUSE10)).content.items()]) 115 | TA_LIST.extend( 116 | [chart.getObject(essential.ruler(chart.getHouse(const.HOUSE10).sign)), 117 | arabicparts.getPart(arabicparts.PARS_MOTHER, chart), 118 | chart.getObject(essential.ruler(arabicparts.getPart(arabicparts.PARS_MOTHER, chart).sign)), 119 | chart.getObject(const.MOON), 120 | chart.getObject(const.VENUS), 121 | chart.getObject(const.SYZYGY), 122 | ]) 123 | 124 | 125 | # And many more... 126 | 127 | for hyleg in TA_LIST: 128 | row = newRow() 129 | digInfo = essential.getInfo(hyleg.sign, hyleg.signlon) 130 | 131 | # Add the scores of each planet where hyleg has dignities 132 | for dignity in DIGNITY_LIST: 133 | objID = digInfo[dignity] 134 | if objID: 135 | score = essential.SCORES[dignity] 136 | row[objID]['string'] += '+%s' % score 137 | row[objID]['score'] += score 138 | 139 | almutems[hyleg.id] = row 140 | 141 | # Compute scores 142 | scores = newRow() 143 | for _property, _list in almutems.items(): 144 | for objID, values in _list.items(): 145 | scores[objID]['string'] += values['string'] 146 | scores[objID]['score'] += values['score'] 147 | almutems['Score'] = scores 148 | 149 | return almutems 150 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " applehelp to make an Apple Help Book" 34 | @echo " devhelp to make HTML files and a Devhelp project" 35 | @echo " epub to make an epub" 36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 37 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 39 | @echo " text to make text files" 40 | @echo " man to make manual pages" 41 | @echo " texinfo to make Texinfo files" 42 | @echo " info to make Texinfo files and run them through makeinfo" 43 | @echo " gettext to make PO message catalogs" 44 | @echo " changes to make an overview of all changed/added/deprecated items" 45 | @echo " xml to make Docutils-native XML files" 46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 47 | @echo " linkcheck to check all external links for integrity" 48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 49 | @echo " coverage to run coverage check of the documentation (if enabled)" 50 | 51 | clean: 52 | rm -rf $(BUILDDIR)/* 53 | 54 | html: 55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 56 | @echo 57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 58 | 59 | dirhtml: 60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 61 | @echo 62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 63 | 64 | singlehtml: 65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 66 | @echo 67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 68 | 69 | pickle: 70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 71 | @echo 72 | @echo "Build finished; now you can process the pickle files." 73 | 74 | json: 75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 76 | @echo 77 | @echo "Build finished; now you can process the JSON files." 78 | 79 | htmlhelp: 80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 81 | @echo 82 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 83 | ".hhp project file in $(BUILDDIR)/htmlhelp." 84 | 85 | qthelp: 86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 87 | @echo 88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/flatlib.qhcp" 91 | @echo "To view the help file:" 92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/flatlib.qhc" 93 | 94 | applehelp: 95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 96 | @echo 97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 98 | @echo "N.B. You won't be able to view it unless you put it in" \ 99 | "~/Library/Documentation/Help or install it in your application" \ 100 | "bundle." 101 | 102 | devhelp: 103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 104 | @echo 105 | @echo "Build finished." 106 | @echo "To view the help file:" 107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/flatlib" 108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/flatlib" 109 | @echo "# devhelp" 110 | 111 | epub: 112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 113 | @echo 114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 115 | 116 | latex: 117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 118 | @echo 119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 121 | "(use \`make latexpdf' here to do that automatically)." 122 | 123 | latexpdf: 124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 125 | @echo "Running LaTeX files through pdflatex..." 126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 128 | 129 | latexpdfja: 130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 131 | @echo "Running LaTeX files through platex and dvipdfmx..." 132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 134 | 135 | text: 136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 137 | @echo 138 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 139 | 140 | man: 141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 142 | @echo 143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 144 | 145 | texinfo: 146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 147 | @echo 148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 149 | @echo "Run \`make' in that directory to run these through makeinfo" \ 150 | "(use \`make info' here to do that automatically)." 151 | 152 | info: 153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 154 | @echo "Running Texinfo files through makeinfo..." 155 | make -C $(BUILDDIR)/texinfo info 156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 157 | 158 | gettext: 159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 160 | @echo 161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 162 | 163 | changes: 164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 165 | @echo 166 | @echo "The overview file is in $(BUILDDIR)/changes." 167 | 168 | linkcheck: 169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 170 | @echo 171 | @echo "Link check complete; look for any errors in the above output " \ 172 | "or in $(BUILDDIR)/linkcheck/output.txt." 173 | 174 | doctest: 175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 176 | @echo "Testing of doctests in the sources finished, look at the " \ 177 | "results in $(BUILDDIR)/doctest/output.txt." 178 | 179 | coverage: 180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 181 | @echo "Testing of coverage in the sources finished, look at the " \ 182 | "results in $(BUILDDIR)/coverage/python.txt." 183 | 184 | xml: 185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 186 | @echo 187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 188 | 189 | pseudoxml: 190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 191 | @echo 192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 193 | 194 | livehtml: 195 | sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 196 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Flatlib documentation 2 | 3 | This document explains how you can setup your environment to build and contribute to the flatlib documentation. 4 | 5 | 6 | ## Readthedocs 7 | 8 | Flatlib's documentation is available at [http://flatlib.readthedocs.org/](http://flatlib.readthedocs.org/). Every change to this repository triggers an immediate documentation build on the readthedocs server. 9 | 10 | 11 | ## Installing Sphinx and Sphinx-autobuild 12 | 13 | ### Sphinx 14 | 15 | The flatlib documentation is built from reStructuredText sources using [Sphinx](http://sphinx-doc.org/). 16 | The preferred way of installing Sphinx is with pip: 17 | 18 | * `pip install sphinx` on Linux or Mac. 19 | * `py pip install sphinx` on Windows. 20 | 21 | Refer to the [Sphinx documentation](http://sphinx-doc.org/install.html) for alternative ways to install Sphinx in your environment. 22 | 23 | ### Sphinx-autobuild 24 | 25 | Sphinx-autobuild is a tool to watch a Sphinx directory and rebuild the documentation when a change is detected. 26 | To install sphinx-autobuild use: 27 | 28 | * `pip install sphinx-autobuild` on Linux or Mac. 29 | * `py pip install sphinx-autobuild` on Windows. 30 | 31 | 32 | ## Build the documention 33 | 34 | There are two ways for building the documentation, both made possible by the available makefiles. Open a terminal or command prompt and *cd* into the *docs* directory: 35 | 36 | * To build the HTML documentation, execute `make html`. The generated documentation will be at *docs/build/html*. 37 | * Execute `make livehtml` to start the autobuild server. Visit the webpage served at `localhost:8000`, and the server will autoreload the page when a change is detected. Quit the server by pressing Ctrl+C (or Command+C). -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 10 | set I18NSPHINXOPTS=%SPHINXOPTS% source 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | echo. coverage to run coverage check of the documentation if enabled 41 | goto end 42 | ) 43 | 44 | if "%1" == "clean" ( 45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 46 | del /q /s %BUILDDIR%\* 47 | goto end 48 | ) 49 | 50 | 51 | REM Check if sphinx-build is available and fallback to Python version if any 52 | %SPHINXBUILD% 2> nul 53 | if errorlevel 9009 goto sphinx_python 54 | goto sphinx_ok 55 | 56 | :sphinx_python 57 | 58 | set SPHINXBUILD=python -m sphinx.__init__ 59 | %SPHINXBUILD% 2> nul 60 | if errorlevel 9009 ( 61 | echo. 62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 63 | echo.installed, then set the SPHINXBUILD environment variable to point 64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 65 | echo.may add the Sphinx directory to PATH. 66 | echo. 67 | echo.If you don't have Sphinx installed, grab it from 68 | echo.http://sphinx-doc.org/ 69 | exit /b 1 70 | ) 71 | 72 | :sphinx_ok 73 | 74 | 75 | if "%1" == "html" ( 76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 77 | if errorlevel 1 exit /b 1 78 | echo. 79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 80 | goto end 81 | ) 82 | 83 | if "%1" == "dirhtml" ( 84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 85 | if errorlevel 1 exit /b 1 86 | echo. 87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 88 | goto end 89 | ) 90 | 91 | if "%1" == "singlehtml" ( 92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 93 | if errorlevel 1 exit /b 1 94 | echo. 95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 96 | goto end 97 | ) 98 | 99 | if "%1" == "pickle" ( 100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 101 | if errorlevel 1 exit /b 1 102 | echo. 103 | echo.Build finished; now you can process the pickle files. 104 | goto end 105 | ) 106 | 107 | if "%1" == "json" ( 108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 109 | if errorlevel 1 exit /b 1 110 | echo. 111 | echo.Build finished; now you can process the JSON files. 112 | goto end 113 | ) 114 | 115 | if "%1" == "htmlhelp" ( 116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 117 | if errorlevel 1 exit /b 1 118 | echo. 119 | echo.Build finished; now you can run HTML Help Workshop with the ^ 120 | .hhp project file in %BUILDDIR%/htmlhelp. 121 | goto end 122 | ) 123 | 124 | if "%1" == "qthelp" ( 125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 129 | .qhcp project file in %BUILDDIR%/qthelp, like this: 130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\flatlib.qhcp 131 | echo.To view the help file: 132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\flatlib.ghc 133 | goto end 134 | ) 135 | 136 | if "%1" == "devhelp" ( 137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 138 | if errorlevel 1 exit /b 1 139 | echo. 140 | echo.Build finished. 141 | goto end 142 | ) 143 | 144 | if "%1" == "epub" ( 145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 146 | if errorlevel 1 exit /b 1 147 | echo. 148 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 149 | goto end 150 | ) 151 | 152 | if "%1" == "latex" ( 153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 154 | if errorlevel 1 exit /b 1 155 | echo. 156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 157 | goto end 158 | ) 159 | 160 | if "%1" == "latexpdf" ( 161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 162 | cd %BUILDDIR%/latex 163 | make all-pdf 164 | cd %~dp0 165 | echo. 166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdfja" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf-ja 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "text" ( 181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 182 | if errorlevel 1 exit /b 1 183 | echo. 184 | echo.Build finished. The text files are in %BUILDDIR%/text. 185 | goto end 186 | ) 187 | 188 | if "%1" == "man" ( 189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 190 | if errorlevel 1 exit /b 1 191 | echo. 192 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 193 | goto end 194 | ) 195 | 196 | if "%1" == "texinfo" ( 197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 198 | if errorlevel 1 exit /b 1 199 | echo. 200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 201 | goto end 202 | ) 203 | 204 | if "%1" == "gettext" ( 205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 206 | if errorlevel 1 exit /b 1 207 | echo. 208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 209 | goto end 210 | ) 211 | 212 | if "%1" == "changes" ( 213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 214 | if errorlevel 1 exit /b 1 215 | echo. 216 | echo.The overview file is in %BUILDDIR%/changes. 217 | goto end 218 | ) 219 | 220 | if "%1" == "linkcheck" ( 221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 222 | if errorlevel 1 exit /b 1 223 | echo. 224 | echo.Link check complete; look for any errors in the above output ^ 225 | or in %BUILDDIR%/linkcheck/output.txt. 226 | goto end 227 | ) 228 | 229 | if "%1" == "doctest" ( 230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 231 | if errorlevel 1 exit /b 1 232 | echo. 233 | echo.Testing of doctests in the sources finished, look at the ^ 234 | results in %BUILDDIR%/doctest/output.txt. 235 | goto end 236 | ) 237 | 238 | if "%1" == "coverage" ( 239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 240 | if errorlevel 1 exit /b 1 241 | echo. 242 | echo.Testing of coverage in the sources finished, look at the ^ 243 | results in %BUILDDIR%/coverage/python.txt. 244 | goto end 245 | ) 246 | 247 | if "%1" == "xml" ( 248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 249 | if errorlevel 1 exit /b 1 250 | echo. 251 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 252 | goto end 253 | ) 254 | 255 | if "%1" == "pseudoxml" ( 256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 257 | if errorlevel 1 exit /b 1 258 | echo. 259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 260 | goto end 261 | ) 262 | 263 | :end 264 | -------------------------------------------------------------------------------- /docs/source/_static/python-interpreter-osx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flatangle/flatlib/fba89c72c13279c0709b0967a597427ee177665b/docs/source/_static/python-interpreter-osx.png -------------------------------------------------------------------------------- /docs/source/_static/python-interpreter-win32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flatangle/flatlib/fba89c72c13279c0709b0967a597427ee177665b/docs/source/_static/python-interpreter-win32.png -------------------------------------------------------------------------------- /docs/source/_static/xcode-command-line-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flatangle/flatlib/fba89c72c13279c0709b0967a597427ee177665b/docs/source/_static/xcode-command-line-tools.png -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # flatlib documentation build configuration file, created by 5 | # sphinx-quickstart on Mon Apr 13 18:08:41 2015. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | import shlex 19 | 20 | # If extensions (or modules to document with autodoc) are in another directory, 21 | # add these directories to sys.path here. If the directory is relative to the 22 | # documentation root, use os.path.abspath to make it absolute, like shown here. 23 | #sys.path.insert(0, os.path.abspath('.')) 24 | 25 | # -- General configuration ------------------------------------------------ 26 | 27 | # If your documentation needs a minimal Sphinx version, state it here. 28 | #needs_sphinx = '1.0' 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [] 34 | 35 | # Add any paths that contain templates here, relative to this directory. 36 | #templates_path = ['_templates'] 37 | 38 | # The suffix(es) of source filenames. 39 | # You can specify multiple suffix as a list of string: 40 | # source_suffix = ['.rst', '.md'] 41 | source_suffix = '.rst' 42 | 43 | # The encoding of source files. 44 | #source_encoding = 'utf-8-sig' 45 | 46 | # The master toctree document. 47 | master_doc = 'index' 48 | 49 | # General information about the project. 50 | project = 'flatlib' 51 | copyright = '2015, João Ventura' 52 | author = 'João Ventura' 53 | 54 | # The version info for the project you're documenting, acts as replacement for 55 | # |version| and |release|, also used in various other places throughout the 56 | # built documents. 57 | # 58 | # The short X.Y version. 59 | version = '0.2' 60 | # The full version, including alpha/beta/rc tags. 61 | release = '0.2.0' 62 | 63 | # The language for content autogenerated by Sphinx. Refer to documentation 64 | # for a list of supported languages. 65 | # 66 | # This is also used if you do content translation via gettext catalogs. 67 | # Usually you set "language" from the command line for these cases. 68 | language = None 69 | 70 | # There are two options for replacing |today|: either, you set today to some 71 | # non-false value, then it is used: 72 | #today = '' 73 | # Else, today_fmt is used as the format for a strftime call. 74 | #today_fmt = '%B %d, %Y' 75 | 76 | # List of patterns, relative to source directory, that match files and 77 | # directories to ignore when looking for source files. 78 | exclude_patterns = [] 79 | 80 | # The reST default role (used for this markup: `text`) to use for all 81 | # documents. 82 | #default_role = None 83 | 84 | # If true, '()' will be appended to :func: etc. cross-reference text. 85 | #add_function_parentheses = True 86 | 87 | # If true, the current module name will be prepended to all description 88 | # unit titles (such as .. function::). 89 | #add_module_names = True 90 | 91 | # If true, sectionauthor and moduleauthor directives will be shown in the 92 | # output. They are ignored by default. 93 | #show_authors = False 94 | 95 | # The name of the Pygments (syntax highlighting) style to use. 96 | pygments_style = 'sphinx' 97 | 98 | # A list of ignored prefixes for module index sorting. 99 | #modindex_common_prefix = [] 100 | 101 | # If true, keep warnings as "system message" paragraphs in the built documents. 102 | #keep_warnings = False 103 | 104 | # If true, `todo` and `todoList` produce output, else they produce nothing. 105 | todo_include_todos = False 106 | 107 | 108 | # -- Options for HTML output ---------------------------------------------- 109 | 110 | # The theme to use for HTML and HTML Help pages. See the documentation for 111 | # a list of builtin themes. 112 | html_theme = 'sphinx_rtd_theme' 113 | 114 | # Theme options are theme-specific and customize the look and feel of a theme 115 | # further. For a list of options available for each theme, see the 116 | # documentation. 117 | #html_theme_options = {} 118 | 119 | # Add any paths that contain custom themes here, relative to this directory. 120 | import sphinx_rtd_theme 121 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 122 | 123 | # The name for this set of Sphinx documents. If None, it defaults to 124 | # " v documentation". 125 | #html_title = None 126 | 127 | # A shorter title for the navigation bar. Default is the same as html_title. 128 | #html_short_title = None 129 | 130 | # The name of an image file (relative to this directory) to place at the top 131 | # of the sidebar. 132 | #html_logo = None 133 | 134 | # The name of an image file (within the static path) to use as favicon of the 135 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 136 | # pixels large. 137 | #html_favicon = None 138 | 139 | # Add any paths that contain custom static files (such as style sheets) here, 140 | # relative to this directory. They are copied after the builtin static files, 141 | # so a file named "default.css" will overwrite the builtin "default.css". 142 | html_static_path = ['_static'] 143 | 144 | # Add any extra paths that contain custom files (such as robots.txt or 145 | # .htaccess) here, relative to this directory. These files are copied 146 | # directly to the root of the documentation. 147 | #html_extra_path = [] 148 | 149 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 150 | # using the given strftime format. 151 | #html_last_updated_fmt = '%b %d, %Y' 152 | 153 | # If true, SmartyPants will be used to convert quotes and dashes to 154 | # typographically correct entities. 155 | #html_use_smartypants = True 156 | 157 | # Custom sidebar templates, maps document names to template names. 158 | #html_sidebars = {} 159 | 160 | # Additional templates that should be rendered to pages, maps page names to 161 | # template names. 162 | #html_additional_pages = {} 163 | 164 | # If false, no module index is generated. 165 | #html_domain_indices = True 166 | 167 | # If false, no index is generated. 168 | #html_use_index = True 169 | 170 | # If true, the index is split into individual pages for each letter. 171 | #html_split_index = False 172 | 173 | # If true, links to the reST sources are added to the pages. 174 | #html_show_sourcelink = True 175 | 176 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 177 | #html_show_sphinx = True 178 | 179 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 180 | #html_show_copyright = True 181 | 182 | # If true, an OpenSearch description file will be output, and all pages will 183 | # contain a tag referring to it. The value of this option must be the 184 | # base URL from which the finished HTML is served. 185 | #html_use_opensearch = '' 186 | 187 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 188 | #html_file_suffix = None 189 | 190 | # Language to be used for generating the HTML full-text search index. 191 | # Sphinx supports the following languages: 192 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' 193 | # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' 194 | #html_search_language = 'en' 195 | 196 | # A dictionary with options for the search language support, empty by default. 197 | # Now only 'ja' uses this config value 198 | #html_search_options = {'type': 'default'} 199 | 200 | # The name of a javascript file (relative to the configuration directory) that 201 | # implements a search results scorer. If empty, the default will be used. 202 | #html_search_scorer = 'scorer.js' 203 | 204 | # Output file base name for HTML help builder. 205 | htmlhelp_basename = 'flatlibdoc' 206 | 207 | # -- Options for LaTeX output --------------------------------------------- 208 | 209 | latex_elements = { 210 | # The paper size ('letterpaper' or 'a4paper'). 211 | #'papersize': 'letterpaper', 212 | 213 | # The font size ('10pt', '11pt' or '12pt'). 214 | #'pointsize': '10pt', 215 | 216 | # Additional stuff for the LaTeX preamble. 217 | #'preamble': '', 218 | 219 | # Latex figure (float) alignment 220 | #'figure_align': 'htbp', 221 | } 222 | 223 | # Grouping the document tree into LaTeX files. List of tuples 224 | # (source start file, target name, title, 225 | # author, documentclass [howto, manual, or own class]). 226 | latex_documents = [ 227 | (master_doc, 'flatlib.tex', 'flatlib Documentation', 228 | 'João Ventura', 'manual'), 229 | ] 230 | 231 | # The name of an image file (relative to this directory) to place at the top of 232 | # the title page. 233 | #latex_logo = None 234 | 235 | # For "manual" documents, if this is true, then toplevel headings are parts, 236 | # not chapters. 237 | #latex_use_parts = False 238 | 239 | # If true, show page references after internal links. 240 | #latex_show_pagerefs = False 241 | 242 | # If true, show URL addresses after external links. 243 | #latex_show_urls = False 244 | 245 | # Documents to append as an appendix to all manuals. 246 | #latex_appendices = [] 247 | 248 | # If false, no module index is generated. 249 | #latex_domain_indices = True 250 | 251 | 252 | # -- Options for manual page output --------------------------------------- 253 | 254 | # One entry per manual page. List of tuples 255 | # (source start file, name, description, authors, manual section). 256 | man_pages = [ 257 | (master_doc, 'flatlib', 'flatlib Documentation', 258 | [author], 1) 259 | ] 260 | 261 | # If true, show URL addresses after external links. 262 | #man_show_urls = False 263 | 264 | 265 | # -- Options for Texinfo output ------------------------------------------- 266 | 267 | # Grouping the document tree into Texinfo files. List of tuples 268 | # (source start file, target name, title, author, 269 | # dir menu entry, description, category) 270 | texinfo_documents = [ 271 | (master_doc, 'flatlib', 'flatlib Documentation', 272 | author, 'flatlib', 'One line description of project.', 273 | 'Miscellaneous'), 274 | ] 275 | 276 | # Documents to append as an appendix to all manuals. 277 | #texinfo_appendices = [] 278 | 279 | # If false, no module index is generated. 280 | #texinfo_domain_indices = True 281 | 282 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 283 | #texinfo_show_urls = 'footnote' 284 | 285 | # If true, do not generate a @detailmenu in the "Top" node's menu. 286 | #texinfo_no_detailmenu = False 287 | -------------------------------------------------------------------------------- /docs/source/faq.rst: -------------------------------------------------------------------------------- 1 | Frequently Asked Questions 2 | ========================== 3 | 4 | 5 | **Can everyone use it?** 6 | 7 | Flatlib is open-source software so everyone is free to install and use it. 8 | However, since it is a programming library, some people may not be particularly inclined to use it since it 9 | requires some learning. 10 | 11 | **So is it not a end-user tool?** 12 | 13 | Flatlib should really be seen as a traditional astrology software without a graphical user interface. 14 | Therefore, it is really powerful, since users can experiment without the "chains" of a graphical user interface. 15 | 16 | **How can I install it?** 17 | 18 | Documentation is still scarce, but I hope to improve it in the future. 19 | You should install the latest Python 3 (3.4) and grab the flatlib package with ``pip3 install flatlib``. 20 | This will install flatlib and its dependencies. 21 | 22 | **Is there a project page?** 23 | 24 | You can check the code and simple documentation in the github page at https://github.com/flatangle/flatlib. 25 | 26 | **Are there any sample code?** 27 | 28 | There's a "recipes" folder with some source code at https://github.com/flatangle/flatlib/tree/master/recipes. 29 | You can start with "aspects.py" which is at https://github.com/flatangle/flatlib/blob/master/recipes/aspects.py. 30 | 31 | **Can I use it on my own work?** 32 | 33 | Absolutely yes, you are free to use it in your own projects. 34 | The flatlib source code is released under an MIT License, which allows it to be used also on commercial projects. 35 | There is a caveat though: flatlib uses the swiss ephemeris which is licensed GPL. 36 | Therefore, if you want to use flatlib in your commercial projects, you must adhere to the GPL license or buy a 37 | Swiss Ephemeris commercial license. 38 | 39 | **Why are you open-sourcing flatlib?** 40 | 41 | I really want to help push forward data-driven research in astrology. 42 | That is only possible with a strong community of researchers and good tools, so there was no point in keeping 43 | flatlib hidden on my hard disk. Flatlib is also a good tool for talking about astrology techniques. 44 | Someone can always point to the source code to explain how things can be done. 45 | 46 | **Can I contribute to the project?** 47 | 48 | I accept contributions such as code and documentation, although I suggest to wait a while since things are not stable yet. 49 | The best contribution for now is to spread the news about the existence of this project. 50 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Flatlib documentation 2 | ===================== 3 | 4 | Flatlib is a Python 3 library for Traditional Astrology.:: 5 | 6 | >>> date = Datetime('2015/03/13', '17:00', '+00:00') 7 | >>> pos = GeoPos('38n32', '8w54') 8 | >>> chart = Chart(date, pos) 9 | 10 | >>> sun = chart.get(const.SUN) 11 | >>> print(sun) 12 | 13 | 14 | 15 | Contents 16 | -------- 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | 21 | installation 22 | tutorials/index 23 | faq -------------------------------------------------------------------------------- /docs/source/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | The following instructions will install flatlib from the source files. In the future, binaries may be made available 5 | and the instructions will be updated accordingly. 6 | 7 | Windows 8 | ------- 9 | 10 | If you don't have Python 3 installed on your system, download and install the latest Python 3.4 for Windows from 11 | https://www.python.org/downloads/. You can check if the interpreter was correctly installed by executing ``py`` on the 12 | command line. 13 | 14 | Open a Windows command prompt (or exit the Python interactive shell) and install flatlib using ``py -m pip install 15 | flatlib``. 16 | 17 | If you get an error such as **Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat)**, you will have 18 | to install a C compiler. The compiler is required to build *pyswisseph* - the Python port of the Swiss Ephemeris. 19 | 20 | There are several C compilers for Windows, such as Cygwin and MinGW, but Visual C++ 2010 is the most used for compiling 21 | Python 3 extensions on Windows. Download Microsoft Visual C++ 2010 Express from http://go.microsoft.com/?linkid=9709949 22 | (it may require the creation of a free Windows Developer account). After the installation, execute the following on 23 | the command line:: 24 | 25 | set CL=-DWIN32 26 | py -m pip install flatlib 27 | 28 | You should now have flatlib installed in your system. 29 | 30 | OS X 31 | ---- 32 | 33 | Latest versions of OS X are bundled only with Python 2. The preferred way to install Python 3 in OS X is using the 34 | homebrew package manager (http://brew.sh/). Install homebrew and then install Python 3 using ``brew install python3``. 35 | 36 | Before you install flatlib, you must have a C compiler in your system. This is because flatlib depends on the Swiss 37 | Ephemeris which is implemented in C. Fortunatelly, Apple provides the *Xcode Command Line Tools* which bundles a C 38 | compiler. To install it, open the terminal (Applications/Utilities/Terminal) and execute ``gcc``. 39 | You'll see an alert box if you don't have a compiler installed: 40 | 41 | .. image:: _static/xcode-command-line-tools.png 42 | :align: center 43 | 44 | If you don't need the entire Xcode (about 2.5GB) just press **Install**.. 45 | 46 | Finally, to install flatlib use ``pip3 install flatlib``. 47 | 48 | 49 | Linux 50 | ----- 51 | 52 | Python 3 is already included on most of the newer distributions. The simplest way to test for the existence of Python 3 53 | is to open the terminal and execute ``python3`` to start the interactive python interpreter. 54 | If the interpreter is not found, you will have to install it from your distribution's repo. 55 | 56 | To install flatlib, use ``pip3 install flatlib``. It may require you to install *pip* and other python 3 development 57 | libraries. 58 | 59 | If you get a Permission Denied error, execute the previous command with ``sudo``. 60 | 61 | 62 | Testing the installation 63 | ------------------------ 64 | 65 | Start the python3 interactive interpreter (``python3`` on Linux and Mac, and ``py`` on Windows) and execute the 66 | following:: 67 | 68 | >>> import flatlib 69 | >>> flatlib 70 | 71 | 72 | If you don't get an import error, flatlib is installed in your system. 73 | 74 | 75 | Upgrading from a previous version 76 | --------------------------------- 77 | 78 | To upgrade from a previous version, run: 79 | 80 | * ``pip3 install flatlib --upgrade`` in Linux and Mac. 81 | * ``py pip install flatlib --upgrade`` in Windows. 82 | 83 | 84 | Uninstalling 85 | ------------ 86 | 87 | Just do ``pip3 uninstall flatlib`` on Linux and Mac or ``py pip uninstall flatlib`` on Windows. 88 | -------------------------------------------------------------------------------- /docs/source/tutorials/chart-properties.rst: -------------------------------------------------------------------------------- 1 | Chart properties and objects 2 | ============================ 3 | 4 | In the previous tutorial it was shown the necessary steps to create a Chart object. 5 | In this tutorial it will be shown which properties, objects and functions are accessible on the chart. 6 | Specifically, you will learn how to access: 7 | 8 | * Objects, houses or angles from the chart 9 | * Fixed stars 10 | * Other chart functions 11 | 12 | Let's start by creating a new chart:: 13 | 14 | >>> from flatlib.datetime import Datetime 15 | >>> from flatlib.geopos import GeoPos 16 | >>> from flatlib.chart import Chart 17 | 18 | >>> date = Datetime('2015/03/13', '17:00', '+00:00') 19 | >>> pos = GeoPos('38n32', '8w54') 20 | >>> chart = Chart(date, pos) 21 | 22 | 23 | Objects 24 | ------- 25 | 26 | In *flatlib* an object is a planet, a moon node, the syzygy or pars fortuna. 27 | The following example shows how you can access an object from the chart:: 28 | 29 | >>> sun = chart.getObject(const.SUN) 30 | >>> print(sun) 31 | 32 | 33 | In this specific example, we use the *getObject* method and say specifically which object we want to access. 34 | All objects identifiers are defined in *const.py* (see `source code`_). 35 | 36 | Another possibility is to use the generic *get* method, which works for objects, houses, angles and fixed-stars:: 37 | 38 | >>> moon = chart.get(const.MOON) 39 | >>> print(moon) 40 | 41 | 42 | By default, when we *print* an object, it prints its identifier, the sign, sign longitude and travel speed. 43 | However, more information can be accessed from the object. Some of the available properties are:: 44 | 45 | >>> sun.lon 46 | 352.7901809551436 47 | >>> sun.lat 48 | 0.00014399505974328042 49 | >>> sun.sign 50 | 'Pisces' 51 | >>> sun.signlon 52 | 22.790180955143626 53 | >>> sun.lonspeed 54 | 0.9976256538994072 55 | 56 | Some of the available functions are:: 57 | 58 | >>> sun.orb() 59 | 15 60 | >>> sun.meanMotion() 61 | 0.9833 62 | >>> sun.movement() 63 | 'Direct' 64 | >>> sun.gender() 65 | 'Masculine' 66 | >>> sun.element() 67 | 'Fire' 68 | >>> sun.isFast() 69 | True 70 | 71 | Most of these properties and functions are self explanatory. 72 | 73 | 74 | Houses 75 | ------ 76 | 77 | Similarly to objects, a list of houses is available from the chart. 78 | To retrieve an individual house, we can use the *getHouse* method or the generic *get* method:: 79 | 80 | >>> house1 = chart.get(const.HOUSE1) 81 | >>> print(house1) 82 | 83 | 84 | Similarly to objects, we can also access the properties of an house:: 85 | 86 | >>> house1.lon 87 | 153.45843823091616 88 | >>> house1.sign 89 | 'Virgo' 90 | >>> house1.signlon 91 | 3.4584382309161583 92 | >>> house1.size 93 | 29.39933122126604 94 | 95 | or its functions:: 96 | 97 | >>> house1.condition() 98 | 'Angular' 99 | >>> house1.gender() 100 | 'Masculine' 101 | 102 | Houses provides also interesting functions to check if an object is in a house, such as:: 103 | 104 | >>> house1.hasObject(sun) 105 | False 106 | 107 | 108 | Angles 109 | ------ 110 | 111 | In some house systems, such as *Equal* or *Whole sign houses*, there is a clear distinction between the *Ascendant* 112 | and *MC*, and the 1st and 10th house cusps, hence the necessity of angles. 113 | To retrieve an angle from the chart you can use the *getAngle* method or the generic *get* method:: 114 | 115 | >>> asc = chart.get(const.ASC) 116 | >>> mc = chart.get(const.MC) 117 | >>> print(asc) 118 | 119 | >>> print(mc) 120 | 121 | 122 | Similarly to objects and houses, some properties and functions are also available for angles. 123 | 124 | Fixed-stars 125 | ----------- 126 | 127 | To retrieve fixed stars from the chart, we must use the *getFixedStar* method:: 128 | 129 | >>> spica = chart.getFixedStar(const.STAR_SPICA) 130 | >>> print(spica) 131 | 132 | >>> spica.mag # magnitude 133 | 0.97 134 | >>> spica.orb() 135 | 7.5 136 | 137 | The list of avaliable fixed stars are defined in the `source code`_. 138 | 139 | Lists 140 | ----- 141 | 142 | In some cases, instead of retrieving objects, houses or angles one by one, it may be useful to get direct access to 143 | their lists. The *chart* object provides the following lists: 144 | 145 | * *chart.objects*, with a list of all objects 146 | * *chart.houses*, with a list of all houses 147 | * *chart.angles*, with a list of all angles 148 | 149 | The following example uses the ``for`` command to iterate over all objects in the list of objects:: 150 | 151 | >>> for obj in chart.objects: 152 | ... print(obj) 153 | ... 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | Lists also provides us with useful functions. 167 | For instance, the house list provides a function to retrieve the house where an object is:: 168 | 169 | >>> house = chart.houses.getObjectHouse(sun) 170 | >>> print(house) 171 | 172 | 173 | In this specific case, the sun is in the 7th house. 174 | The `lists.py`_ file provides a full overview of what is available for each list. 175 | 176 | 177 | Chart functions 178 | --------------- 179 | 180 | Besides the functions to retrieve objects, houses, angles and fixed-stars, the chart object provides other useful 181 | functions:: 182 | 183 | >>> chart.isDiurnal() 184 | True 185 | >>> chart.getMoonPhase() 186 | 'Third Quarter' 187 | 188 | Finally, the chart object also provides a useful function to retrieve the solar return chart for a year:: 189 | 190 | >>> srchart = chart.solarReturn(2020) 191 | >>> print(srchart.date) 192 | <2020/03/12 22:01:59 00:00:00> 193 | 194 | 195 | .. _`source code`: https://github.com/flatangle/flatlib/blob/master/flatlib/const.py 196 | .. _`lists.py`: https://github.com/flatangle/flatlib/blob/master/flatlib/lists.py -------------------------------------------------------------------------------- /docs/source/tutorials/create-chart.rst: -------------------------------------------------------------------------------- 1 | Creating a Chart 2 | ================ 3 | 4 | The goal for this tutorial is to help you create a Chart for a specific date and location. 5 | To build a Chart it will be necessary to define: 6 | 7 | * the date and time, given by the *Datetime* object. 8 | * the geographic position, given by the *GeoPos* object. 9 | 10 | 11 | Datetime 12 | -------- 13 | 14 | The *Datetime* class represents a specific moment in time given by a *Date*, a *Time*, an *UTC offset* 15 | and the calendar type. It assumes, by default, the Gregorian calendar. 16 | 17 | To create a Datetime object, we must first import it. Here's an example that creates a Datetime object for the 18 | 13th of March of 2015 at 5pm, assuming UTC+0:: 19 | 20 | >>> from flatlib.datetime import Datetime 21 | >>> date = Datetime('2015/03/13', '17:00', '+00:00') 22 | >>> date.jd 23 | 2457095.2083333335 24 | 25 | The *jd* attribute (as in ``date.jd``) returns the `Julian Date`_. 26 | 27 | The time and UTC offset parameters are optional, and the arguments could be given as lists instead of strings. 28 | Some alternative ways to build the same date object are:: 29 | 30 | >>> # No UTC Offset argument 31 | >>> date = Datetime('2015/03/13', '17:00') 32 | >>> date.jd 33 | 2457095.2083333335 34 | 35 | >>> # Build date with date and time lists 36 | >>> date = Datetime([2015,3,13], ['+',17,0,0]) 37 | >>> date.jd 38 | 2457095.2083333335 39 | 40 | The Datetime object provides properties and functions which may be useful for some situations:: 41 | 42 | >>> # Print date, time and offset 43 | >>> print(date.date) 44 | <2015/03/13> 45 | >>> print(date.time) 46 | <17:00:00> 47 | >>> print(date.utcoffset) 48 | <00:00:00> 49 | 50 | >>> # Other properties 51 | >>> date.date.dayofweek() 52 | 5 # 5 is Friday 53 | >>> date.time.toList() 54 | ['+', 17, 0, 0] 55 | 56 | 57 | GeoPos 58 | ------ 59 | 60 | The *GeoPos* class represents a geographic position on Earth given by a latitude and longitude. 61 | To create a GeoPos object, we must first import the class definition and instantiate an object. 62 | Here's an example:: 63 | 64 | >>> from flatlib.geopos import GeoPos 65 | >>> pos = GeoPos('38n32', '8w54') 66 | >>> pos.lat 67 | 38.53333333333333 68 | >>> pos.lon 69 | -8.9 70 | 71 | When building the geopos object, the first parameter must be the latitude and the second the longitude. 72 | The latitude and longitude properties can be accessed directly (using ``pos.lat`` and ``pos.lon``). 73 | Northern latitudes and eastern longitudes have positive values, while southern latitudes and western longitudes 74 | have negative values. 75 | 76 | Alternative ways to build a Geopos object can be:: 77 | 78 | >>> # Using angle strings 79 | >>> pos = GeoPos('+38:32','-8:54') 80 | >>> pos.lat, pos.lon 81 | (38.53333333333333, -8.9) 82 | 83 | >>> # Using angle lists 84 | >>> pos = GeoPos(['+',38,32], ['-',8,54]) 85 | >>> pos.lat, pos.lon 86 | (38.53333333333333, -8.9) 87 | 88 | >>> # Using the float values 89 | >>> pos = GeoPos(38.53333333333333, -8.9) 90 | >>> pos.lat, pos.lon 91 | (38.53333333333333, -8.9) 92 | 93 | 94 | Chart 95 | ----- 96 | 97 | The *Chart* class represents an Astrology chart for a specific datetime and geographic position. 98 | To create a chart object, we must create the Datetime and GeoPos objects and pass them as arguments to the Chart:: 99 | 100 | >>> # Set datetime and position 101 | >>> from flatlib.datetime import Datetime 102 | >>> from flatlib.geopos import GeoPos 103 | >>> date = Datetime('2015/03/13', '17:00', '+00:00') 104 | >>> pos = GeoPos('38n32', '8w54') 105 | 106 | >>> # Finally create the chart 107 | >>> from flatlib.chart import Chart 108 | >>> chart = Chart(date, pos) 109 | 110 | By default, the chart will include only the Traditional planets (*Sun* to *Saturn*, including *Pars Fortuna* and 111 | the Moon nodes) and the *Alcabitius* house system. 112 | To create a chart with other parameters, we must first import the **flatlib.const** module (where some things are 113 | defined) and pass some arguments in the object constructor:: 114 | 115 | >>> from flatlib import const 116 | 117 | >>> # Build a chart with Regiomontanus houses 118 | >>> chart = Chart(date, pos, hsys=const.HOUSES_REGIOMONTANUS) 119 | 120 | >>> # Build a chart including modern planets 121 | >>> chart = Chart(date, pos, IDs=const.LIST_OBJECTS) 122 | 123 | >>> # Build a chart with only the Sun and Moon 124 | >>> chart = Chart(date, pos, IDs=[const.SUN, const.MOON]) 125 | 126 | In the next tutorials it will be shown how we can access the chart's properties, including objects, houses and angles. 127 | 128 | 129 | .. _`Julian Date`: http://en.wikipedia.org/wiki/Julian_day -------------------------------------------------------------------------------- /docs/source/tutorials/index.rst: -------------------------------------------------------------------------------- 1 | Tutorials 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | intro-python 8 | create-chart 9 | chart-properties -------------------------------------------------------------------------------- /docs/source/tutorials/intro-python.rst: -------------------------------------------------------------------------------- 1 | Introduction to Python 2 | ====================== 3 | 4 | The purpose of this tutorial is to show you how you can quickly start working with the Python programming language. 5 | It assumes that you have already succesfully installed Python in your computer. 6 | If you already know how to use Python, you can skip this tutorial. 7 | 8 | 9 | Interactive interpreter 10 | ----------------------- 11 | 12 | Python is a general purpose programming language that bundles an interactive interpreter. 13 | To start the interactive interpreter, open the terminal (command prompt in Windows) and execute ``python3`` 14 | (or ``py`` in Windows) 15 | 16 | .. image:: ../_static/python-interpreter-osx.png 17 | :align: center 18 | 19 | .. Cimage:: ../_static/python-interpreter-win32.png 20 | :align: center 21 | 22 | In the interactive interpreter, you can enter commands and the Python interpreter will execute those commands and 23 | return the answers. 24 | 25 | 26 | Print command 27 | ------------- 28 | 29 | The *print* command is one of the most useful commands in Python, since it allows us to print the contents of python 30 | *variables*. For instance, try the following in your Python interpreter:: 31 | 32 | >>> print('Hello, world!') 33 | Hello, world! 34 | 35 | You can see that the interpreter will print the exact contents of whatever you put between quotation marks (called string). 36 | Try to print other strings. 37 | 38 | 39 | Variables 40 | --------- 41 | 42 | In computer languages, variables are reserved memory locations to store values. Basically, when you create a variable, 43 | the Python interpreter allocates memory and stores a value in that memory location. The equal sign (=) is used to assign 44 | values to variables. Try the following in your interpreter:: 45 | 46 | >>> number = 100 47 | >>> miles = 1000.0 48 | >>> name = "John" 49 | >>> print(number) 50 | 100 51 | >>> print(miles) 52 | 1000.0 53 | >>> print(name) 54 | John 55 | 56 | You can assign integer numbers to variables, floating point numbers and strings. 57 | 58 | 59 | Basic Operations 60 | ---------------- 61 | 62 | Since variables may include numbers, strings or other objects, Python allows us to do some basic operations on 63 | variables, such as adding, subtracting, multiplying or divinding. Some of those operations make more sense on numbers, 64 | but others may be applied in strings as well. 65 | 66 | Try the following operations on numbers:: 67 | 68 | >>> num1 = 10 69 | >>> num2 = 20 70 | >>> num1 + num2 71 | 30 72 | >>> num1 - num2 73 | -10 74 | >>> num1 * num2 75 | 200 76 | >>> num1 / num2 77 | 0.5 78 | 79 | Now let's see how it works for strings:: 80 | 81 | >>> name1 = 'Homer' 82 | >>> name2 = 'Simpson' 83 | >>> name1 + name2 84 | HomerSimpson 85 | >>> name1 - name2 86 | Traceback (most recent call last): 87 | File "", line 1, in 88 | TypeError: unsupported operand type(s) for -: 'str' and 'str' 89 | 90 | Some operations do not make sense for strings. 91 | 92 | 93 | Assignment operator 94 | ------------------- 95 | 96 | Something very important in programming languages is the assigment operator. We have already discussed it above when 97 | we assigned numbers and strings to variables using the equal operator (=). The important thing to notice is that we 98 | can assign the result of an operator to a variable like in the following example:: 99 | 100 | >>> num1 = 10 101 | >>> num2 = 20 102 | >>> result = num1 + num2 103 | >>> print(result) 104 | 30 105 | >>> result # This also works in the interpreter 106 | 30 107 | 108 | 109 | Python lists and dictionaries 110 | ----------------------------- 111 | 112 | In Python, there are two special data structures called *lists* and *dictionaries*. 113 | A list is basically a sequence of variables which can be or not of the same data type. 114 | Here is a simple example:: 115 | 116 | >>> mylist = [-5, 0.3, 2.5, 33] 117 | >>> mylist[0] 118 | -5 119 | >>> mylist[1] 120 | 0.3 121 | >>> mylist[0] + mylist[1] 122 | -4.7 123 | 124 | We can access the individual contents of a list by referring to the index number between brackets. 125 | For instance, ``mylist[1]`` returns the contents of *mylist* at index 1. Lists are zero-based. 126 | 127 | A dictionary is a data structure somewhat similar to lists but which do not represent sequences of variables. 128 | Here is an example for dictionaries:: 129 | 130 | >>> mydict = {'name': 'John Doe', 'age': 32, 'gender': 'male'} 131 | >>> mydict['name'] 132 | John Doe 133 | >>> mydict['age'] 134 | 32 135 | >>> mydict['age'] = 32 * 2 136 | >>> mydict['age'] 137 | 64 138 | 139 | Similarly to lists, you can access the individual contents of a dictionary using the index value between brackets. 140 | But unlike lists, you can also use strings or other objects as *key*. 141 | 142 | Python modules 143 | -------------- 144 | 145 | Python provides different functionalities organized by *modules*. A module is a file containing Python definitions, 146 | statements and functions. 147 | 148 | Python comes with a library of standard modules which provides many functionalities. 149 | To access a module you must explicitly import it using the *import* command. Here is an example of importing 150 | the *math* module to use some of its functions:: 151 | 152 | >>> import math 153 | >>> math.factorial(10) 154 | 3628800 155 | >>> math.log(20) 156 | 2.995732273553991 157 | 158 | The Python Library Reference describes the standard library that is distributed with Python, and can be found at 159 | https://docs.python.org/3.4/library/index.html. 160 | 161 | 162 | More about Python 163 | ----------------- 164 | 165 | The purpose of this tutorial is just to give you enough knowledge on Python to get you started with *flatlib*. 166 | There are many more tutorials on the internet which may give you deeper knowledge of the Python programming language. 167 | 168 | The Python community provides an official tutorial which can be found at https://docs.python.org/3.4/tutorial/index.html. -------------------------------------------------------------------------------- /flatlib/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is part of flatlib - (C) FlatAngle 3 | Author: João Ventura (flatangleweb@gmail.com) 4 | 5 | """ 6 | 7 | import os 8 | 9 | __version__ = '0.2.3' 10 | 11 | # Library and resource paths 12 | PATH_LIB = os.path.dirname(__file__) + os.sep 13 | PATH_RES = PATH_LIB + 'resources' + os.sep 14 | -------------------------------------------------------------------------------- /flatlib/angle.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is part of flatlib - (C) FlatAngle 3 | Author: João Ventura (flatangleweb@gmail.com) 4 | 5 | 6 | This module provides useful functions for handling angles. 7 | An angle is represented in this library as a value. 8 | 9 | It also provides useful functions for handling the conversion 10 | of angles between strings, signed lists and float values. 11 | 12 | The conversion functions assume that: 13 | 14 | 1. Angle strings are like "-12:30:00". 15 | 2. Signed lists are like ['-',12,30,00]. 16 | 3. Regular lists are like [+12,30,30] or [-0.0,30,30] 17 | 4. Float value are fractions of an angle with base 60. 18 | Eg. "-12:30:00" is converted to -12.5. 19 | 20 | Regular lists are discouraged because it is hard to represent 21 | negative angles such as ['-',00,30,00]. In this case a -0.0 22 | should be used, as [-0.0,30,00], and converted to a signed 23 | list for further use. 24 | 25 | """ 26 | 27 | import math 28 | 29 | 30 | # === Angular utilities === # 31 | 32 | def norm(angle): 33 | """ Normalizes an angle between 0 and 360. """ 34 | return angle % 360 35 | 36 | 37 | def znorm(angle): 38 | """ Normalizes an angle between -180 and 180. """ 39 | angle = angle % 360 40 | return angle if angle <= 180 else angle - 360 41 | 42 | 43 | def distance(angle1, angle2): 44 | """ Angular distance from angle1 to angle2 (ccw). """ 45 | return norm(angle2 - angle1) 46 | 47 | 48 | def closestdistance(angle1, angle2): 49 | """ Closest distance from angle1 to angle2 (ccw is positive). """ 50 | return znorm(angle2 - angle1) 51 | 52 | 53 | # === Signed Lists utilities === # 54 | 55 | def _fixSlist(slist): 56 | """ Guarantees that a signed list has exactly four elements. """ 57 | slist.extend([0] * (4 - len(slist))) 58 | return slist[:4] 59 | 60 | 61 | def _roundSlist(slist): 62 | """ Rounds a signed list over the last element and removes it. """ 63 | slist[-1] = 60 if slist[-1] >= 30 else 0 64 | for i in range(len(slist) - 1, 1, -1): 65 | if slist[i] == 60: 66 | slist[i] = 0 67 | slist[i - 1] += 1 68 | return slist[:-1] 69 | 70 | 71 | # === Base conversions === # 72 | 73 | def strSlist(string): 74 | """ Converts angle string to signed list. """ 75 | sign = '-' if string[0] == '-' else '+' 76 | values = [abs(int(x)) for x in string.split(':')] 77 | return _fixSlist(list(sign) + values) 78 | 79 | 80 | def slistStr(slist): 81 | """ Converts signed list to angle string. """ 82 | slist = _fixSlist(slist) 83 | string = ':'.join(['%02d' % x for x in slist[1:]]) 84 | return slist[0] + string 85 | 86 | 87 | def slistFloat(slist): 88 | """ Converts signed list to float. """ 89 | values = [v / 60 ** (i) for (i, v) in enumerate(slist[1:])] 90 | value = sum(values) 91 | return -value if slist[0] == '-' else value 92 | 93 | 94 | def floatSlist(value): 95 | """ Converts float to signed list. """ 96 | slist = ['+', 0, 0, 0, 0] 97 | if value < 0: 98 | slist[0] = '-' 99 | value = abs(value) 100 | for i in range(1, 5): 101 | slist[i] = math.floor(value) 102 | value = (value - slist[i]) * 60 103 | return _roundSlist(slist) 104 | 105 | 106 | def strFloat(string): 107 | """ Converts angle string to float. """ 108 | slist = strSlist(string) 109 | return slistFloat(slist) 110 | 111 | 112 | def floatStr(value): 113 | """ Converts angle float to string. """ 114 | slist = floatSlist(value) 115 | return slistStr(slist) 116 | 117 | 118 | # === Direct conversions === # 119 | 120 | def toFloat(value): 121 | """ Converts string or signed list to float. """ 122 | if isinstance(value, str): 123 | return strFloat(value) 124 | elif isinstance(value, list): 125 | return slistFloat(value) 126 | else: 127 | return value 128 | 129 | 130 | def toList(value): 131 | """ Converts angle float to signed list. """ 132 | return floatSlist(value) 133 | 134 | 135 | def toString(value): 136 | """ Converts angle float to string. """ 137 | return floatStr(value) 138 | -------------------------------------------------------------------------------- /flatlib/aspects.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is part of flatlib - (C) FlatAngle 3 | Author: João Ventura (flatangleweb@gmail.com) 4 | 5 | 6 | This module provides useful for handling aspects between 7 | objects in flatlib. An aspect is an angular relation 8 | between a planet and another object. 9 | 10 | This module has the following base terminology: 11 | - Active/Passive object: The active object is the planet 12 | responsible for the aspect. 13 | - Separation: the angular distance between the active and 14 | passive object. 15 | - Orb: the orb distance (>0) between active and passive 16 | objects. 17 | - Obj.orb: is the orb allowed by the aspect. 18 | - Type: the type of the aspect. 19 | - Direction/Condition/Movement/etc. are properties of an 20 | aspect. 21 | - Movement: The objects have their movements, but the 22 | aspect movement can be also exact. 23 | 24 | Major aspects must be within orb of one of the planets. 25 | Minor aspects only when within a max allowed orb. 26 | 27 | In parameters, objA is the active object and objP is the 28 | passive object. 29 | 30 | """ 31 | 32 | from . import angle 33 | from . import const 34 | 35 | # Orb for minor and exact aspects 36 | MAX_MINOR_ASP_ORB = 3 37 | MAX_EXACT_ORB = 0.3 38 | 39 | 40 | # === Private functions === # 41 | 42 | def _orbList(obj1, obj2, aspList): 43 | """ Returns a list with the orb and angular 44 | distances from obj1 to obj2, considering a 45 | list of possible aspects. 46 | 47 | """ 48 | sep = angle.closestdistance(obj1.lon, obj2.lon) 49 | absSep = abs(sep) 50 | return [ 51 | { 52 | 'type': asp, 53 | 'orb': abs(absSep - asp), 54 | 'separation': sep, 55 | } for asp in aspList 56 | ] 57 | 58 | 59 | def _aspectDict(obj1, obj2, aspList): 60 | """ Returns the properties of the aspect of 61 | obj1 to obj2, considering a list of possible 62 | aspects. 63 | 64 | This function makes the following assumptions: 65 | - Syzygy does not start aspects but receives 66 | any aspect. 67 | - Pars Fortuna and Moon Nodes only starts 68 | conjunctions but receive any aspect. 69 | - All other objects can start and receive 70 | any aspect. 71 | 72 | Note: this function returns the aspect 73 | even if it is not within the orb of obj1 74 | (but is within the orb of obj2). 75 | 76 | """ 77 | # Ignore aspects from same and Syzygy 78 | if obj1 == obj2 or obj1.id == const.SYZYGY: 79 | return None 80 | 81 | orbs = _orbList(obj1, obj2, aspList) 82 | for aspDict in orbs: 83 | asp = aspDict['type'] 84 | orb = aspDict['orb'] 85 | 86 | # Check if aspect is within orb 87 | if asp in const.MAJOR_ASPECTS: 88 | # Ignore major aspects out of orb 89 | if obj1.orb() < orb and obj2.orb() < orb: 90 | continue 91 | else: 92 | # Ignore minor aspects out of max orb 93 | if MAX_MINOR_ASP_ORB < orb: 94 | continue 95 | 96 | # Only conjunctions for Pars Fortuna and Nodes 97 | if obj1.id in [const.PARS_FORTUNA, 98 | const.NORTH_NODE, 99 | const.SOUTH_NODE] and \ 100 | asp != const.CONJUNCTION: 101 | continue 102 | 103 | # We have a valid aspect within orb 104 | return aspDict 105 | 106 | return None 107 | 108 | 109 | def _aspectProperties(obj1, obj2, aspDict): 110 | """ Returns the properties of an aspect between 111 | obj1 and obj2, given by 'aspDict'. 112 | 113 | This function assumes obj1 to be the active object, 114 | i.e., the one responsible for starting the aspect. 115 | 116 | """ 117 | orb = aspDict['orb'] 118 | asp = aspDict['type'] 119 | sep = aspDict['separation'] 120 | 121 | # Properties 122 | prop1 = { 123 | 'id': obj1.id, 124 | 'inOrb': False, 125 | 'movement': const.NO_MOVEMENT 126 | } 127 | prop2 = { 128 | 'id': obj2.id, 129 | 'inOrb': False, 130 | 'movement': const.NO_MOVEMENT 131 | } 132 | prop = { 133 | 'type': asp, 134 | 'orb': orb, 135 | 'direction': -1, 136 | 'condition': -1, 137 | 'active': prop1, 138 | 'passive': prop2 139 | } 140 | 141 | if asp == const.NO_ASPECT: 142 | return prop 143 | 144 | # Aspect within orb 145 | prop1['inOrb'] = orb <= obj1.orb() 146 | prop2['inOrb'] = orb <= obj2.orb() 147 | 148 | # Direction 149 | prop['direction'] = const.DEXTER if sep <= 0 else const.SINISTER 150 | 151 | # Sign conditions 152 | # Note: if obj1 is before obj2, orbDir will be less than zero 153 | orbDir = sep - asp if sep >= 0 else sep + asp 154 | offset = obj1.signlon + orbDir 155 | if 0 <= offset < 30: 156 | prop['condition'] = const.ASSOCIATE 157 | else: 158 | prop['condition'] = const.DISSOCIATE 159 | 160 | # Movement of the individual objects 161 | if abs(orbDir) < MAX_EXACT_ORB: 162 | prop1['movement'] = prop2['movement'] = const.EXACT 163 | else: 164 | # Active object applies to Passive if it is before 165 | # and direct, or after the Passive and Rx.. 166 | prop1['movement'] = const.SEPARATIVE 167 | if (orbDir > 0 and obj1.isDirect()) or \ 168 | (orbDir < 0 and obj1.isRetrograde()): 169 | prop1['movement'] = const.APPLICATIVE 170 | elif obj1.isStationary(): 171 | prop1['movement'] = const.STATIONARY 172 | 173 | # The Passive applies or separates from the Active 174 | # if it has a different direction.. 175 | # Note: Non-planets have zero speed 176 | prop2['movement'] = const.NO_MOVEMENT 177 | obj2speed = obj2.lonspeed if obj2.isPlanet() else 0.0 178 | sameDir = obj1.lonspeed * obj2speed >= 0 179 | if not sameDir: 180 | prop2['movement'] = prop1['movement'] 181 | 182 | return prop 183 | 184 | 185 | def _getActivePassive(obj1, obj2): 186 | """ Returns which is the active and the passive objects. """ 187 | speed1 = abs(obj1.lonspeed) if obj1.isPlanet() else -1.0 188 | speed2 = abs(obj2.lonspeed) if obj2.isPlanet() else -1.0 189 | if speed1 > speed2: 190 | return { 191 | 'active': obj1, 192 | 'passive': obj2 193 | } 194 | else: 195 | return { 196 | 'active': obj2, 197 | 'passive': obj1 198 | } 199 | 200 | 201 | # === Public functions === # 202 | 203 | def aspectType(obj1, obj2, aspList): 204 | """ Returns the aspect type between objects considering 205 | a list of possible aspect types. 206 | 207 | """ 208 | ap = _getActivePassive(obj1, obj2) 209 | aspDict = _aspectDict(ap['active'], ap['passive'], aspList) 210 | return aspDict['type'] if aspDict else const.NO_ASPECT 211 | 212 | 213 | def hasAspect(obj1, obj2, aspList): 214 | """ Returns if there is an aspect between objects 215 | considering a list of possible aspect types. 216 | 217 | """ 218 | aspType = aspectType(obj1, obj2, aspList) 219 | return aspType != const.NO_ASPECT 220 | 221 | 222 | def isAspecting(obj1, obj2, aspList): 223 | """ Returns if obj1 aspects obj2 within its orb, 224 | considering a list of possible aspect types. 225 | 226 | """ 227 | aspDict = _aspectDict(obj1, obj2, aspList) 228 | if aspDict: 229 | return aspDict['orb'] < obj1.orb() 230 | return False 231 | 232 | 233 | def getAspect(obj1, obj2, aspList): 234 | """ Returns an Aspect object for the aspect between two 235 | objects considering a list of possible aspect types. 236 | 237 | """ 238 | ap = _getActivePassive(obj1, obj2) 239 | aspDict = _aspectDict(ap['active'], ap['passive'], aspList) 240 | if not aspDict: 241 | aspDict = { 242 | 'type': const.NO_ASPECT, 243 | 'orb': 0, 244 | 'separation': 0, 245 | } 246 | aspProp = _aspectProperties(ap['active'], ap['passive'], aspDict) 247 | return Aspect(aspProp) 248 | 249 | 250 | # ---------------- # 251 | # Aspect Class # 252 | # ---------------- # 253 | 254 | class AspectObject: 255 | """ Dummy class to represent the Active and 256 | Passive objects and to allow access to their 257 | properties using the dot notation. 258 | 259 | """ 260 | 261 | def __init__(self, properties): 262 | self.__dict__.update(properties) 263 | 264 | 265 | class Aspect: 266 | """ This class represents an aspect with all 267 | its properties. 268 | 269 | """ 270 | 271 | def __init__(self, properties): 272 | self.__dict__.update(properties) 273 | self.active = AspectObject(self.active) 274 | self.passive = AspectObject(self.passive) 275 | 276 | def exists(self): 277 | """ Returns if this aspect is valid. """ 278 | return self.type != const.NO_ASPECT 279 | 280 | def movement(self): 281 | """ Returns the movement of this aspect. 282 | The movement is the one of the active object, except 283 | if the active is separating but within less than 1 284 | degree. 285 | 286 | """ 287 | mov = self.active.movement 288 | if self.orb < 1 and mov == const.SEPARATIVE: 289 | mov = const.EXACT 290 | return mov 291 | 292 | def mutualAspect(self): 293 | """ Returns if both object are within aspect orb. """ 294 | return self.active.inOrb == self.passive.inOrb == True 295 | 296 | def mutualMovement(self): 297 | """ Returns if both objects are mutually applying or 298 | separating. 299 | 300 | """ 301 | return self.active.movement == self.passive.movement 302 | 303 | def getRole(self, ID): 304 | """ Returns the role (active or passive) of an object 305 | in this aspect. 306 | 307 | """ 308 | if self.active.id == ID: 309 | return { 310 | 'role': 'active', 311 | 'inOrb': self.active.inOrb, 312 | 'movement': self.active.movement 313 | } 314 | elif self.passive.id == ID: 315 | return { 316 | 'role': 'passive', 317 | 'inOrb': self.passive.inOrb, 318 | 'movement': self.passive.movement 319 | } 320 | return None 321 | 322 | def inOrb(self, ID): 323 | """ Returns if the object (given by ID) is within orb 324 | in the Aspect. 325 | 326 | """ 327 | role = self.getRole(ID) 328 | return role['inOrb'] if role else None 329 | 330 | def __str__(self): 331 | return '<%s %s %s %s %s>' % (self.active.id, 332 | self.passive.id, 333 | self.type, 334 | self.active.movement, 335 | angle.toString(self.orb)) 336 | -------------------------------------------------------------------------------- /flatlib/chart.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is part of flatlib - (C) FlatAngle 3 | Author: João Ventura (flatangleweb@gmail.com) 4 | 5 | 6 | This module implements a class to represent an 7 | astrology Chart. It provides methods to handle 8 | the chart, as well as three relevant properties: 9 | 10 | - objects: a list with the chart's objects 11 | - houses: a list with the chart's houses 12 | - angles: a list with the chart's angles 13 | 14 | Since houses 1 and 10 may not match the Asc and 15 | MC in some house systems, the Chart class 16 | includes the list of angles. The angles should be 17 | used when you want to deal with angle's longitudes. 18 | 19 | There are also methods to access fixed stars. 20 | 21 | """ 22 | 23 | from . import angle 24 | from . import const 25 | from . import utils 26 | from .ephem import ephem 27 | from .datetime import Datetime 28 | 29 | 30 | # ------------------ # 31 | # Chart Class # 32 | # ------------------ # 33 | 34 | class Chart: 35 | """ This class represents an astrology chart. """ 36 | 37 | def __init__(self, date, pos, **kwargs): 38 | """ Creates an astrology chart for a given 39 | date and location. 40 | 41 | Optional arguments are: 42 | - hsys: house system 43 | - IDs: list of objects to include 44 | 45 | """ 46 | # Handle optional arguments 47 | hsys = kwargs.get('hsys', const.HOUSES_DEFAULT) 48 | IDs = kwargs.get('IDs', const.LIST_OBJECTS_TRADITIONAL) 49 | 50 | self.date = date 51 | self.pos = pos 52 | self.hsys = hsys 53 | self.objects = ephem.getObjectList(IDs, date, pos) 54 | self.houses, self.angles = ephem.getHouses(date, pos, hsys) 55 | 56 | def copy(self): 57 | """ Returns a deep copy of this chart. """ 58 | chart = Chart.__new__(Chart) 59 | chart.date = self.date 60 | chart.pos = self.pos 61 | chart.hsys = self.hsys 62 | chart.objects = self.objects.copy() 63 | chart.houses = self.houses.copy() 64 | chart.angles = self.angles.copy() 65 | return chart 66 | 67 | # === Properties === # 68 | 69 | def getObject(self, ID): 70 | """ Returns an object from the chart. """ 71 | return self.objects.get(ID) 72 | 73 | def getHouse(self, ID): 74 | """ Returns an house from the chart. """ 75 | return self.houses.get(ID) 76 | 77 | def getAngle(self, ID): 78 | """ Returns an angle from the chart. """ 79 | return self.angles.get(ID) 80 | 81 | def get(self, ID): 82 | """ Returns an object, house or angle 83 | from the chart. 84 | 85 | """ 86 | if ID.startswith('House'): 87 | return self.getHouse(ID) 88 | elif ID in const.LIST_ANGLES: 89 | return self.getAngle(ID) 90 | else: 91 | return self.getObject(ID) 92 | 93 | # === Fixed stars === # 94 | 95 | # The computation of fixed stars is inefficient, 96 | # so the access must be made directly to the 97 | # ephemeris only when needed. 98 | 99 | def getFixedStar(self, ID): 100 | """ Returns a fixed star from the ephemeris. """ 101 | return ephem.getFixedStar(ID, self.date) 102 | 103 | def getFixedStars(self): 104 | """ Returns a list with all fixed stars. """ 105 | IDs = const.LIST_FIXED_STARS 106 | return ephem.getFixedStarList(IDs, self.date) 107 | 108 | # === Houses and angles === # 109 | 110 | def isHouse1Asc(self): 111 | """ Returns true if House1 is the same as the Asc. """ 112 | house1 = self.getHouse(const.HOUSE1) 113 | asc = self.getAngle(const.ASC) 114 | dist = angle.closestdistance(house1.lon, asc.lon) 115 | return abs(dist) < 0.0003 # 1 arc-second 116 | 117 | def isHouse10MC(self): 118 | """ Returns true if House10 is the same as the MC. """ 119 | house10 = self.getHouse(const.HOUSE10) 120 | mc = self.getAngle(const.MC) 121 | dist = angle.closestdistance(house10.lon, mc.lon) 122 | return abs(dist) < 0.0003 # 1 arc-second 123 | 124 | # === Other properties === # 125 | 126 | def isDiurnal(self): 127 | """ Returns true if this chart is diurnal. """ 128 | sun = self.getObject(const.SUN) 129 | mc = self.getAngle(const.MC) 130 | 131 | # Get ecliptical positions and check if the 132 | # sun is above the horizon. 133 | lat = self.pos.lat 134 | sunRA, sunDecl = utils.eqCoords(sun.lon, sun.lat) 135 | mcRA, mcDecl = utils.eqCoords(mc.lon, 0) 136 | return utils.isAboveHorizon(sunRA, sunDecl, mcRA, lat) 137 | 138 | def getMoonPhase(self): 139 | """ Returns the phase of the moon. """ 140 | sun = self.getObject(const.SUN) 141 | moon = self.getObject(const.MOON) 142 | dist = angle.distance(sun.lon, moon.lon) 143 | if dist < 90: 144 | return const.MOON_FIRST_QUARTER 145 | elif dist < 180: 146 | return const.MOON_SECOND_QUARTER 147 | elif dist < 270: 148 | return const.MOON_THIRD_QUARTER 149 | else: 150 | return const.MOON_LAST_QUARTER 151 | 152 | # === Solar returns === # 153 | 154 | def solarReturn(self, year): 155 | """ Returns this chart's solar return for a 156 | given year. 157 | 158 | """ 159 | sun = self.getObject(const.SUN) 160 | date = Datetime('{0}/01/01'.format(year), 161 | '00:00', 162 | self.date.utcoffset) 163 | srDate = ephem.nextSolarReturn(date, sun.lon) 164 | return Chart(srDate, self.pos, hsys=self.hsys) 165 | -------------------------------------------------------------------------------- /flatlib/const.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is part of flatlib - (C) FlatAngle 3 | Author: João Ventura (flatangleweb@gmail.com) 4 | 5 | 6 | This module defines the names of signs, objects, angles, 7 | houses and fixed-stars used in the library. 8 | 9 | """ 10 | 11 | # === Base constants === */ 12 | 13 | # Four primitive qualities 14 | HOT = 'Hot' 15 | COLD = 'Cold' 16 | DRY = 'Dry' 17 | HUMID = 'Humid' 18 | 19 | # Four Elements 20 | FIRE = 'Fire' 21 | EARTH = 'Earth' 22 | AIR = 'Air' 23 | WATER = 'Water' 24 | 25 | # Four Temperaments 26 | CHOLERIC = 'Choleric' 27 | MELANCHOLIC = 'Melancholic' 28 | SANGUINE = 'Sanguine' 29 | PHLEGMATIC = 'Phlegmatic' 30 | 31 | # Genders 32 | MASCULINE = 'Masculine' 33 | FEMININE = 'Feminine' 34 | NEUTRAL = 'Neutral' 35 | 36 | # Factions 37 | DIURNAL = 'Diurnal' 38 | NOCTURNAL = 'Nocturnal' 39 | 40 | # Sun seasons 41 | SPRING = 'Spring' 42 | SUMMER = 'Summer' 43 | AUTUMN = 'Autumn' 44 | WINTER = 'Winter' 45 | 46 | # Moon Quarters 47 | MOON_FIRST_QUARTER = 'First Quarter' 48 | MOON_SECOND_QUARTER = 'Second Quarter' 49 | MOON_THIRD_QUARTER = 'Third Quarter' 50 | MOON_LAST_QUARTER = 'Last Quarter' 51 | 52 | # === Signs === */ 53 | 54 | ARIES = 'Aries' 55 | TAURUS = 'Taurus' 56 | GEMINI = 'Gemini' 57 | CANCER = 'Cancer' 58 | LEO = 'Leo' 59 | VIRGO = 'Virgo' 60 | LIBRA = 'Libra' 61 | SCORPIO = 'Scorpio' 62 | SAGITTARIUS = 'Sagittarius' 63 | CAPRICORN = 'Capricorn' 64 | AQUARIUS = 'Aquarius' 65 | PISCES = 'Pisces' 66 | 67 | # Sign modes 68 | CARDINAL = 'Cardinal' 69 | FIXED = 'Fixed' 70 | MUTABLE = 'Mutable' 71 | 72 | # Sign figures 73 | SIGN_FIGURE_NONE = 'None' 74 | SIGN_FIGURE_BEAST = 'Beast' 75 | SIGN_FIGURE_HUMAN = 'Human' 76 | SIGN_FIGURE_WILD = 'Wild' 77 | 78 | # Sign fertilities 79 | SIGN_FERTILE = 'Fertile' 80 | SIGN_STERILE = 'Sterile' 81 | SIGN_MODERATELY_FERTILE = 'Moderately Fertile' 82 | SIGN_MODERATELY_STERILE = 'Moderately Sterile' 83 | 84 | # === Objects === */ 85 | 86 | # Names 87 | SUN = 'Sun' 88 | MOON = 'Moon' 89 | MERCURY = 'Mercury' 90 | VENUS = 'Venus' 91 | MARS = 'Mars' 92 | JUPITER = 'Jupiter' 93 | SATURN = 'Saturn' 94 | URANUS = 'Uranus' 95 | NEPTUNE = 'Neptune' 96 | PLUTO = 'Pluto' 97 | CHIRON = 'Chiron' 98 | NORTH_NODE = 'North Node' 99 | SOUTH_NODE = 'South Node' 100 | SYZYGY = 'Syzygy' 101 | PARS_FORTUNA = 'Pars Fortuna' 102 | NO_PLANET = 'None' 103 | 104 | # Object movement 105 | DIRECT = 'Direct' 106 | RETROGRADE = 'Retrograde' 107 | STATIONARY = 'Stationary' 108 | 109 | # Mean daily motions 110 | MEAN_MOTION_SUN = 0.9833 111 | MEAN_MOTION_MOON = 13.1833 112 | 113 | # Object type 114 | OBJ_PLANET = 'Planet' 115 | OBJ_HOUSE = 'House' 116 | OBJ_MOON_NODE = 'Moon Node' 117 | OBJ_ARABIC_PART = 'Arabic Part' 118 | OBJ_FIXED_STAR = 'Fixed Star' 119 | OBJ_ASTEROID = 'Asteroid' 120 | OBJ_LUNATION = 'Lunation' 121 | OBJ_GENERIC = 'Generic' 122 | 123 | # === Houses === */ 124 | 125 | HOUSE1 = 'House1' 126 | HOUSE2 = 'House2' 127 | HOUSE3 = 'House3' 128 | HOUSE4 = 'House4' 129 | HOUSE5 = 'House5' 130 | HOUSE6 = 'House6' 131 | HOUSE7 = 'House7' 132 | HOUSE8 = 'House8' 133 | HOUSE9 = 'House9' 134 | HOUSE10 = 'House10' 135 | HOUSE11 = 'House11' 136 | HOUSE12 = 'House12' 137 | 138 | # House conditions 139 | ANGULAR = 'Angular' 140 | SUCCEDENT = 'Succedent' 141 | CADENT = 'Cadent' 142 | 143 | # Benefic/Malefic houses 144 | HOUSES_BENEFIC = [HOUSE1, HOUSE5, HOUSE11] 145 | HOUSES_MALEFIC = [HOUSE6, HOUSE12] 146 | 147 | # House Systems 148 | HOUSES_PLACIDUS = 'Placidus' 149 | HOUSES_KOCH = 'Koch' 150 | HOUSES_PORPHYRIUS = 'Porphyrius' 151 | HOUSES_REGIOMONTANUS = 'Regiomontanus' 152 | HOUSES_CAMPANUS = 'Campanus' 153 | HOUSES_EQUAL = 'Equal' 154 | HOUSES_EQUAL_2 = 'Equal 2' 155 | HOUSES_VEHLOW_EQUAL = 'Vehlow Equal' 156 | HOUSES_WHOLE_SIGN = 'Whole Sign' 157 | HOUSES_MERIDIAN = 'Meridian' 158 | HOUSES_AZIMUTHAL = 'Azimuthal' 159 | HOUSES_POLICH_PAGE = 'Polich Page' 160 | HOUSES_ALCABITUS = 'Alcabitus' 161 | HOUSES_MORINUS = 'Morinus' 162 | HOUSES_DEFAULT = HOUSES_ALCABITUS 163 | 164 | # === Angles === */ 165 | 166 | ASC = 'Asc' 167 | DESC = 'Desc' 168 | MC = 'MC' 169 | IC = 'IC' 170 | 171 | # === Fixed Stars === */ 172 | 173 | STAR_ALGENIB = 'Algenib' 174 | STAR_ALPHERATZ = 'Alpheratz' 175 | STAR_ALGOL = 'Algol' 176 | STAR_ALCYONE = 'Alcyone' 177 | STAR_PLEIADES = STAR_ALCYONE 178 | STAR_ALDEBARAN = 'Aldebaran' 179 | STAR_RIGEL = 'Rigel' 180 | STAR_CAPELLA = 'Capella' 181 | STAR_BETELGEUSE = 'Betelgeuse' 182 | STAR_SIRIUS = 'Sirius' 183 | STAR_CANOPUS = 'Canopus' 184 | STAR_CASTOR = 'Castor' 185 | STAR_POLLUX = 'Pollux' 186 | STAR_PROCYON = 'Procyon' 187 | STAR_ASELLUS_BOREALIS = 'Asellus Borealis' 188 | STAR_ASELLUS_AUSTRALIS = 'Asellus Australis' 189 | STAR_ALPHARD = 'Alphard' 190 | STAR_REGULUS = 'Regulus' 191 | STAR_DENEBOLA = 'Denebola' 192 | STAR_ALGORAB = 'Algorab' 193 | STAR_SPICA = 'Spica' 194 | STAR_ARCTURUS = 'Arcturus' 195 | STAR_ALPHECCA = 'Alphecca' 196 | STAR_ZUBEN_ELGENUBI = 'Zuben Elgenubi' 197 | STAR_ZUBEN_ELSCHEMALI = 'Zuben Eshamali' 198 | STAR_UNUKALHAI = 'Unukalhai' 199 | STAR_AGENA = 'Agena' 200 | STAR_RIGEL_CENTAURUS = 'Rigel Kentaurus' 201 | STAR_ANTARES = 'Antares' 202 | STAR_LESATH = 'Lesath' 203 | STAR_VEGA = 'Vega' 204 | STAR_ALTAIR = 'Altair' 205 | STAR_DENEB_ALGEDI = 'Deneb Algedi' 206 | STAR_FOMALHAUT = 'Fomalhaut' 207 | STAR_DENEB_ADIGE = 'Deneb' # Alpha-Cygnus 208 | STAR_ACHERNAR = 'Achernar' 209 | 210 | # === Aspects === */ 211 | 212 | # Major Aspects 213 | NO_ASPECT = -1 214 | CONJUNCTION = 0 215 | SEXTILE = 60 216 | SQUARE = 90 217 | TRINE = 120 218 | OPPOSITION = 180 219 | 220 | # Minor Aspects 221 | SEMISEXTILE = 30 222 | SEMIQUINTILE = 36 223 | SEMISQUARE = 45 224 | QUINTILE = 72 225 | SESQUIQUINTILE = 108 226 | SESQUISQUARE = 135 227 | BIQUINTILE = 144 228 | QUINCUNX = 150 229 | 230 | # Aspect movement 231 | APPLICATIVE = 'Applicative' 232 | SEPARATIVE = 'Separative' 233 | EXACT = 'Exact' 234 | NO_MOVEMENT = 'None' 235 | 236 | # Aspect direction 237 | DEXTER = 'Dexter' # Right side 238 | SINISTER = 'Sinister' # Left side 239 | 240 | # Aspect properties 241 | ASSOCIATE = 'Associate' 242 | DISSOCIATE = 'Dissociate' 243 | 244 | # Aspect lists 245 | MAJOR_ASPECTS = [0, 60, 90, 120, 180] 246 | MINOR_ASPECTS = [30, 36, 45, 72, 108, 135, 144, 150] 247 | ALL_ASPECTS = MAJOR_ASPECTS + MINOR_ASPECTS 248 | 249 | # === Some Lists === */ 250 | 251 | LIST_SIGNS = [ 252 | ARIES, TAURUS, GEMINI, CANCER, LEO, VIRGO, LIBRA, 253 | SCORPIO, SAGITTARIUS, CAPRICORN, AQUARIUS, PISCES 254 | ] 255 | 256 | LIST_OBJECTS = [ 257 | SUN, MOON, MERCURY, VENUS, MARS, JUPITER, SATURN, 258 | URANUS, NEPTUNE, PLUTO, CHIRON, NORTH_NODE, 259 | SOUTH_NODE, SYZYGY, PARS_FORTUNA, 260 | ] 261 | 262 | LIST_OBJECTS_TRADITIONAL = [ 263 | SUN, MOON, MERCURY, VENUS, MARS, JUPITER, SATURN, 264 | NORTH_NODE, SOUTH_NODE, SYZYGY, PARS_FORTUNA 265 | ] 266 | 267 | LIST_SEVEN_PLANETS = [ 268 | SUN, MOON, MERCURY, VENUS, MARS, JUPITER, SATURN 269 | ] 270 | 271 | LIST_HOUSES = [ 272 | HOUSE1, HOUSE2, HOUSE3, HOUSE4, HOUSE5, HOUSE6, 273 | HOUSE7, HOUSE8, HOUSE9, HOUSE10, HOUSE11, HOUSE12, 274 | ] 275 | 276 | LIST_ANGLES = [ 277 | ASC, MC, DESC, IC 278 | ] 279 | 280 | LIST_FIXED_STARS = [ 281 | STAR_ALGENIB, STAR_ALPHERATZ, STAR_ALGOL, STAR_ALCYONE, 282 | STAR_PLEIADES, STAR_ALDEBARAN, STAR_RIGEL, STAR_CAPELLA, 283 | STAR_BETELGEUSE, STAR_SIRIUS, STAR_CANOPUS, STAR_CASTOR, 284 | STAR_POLLUX, STAR_PROCYON, STAR_ASELLUS_BOREALIS, 285 | STAR_ASELLUS_AUSTRALIS, STAR_ALPHARD, STAR_REGULUS, 286 | STAR_DENEBOLA, STAR_ALGORAB, STAR_SPICA, STAR_ARCTURUS, 287 | STAR_ALPHECCA, STAR_ZUBEN_ELSCHEMALI, STAR_UNUKALHAI, 288 | STAR_AGENA, STAR_RIGEL_CENTAURUS, STAR_ANTARES, 289 | STAR_LESATH, STAR_VEGA, STAR_ALTAIR, STAR_DENEB_ALGEDI, 290 | STAR_FOMALHAUT, STAR_DENEB_ADIGE, STAR_ACHERNAR, 291 | ] 292 | -------------------------------------------------------------------------------- /flatlib/datetime.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is part of flatlib - (C) FlatAngle 3 | Author: João Ventura (flatangleweb@gmail.com) 4 | 5 | 6 | This module provides functions and classes for handling 7 | dates and times. 8 | 9 | The classes implemented in this file are ,