Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/PascalTriangle.activity/pascaltriangle.py
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2013-08-16 20:09:44 (GMT)
committer Philip Withnall <philip@tecnocode.co.uk>2013-08-16 20:09:44 (GMT)
commitccf35761bca15c7f3524f3c38de820c9a05b9ec7 (patch)
treede4388b457a0b05a2ba930f700ac686edcc5a24a /PascalTriangle.activity/pascaltriangle.py
parentde301fe72296f113da2439d859cd73ea244c0151 (diff)
Implement drawing a Pascal triangle
This uses very basic graphics and is not yet interactive.
Diffstat (limited to 'PascalTriangle.activity/pascaltriangle.py')
-rwxr-xr-xPascalTriangle.activity/pascaltriangle.py60
1 files changed, 59 insertions, 1 deletions
diff --git a/PascalTriangle.activity/pascaltriangle.py b/PascalTriangle.activity/pascaltriangle.py
index 825fc9f..2acd364 100755
--- a/PascalTriangle.activity/pascaltriangle.py
+++ b/PascalTriangle.activity/pascaltriangle.py
@@ -26,10 +26,68 @@ class PascalTriangleActivity(activity.Activity):
# The final step is to display this newly created widget.
self.drawing_area.show()
+ # Set the initial size of the Pascal triangle to be drawn. This is
+ # the number of cells on its base (equivalently, the number of rows in
+ # the triangle).
+ self.triangle_size = 5
+
+
+ """
+ Calculate the Pascal number for the (row, column) cell, where row and column
+ are both 0-based. This is equivalent to calculating the Binomial coefficient
+ of (row choose column).
+ """
+ def _calculate_pascal_number(self, row, column):
+ num = math.factorial(row)
+ denom = math.factorial(column) * math.factorial(row - column)
+ return num / denom
+
def _drawing_area_button_press_cb(self, widget, event, data = None):
pass
def _drawing_area_draw_cb(self, widget, ctx, data = None):
- return False
+ # Default sizes (Cairo units).
+ padding = 10.0
+
+ # Widget allocation.
+ widget_height = widget.get_allocated_height()
+ base_width = widget.get_allocated_width() - 2.0 * padding
+ triangle_height = widget_height - 2.0 * padding
+ cell_width = base_width / self.triangle_size
+ cell_height = triangle_height / self.triangle_size
+
+ # Draw the triangle rows from the top down. The row_order is the number
+ # of cells in the row (increasing from 1 to triangle_size, inclusive).
+ row_order = 1
+ # X position of the first cell on the row
+ cell_start_x = padding + base_width / 2.0 - cell_width / 2.0
+
+ for row_index in range(self.triangle_size):
+ for column_index in range(row_order):
+ # Calculate the cell position. Add an offset every odd row so
+ # the triangle is balanced.
+ cell_x = cell_start_x + cell_width * column_index
+ cell_y = padding + cell_height * row_index
+
+ # Draw the cell and fill it.
+ ctx.rectangle(cell_x, cell_y, cell_width, cell_height)
+ ctx.set_source_rgb(0.0, 0.0, 0.0)
+ ctx.stroke_preserve()
+ ctx.set_source_rgb(1.0, 1.0, 1.0)
+ ctx.fill()
+
+ # Write its number.
+ cell_number = self._calculate_pascal_number(row_index,
+ column_index)
+ extents = ctx.text_extents(str(cell_number))
+ ctx.move_to(cell_x + (cell_width - extents[2]) / 2.0,
+ cell_y + (cell_height - extents[3]) / 2.0)
+ ctx.set_source_rgb(0.0, 0.0, 0.0)
+ ctx.show_text(str(cell_number))
+
+ cell_start_x -= cell_width / 2.0
+ row_order += 1
+
+ return True