Victoria amazonica is a species of flowering plant, the largest of the Nymphaeaceae family of water lilies. It thrives at a temperature of 27-30 °C and is native to the shallow waters of the Amazon River basin, such as oxbow lakes and bayous. In Belgium, the plant can be admired in the botanical garden of Ghent University (Ghent) and the National Botanic Garden of Belgium (Meise).

The leaves of V. amazonica are maroon when they reach the surface, but turn green later on. Young leaves have short edges that are curled inwards. Older leaves can grow up to 3 meter in diameter and float on the water's surface on a submerged stalk, 7 to 8 meter in length. The largest leaves can easily carry 40 kg. The underside of the leaves is covered with thorns and prominent ribs that form an irregular pattern of cells.

Victoria amazonica
V. amazonica flowering.
Victoria amazonica
Underside of a leaf of V. amazonica.

To investigate a plant species we want to count the number of cells on its leaves and determine the average size of these leaf cells. To do this, we convert images of leaves into bitmaps in which leaf cells are clearly delineated. Such a bitmap is nothing more than a rectangular grid and the squares of the bitmap are called bits. Each bit in the grid is either empty (represented by a space) or covered by a piece of rib of the leaf (represented by a pound sign: #). Below you see an example image of a simple leaf having only two cells (left) and the bitmap we have created from this image (right). In a bitmap, leaf cells correspond to regions of contiguous empty bits. Bits are called contiguous if they share a common side. A region of contiguous empty bits is never considered to be a leaf cell, if it contains empty bits on the outer border of the bitmap.

leaf
Image of a leaf with two cells.
bitmap of leaf
Bitmap created from the image of a leaf with two cells. This bitmap is a rectangular grid with 20 rows and 60 columns, where positions that coincide with ribs of the leaf are indicates with pound signs (#).

Assignment

Define a class Leaf that can be used to analyze plant leafs. The objects of this class must at least have the following methods:

Example

In the following interactive session we assume that the text files leaf.txt1 and victoria.txt2 are located in the current directory. The first file contains the bitmap created from the image of the simple leaf used as an example above. The second file contains a bitmap created from the image of the underside of a leaf of V. amazonica that we have used in the introduction of this assignment.

>>> leaf = Leaf('leaf.txt')
>>> print(leaf)
<BLANKLINE>
                                      ######                
                           #############   ##########       
                     #######                         #####  
                  #####                       ############# 
               ####                       ####          ##  
             ###                     #####              ##  
           ###                  #####                  ###  
         ###                ####                       ##   
        ##               ###                          ###   
       ##             ###                            ###    
      ##          ####                             ###      
     ##        ###                                ###       
     #     ####                                 ###         
    ##  ####                                 ####           
    #####                                 #####             
    ###                                #####                
    #####                        #######                    
    #   ##########################                          
<BLANKLINE>
>>> leaf.fill(5, 30)
182
>>> print(leaf)
<BLANKLINE>
                                      ######                
                           #############...##########       
                     #######.........................#####  
                  #####.......................############# 
               ####.......................####          ##  
             ###.....................#####              ##  
           ###..................#####                  ###  
         ###................####                       ##   
        ##...............###                          ###   
       ##.............###                            ###    
      ##..........####                             ###      
     ##........###                                ###       
     #.....####                                 ###         
    ##..####                                 ####           
    #####                                 #####             
    ###                                #####                
    #####                        #######                    
    #   ##########################                          
<BLANKLINE>
>>> leaf.fill(8, 30)
Traceback (most recent call last):
AssertionError: bit must be empty
>>> leaf.fill(15, 30)
335
>>> print(leaf)
<BLANKLINE>
                                      ######                
                           #############...##########       
                     #######.........................#####  
                  #####.......................############# 
               ####.......................####..........##  
             ###.....................#####..............##  
           ###..................#####..................###  
         ###................####.......................##   
        ##...............###..........................###   
       ##.............###............................###    
      ##..........####.............................###      
     ##........###................................###       
     #.....####.................................###         
    ##..####.................................####           
    #####.................................#####             
    ###................................#####                
    #####........................#######                    
    #   ##########################                          
<BLANKLINE>
>>> leaf.clear()
>>> print(leaf)
<BLANKLINE>
                                      ######                
                           #############   ##########       
                     #######                         #####  
                  #####                       ############# 
               ####                       ####          ##  
             ###                     #####              ##  
           ###                  #####                  ###  
         ###                ####                       ##   
        ##               ###                          ###   
       ##             ###                            ###    
      ##          ####                             ###      
     ##        ###                                ###       
     #     ####                                 ###         
    ##  ####                                 ####           
    #####                                 #####             
    ###                                #####                
    #####                        #######                    
    #   ##########################                          
<BLANKLINE>
>>> leaf.cells()
2
>>> leaf.cellsize()
258.5

>>> victoria = Leaf('victoria.txt')
>>> victoria.cells()
242
>>> victoria.cells(minimum=10)
219
>>> victoria.cells(minimum=20)
213
>>> victoria.cellsize()
107.86363636363636
>>> victoria.cellsize(minimum=10)
118.74885844748859
>>> victoria.cellsize(minimum=20)
121.64319248826291