I CHING Divination

Download worked project

Browse files online

expected-plot-Will-I-pass-programming-exam-101100-preview

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

  1. 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 !

  1. 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

  2. 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.

iching-lookup-table-header.png

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

iching-lookup-table.png

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'}
     .
     .
}
Show solution
[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

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
Show solution
[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
    # Mountain ---
    #          ---
    #          - -
    # Air      ---
    #          - -
    #          - -

    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'

expected-plot-Will-I-pass-programming-exam-101100.png

Show solution
[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