I CHING Divination
Download worked project
The I Ching, or Book of Changes, is a chinese divination manual and philosophical text which is believed to be one of the world’s oldest books, dating from over 3,000 years ago.
The great mathematician Gottfried Wilhelm Leibniz (1646 - 1716) is considered the first information theorist, and extensively documented the binary numeral system. Leibniz was also interested in Chinese culture, and saw in the I Ching diagrams showing solid and broken lines called yin and yang, which progressed in a sequence: that was unmistakably a binary encoding.
You will parse a dataset of hexagrams and develop a divinator software which will predict the outcome of your exams.
Data source: Wikipedia, July 2021, Bagua page
What to do
Unzip exercises zip in a folder, you should obtain something like this:
iching-prj
iching.ipynb
iching-sol.ipynb
iching.csv
jupman.py
WARNING: to correctly visualize the notebook, it MUST be in an unzipped folder !
open Jupyter Notebook from that folder. Two things should open, first a console and then a browser. The browser should show a file list: navigate the list and open the notebook
iching.ipynb
Go on reading the notebook, and write in the appropriate cells when asked
Shortcut keys:
to execute Python code inside a Jupyter cell, press
Control + Enter
to execute Python code inside a Jupyter cell AND select next cell, press
Shift + Enter
to execute Python code inside a Jupyter cell AND a create a new cell aftwerwards, press
Alt + Enter
If the notebooks look stuck, try to select
Kernel -> Restart
The dataset
Yin and yang: Yin and yang are represented by lines:
name |
line |
bit |
---|---|---|
yin |
|
0 |
yang |
|
1 |
Trigrams: Different constructions of three yin and yang lines lead to 8 trigrams. We can express a trigram as a sequence of bits, reading lines from bottom to top. For example Fire is 101
, Thunder is 100
.
Hexagrams: Combining a lower trigram with an upper trigram leads to 64 hexagrams. Each hexagram can be represented as a sequence of bits and the outcome of a divination. For example trigrams Fire (lower) and Thunder (upper) gives outcome hexagram Abounding: 101100
1. load_db
Parse iching.csv and output a dictionary mapping each sequence to a dictionary with all the information you can extract. Use CSV reader.
in headers and first column you will find a bit sequence like
011
in body cells, you will not find a bit sequence: you will have to determine it according to the corresponding tri-sequences from the header and first column
note for hexagrams you must extract only
name-en
, ignore the decimal numbers
Example (complete output is in file expected_iching_db.py):
>>> load_db('iching.csv')
{
'111': {'name-en': 'Heaven', 'name-ch': '乾', 'spelling': 'Qián'}
'000': {'name-en': 'Earth', 'name-ch': '坤', 'spelling': 'Kūn'}
'100': {'name-en': 'Thunder', 'name-ch': '震', 'spelling': 'Zhèn'}
'010': {'name-en': 'Water', 'name-ch': '坎', 'spelling': 'Kǎn'}
'001': {'name-en': 'Mountain', 'name-ch': '艮', 'spelling': 'Gèn'}
'011': {'name-en': 'Air', 'name-ch': '巽', 'spelling': 'Xùn'}
'101': {'name-en': 'Fire', 'name-ch': '離', 'spelling': 'Lí'}
'110': {'name-en': 'Lake', 'name-ch': '兌', 'spelling': 'Duì'}
'111111': {'name-en': 'Force'}
'111000': {'name-en': 'Pervading'}
'111100': {'name-en': 'Great Invigorating'}
'111010': {'name-en': 'Attending'}
'111001': {'name-en': 'Great Accumulating'}
'111011': {'name-en': 'Small Harvest'}
'111101': {'name-en': 'Great Possessing'}
.
.
}
[1]:
import csv
def load_db(filepath):
raise Exception('TODO IMPLEMENT ME !')
iching_db = load_db('iching.csv')
iching_db
[3]:
# EXECUTE FOR TESTING
from pprint import pformat; from expected_iching_db import expected_iching_db
for seq in expected_iching_db.keys():
if seq not in iching_db: print('\nERROR: MISSING sequence', seq); break
for k in expected_iching_db[seq]:
if k not in iching_db[seq]:
print('\nERROR at sequence', seq,'\n\n MISSING key:', k); break
if expected_iching_db[seq][k] != iching_db[seq][k]:
print('\nERROR at sequence', seq, 'key:',k)
print(' ACTUAL:\n', pformat(iching_db[seq][k]))
print(' EXPECTED:\n', pformat(expected_iching_db[seq][k]))
break
2. divine
A divination is done by flipping 3 coins to determine the bottom trigram (bottom up order), flipping other three coins for the upper trigram (again bottom up order), and then the union gives the resulting hexagram. Write a function that PRINTS the process as in the example and RETURNS a string of bits representing the resulting hexagram.
try to avoid writing duplicated code
HINT: to flip coins use
random.randint(0,1)
WARNING: DOUBLE CHECK THE ORDER IN WHICH LINES ARE VISUALIZED!
Example:
>>> divination = divine(iching_db, "Will I pass the exam?")
>>> print("\nRETURNED:", divination)
Dear stranger, welcome to SOFTPYTHON I CHING 易經 DIVINATOR
Tell me your question...
Will I pass the exam?
The coin says 'heads' : we get a yang ---
The coin says 'tails' : we get a yin - -
The coin says 'heads' : we get a yang ---
The sacred bottom trigram is:
Fire
---
- -
---
The coin says 'heads' : we get a yang ---
The coin says 'tails' : we get a yin - -
The coin says 'tails' : we get a yin - -
The sacred upper trigram is:
Thunder
- -
- -
---
The final response hexagram is...
Abounding
- -
- -
---
---
- -
---
RETURNED: 101100
[4]:
import random
def divine(iching, question):
#THE SEED DETERMINES FOLLOWING randint RESULTS
random.seed(109) # Abounding
# Thunder
# Fire
#IMPORTANT: try also this seed to check lines visualization order
#random.seed(1)
#
# Infiltrating 001011
# Air ---
# ---
# - -
# Mountain ---
# - -
# - -
raise Exception('TODO IMPLEMENT ME !')
divination = divine(iching_db, "Will I pass the exam?")
print("\nRETURNED:", divination)
3. plot_divination
Given a divination as a string of bits, plot the divination.
first draw the lines, then the rest if you have time.
make it fancy with these examples
to center text you can use these parameters:
ha='center', va='center'
[5]:
%matplotlib inline
import matplotlib.pyplot as plt
def plot_divination(iching, question, divination):
raise Exception('TODO IMPLEMENT ME !')
plot_divination(iching_db, "Will I pass programming exam?", '101100') # Abounding
#plot_divination(iching_db, "Will I pass programming exam?", '111011') # Small Harvest
#plot_divination(iching_db, "Will I pass programming exam?",'001011') # Infiltrating