xander_bakker

Japanese visual multiplication with lines using arcpy

Blog Post created by xander_bakker on Jul 3, 2014

Today I stumbled upon a tweet showing how children in Japan are using line intersections to calculate the multiplication of two numbers. I was amazed by the beauty of the method which can be extended to larger numbers too.  Just take a look at the example below:

 

Japanese-Multiplication-Trick.jpg

Source: http://www.pinpopular.com/japanese-multiplication-trick-pinterest-education/

 

It is basically counting intersections of lines. Wait ... intersections of lines ... sounds to me that arcpy could do that too. So, why not write some arcpy / python code to multiply 2 numbers?

 

I know, what you're thinking ... why? Because it's fun and completely useless!

 

So this is what I came up with:

 

# Japanese visual multiplication with arcpy
import arcpy
import os

ws = r"C:\Forum\JapaneseMultiply\fgdb\test.gdb"
arcpy.env.workspace = ws
arcpy.env.overwriteOutput = True

sr = arcpy.SpatialReference(3857)
arcpy.env.outputCoordinateSystem = sr

# values to multiply:
value1 = 47 # (1 -99)
value2 = 63 # (1 -99)

fc_points = "points"
fc_lines_h = "lines_h"
fc_lines_v = "lines_v"
fc_polygones = "polygons"
fc_result = "result"
size = 10
fld_factor = "factor"

val_h1 = value1 / 10
val_h2 = value1 % 10
val_v1 = value2 / 10
val_v2 = value2 % 10

# create horizontal lines
arcpy.CreateFeatureclass_management(ws, fc_lines_h, "POLYLINE", "#", "DISABLED", "DISABLED", sr)
with arcpy.da.InsertCursor(fc_lines_h, ("SHAPE@")) as rows:
    for y in range(1, val_h1 + 1):
        x1 = -1 * size
        x2 = size
        array = arcpy.Array([arcpy.Point(x1, y),
                     arcpy.Point(x2, y)])
        polyline = arcpy.Polyline(array)
        rows.insertRow([polyline])

    for y in range(1, val_h2 + 1):
        x1 = -1 * size
        x2 = size
        array = arcpy.Array([arcpy.Point(x1, -1 * y),
                     arcpy.Point(x2, -1 * y)])
        polyline = arcpy.Polyline(array)
        rows.insertRow([polyline])


# create vertical lines
arcpy.CreateFeatureclass_management(ws, fc_lines_v, "POLYLINE", "#", "DISABLED", "DISABLED", sr)
with arcpy.da.InsertCursor(fc_lines_v, ("SHAPE@")) as rows:
    for x in range(1, val_v1 + 1):
        y1 = -1 * size
        y2 = size
        array = arcpy.Array([arcpy.Point(-1 * x, y1),
                     arcpy.Point(-1 * x, y2)])
        polyline = arcpy.Polyline(array)
        rows.insertRow([polyline])

    for x in range(1, val_v2 + 1):
        y1 = -1 * size
        y2 = size
        array = arcpy.Array([arcpy.Point(x, y1),
                     arcpy.Point(x, y2)])
        polyline = arcpy.Polyline(array)
        rows.insertRow([polyline])


# Create polygon cuadrants
arcpy.CreateFeatureclass_management(ws, fc_polygones, "POLYGON", "#", "DISABLED", "DISABLED", sr)
arcpy.AddField_management(fc_polygones, fld_factor, "DOUBLE")
with arcpy.da.InsertCursor(fc_polygones, ("SHAPE@", fld_factor)) as rows:
    # left top factor 100
    factor = 100
    array = arcpy.Array([arcpy.Point(-1 * size, 0),
                         arcpy.Point(-1 * size, size),
                         arcpy.Point(0, size),
                         arcpy.Point(0, 0),
                         arcpy.Point(-1 * size, 0)])
    polygon = arcpy.Polygon(array)
    rows.insertRow([polygon, factor])

    # right top factor 10
    factor = 10
    array = arcpy.Array([arcpy.Point(0, 0),
                         arcpy.Point(0, size),
                         arcpy.Point(size, size),
                         arcpy.Point(size, 0),
                         arcpy.Point(0, 0)])
    polygon = arcpy.Polygon(array)
    rows.insertRow([polygon, factor])

    # left bottom factor 10
    factor = 10
    array = arcpy.Array([arcpy.Point(-1 * size, -1 * size),
                         arcpy.Point(-1 * size, 0),
                         arcpy.Point(0, 0),
                         arcpy.Point(0, -1 * size),
                         arcpy.Point(-1 * size, -1 * size)])
    polygon = arcpy.Polygon(array)
    rows.insertRow([polygon, factor])

    # right bottom factor 1
    factor = 1
    array = arcpy.Array([arcpy.Point(0, 0),
                         arcpy.Point(0, -1 * size),
                         arcpy.Point(size, -1 * size),
                         arcpy.Point(size, 0),
                         arcpy.Point(0, 0)])
    polygon = arcpy.Polygon(array)
    rows.insertRow([polygon, factor])


# start analysis: intersect horizontal and vertical lines
arcpy.Intersect_analysis([fc_lines_h, fc_lines_v], fc_points, "ALL", "", "POINT")

# Next intersect the polygon with the points (intersection of lines)
arcpy.Intersect_analysis([fc_polygones, fc_points], fc_result)

# now use Search cursor to get result
res = 0
with arcpy.da.SearchCursor(fc_result, (fld_factor)) as rows:
    for row in rows:
        factor = row[0]
        res += factor


print "{0} * {1} = {2}".format(value1, value2, res)
print "verify: {0} * {1} = {2}".format(value1, value2, value1 * value2)


 

In the example above the following result is printed:

 

47 * 63 = 2961.0

verify: 47 * 63 = 2961

 

Displaying the featureclasses gives the following result:

result.png

 

I hope my next blog post will be of more use.

 

Xander

Outcomes