I CHING Divination

Download worked project

Browse files online


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:


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:





- -





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'}
Show solution
import csv

def load_db(filepath):
    raise Exception('TODO IMPLEMENT ME !')

iching_db = load_db('iching.csv')

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]))

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)



>>> 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:


   - -

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:


   - -
   - -

The final response hexagram is...


   - -
   - -
   - -

RETURNED: 101100
Show solution

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'


Show solution

%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