<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Table of Contents
<p><div class="lev1 toc-item"><a href="#Generating-Fractal-From-Random-Points---The-Chaos-Game" data-toc-modified-id="Generating-Fractal-From-Random-Points---The-Chaos-Game-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Generating Fractal From Random Points - The Chaos Game</a></div><div class="lev2 toc-item"><a href="#Initial-Definitions" data-toc-modified-id="Initial-Definitions-1.1"><span class="toc-item-num">1.1&nbsp;&nbsp;</span>Initial Definitions</a></div><div class="lev2 toc-item"><a href="#Make-A-Fractal" data-toc-modified-id="Make-A-Fractal-1.2"><span class="toc-item-num">1.2&nbsp;&nbsp;</span>Make A Fractal</a></div><div class="lev4 toc-item"><a href="#Regular-Polygons" data-toc-modified-id="Regular-Polygons-1.2.0.1"><span class="toc-item-num">1.2.0.1&nbsp;&nbsp;</span>Regular Polygons</a></div><div class="lev4 toc-item"><a href="#Exploring-Further
Step1:  Generating Fractal From Random Points - The Chaos Game
Initial Definitions
Step2:  Make A Fractal
Step3:  Regular Polygons
Step4:  Exploring Further
Step5:  Randomness on Large Scales
Step6:  Learn More
Step7:  For Barnsley's Fern
<ASSISTANT_TASK:>
Python Code:
import pickle,glob
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
%pylab inline
Explanation: Table of Contents
<p><div class="lev1 toc-item"><a href="#Generating-Fractal-From-Random-Points---The-Chaos-Game" data-toc-modified-id="Generating-Fractal-From-Random-Points---The-Chaos-Game-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Generating Fractal From Random Points - The Chaos Game</a></div><div class="lev2 toc-item"><a href="#Initial-Definitions" data-toc-modified-id="Initial-Definitions-1.1"><span class="toc-item-num">1.1&nbsp;&nbsp;</span>Initial Definitions</a></div><div class="lev2 toc-item"><a href="#Make-A-Fractal" data-toc-modified-id="Make-A-Fractal-1.2"><span class="toc-item-num">1.2&nbsp;&nbsp;</span>Make A Fractal</a></div><div class="lev4 toc-item"><a href="#Regular-Polygons" data-toc-modified-id="Regular-Polygons-1.2.0.1"><span class="toc-item-num">1.2.0.1&nbsp;&nbsp;</span>Regular Polygons</a></div><div class="lev4 toc-item"><a href="#Exploring-Further:-Dimension" data-toc-modified-id="Exploring-Further:-Dimension-1.2.0.2"><span class="toc-item-num">1.2.0.2&nbsp;&nbsp;</span>Exploring Further: Dimension</a></div><div class="lev4 toc-item"><a href="#Randomness-on-Large-Scales" data-toc-modified-id="Randomness-on-Large-Scales-1.2.0.3"><span class="toc-item-num">1.2.0.3&nbsp;&nbsp;</span>Randomness on Large Scales</a></div><div class="lev2 toc-item"><a href="#Learn-More:" data-toc-modified-id="Learn-More:-1.3"><span class="toc-item-num">1.3&nbsp;&nbsp;</span>Learn More:</a></div><div class="lev2 toc-item"><a href="#Modeling-Life" data-toc-modified-id="Modeling-Life-1.4"><span class="toc-item-num">1.4&nbsp;&nbsp;</span>Modeling Life</a></div><div class="lev4 toc-item"><a href="#For-Barnsley's-Fern:" data-toc-modified-id="For-Barnsley's-Fern:-1.4.0.1"><span class="toc-item-num">1.4.0.1&nbsp;&nbsp;</span>For Barnsley's Fern:</a></div>
End of explanation
def placeStartpoint(npts,fixedpts):
    #Start Point
    #start = (0.5,0.5)
    start = (np.random.random(),np.random.random())
    if fixedpts == []: #generates a set of random verticies
        for i in range(npts):
            randx = np.random.random()
            randy = np.random.random()
            point = (randx,randy)
            fixedpts.append(point)
            
    return (start,fixedpts)
        
def choosePts(npts,fixedpts,frac):
    #chooses a vertex at random
    #further rules could be applied here
    roll = floor(npts*np.random.random())
    point = fixedpts[int(roll)]
    
    return point
def placeItteratePts(npts,itt,start,fixedpts,frac):
    ittpts = []
    
    for i in range(itt):
        point = choosePts(npts,fixedpts,frac) #chooses a vertex at random
#        halfway = ((point[0]+start[0])*frac,(point[1]+start[1])*frac) #calculates the halfway point between the starting point and the vertex
        halfway = ((point[0]-start[0])*(1.0 - frac)+start[0],(point[1]-start[1])*(1.0 - frac)+start[1])
        ittpts.append(halfway)
        start = halfway #sets the starting point to the new point
        
    return ittpts
def plotFractal(start,fixedpts,ittpts):
    # set axes range
    plt.xlim(-0.05,1.05)
    plt.ylim(-0.05,1.05)
    
    plt.axes().set_aspect('equal')
    
    #plots the verticies
    plt.scatter(transpose(fixedpts)[0],transpose(fixedpts)[1],alpha=0.8, c='black', edgecolors='none', s=30)
    #plots the starting point
    plt.scatter(start[0],start[1],alpha=0.8, c='red', edgecolors='none', s=30)    
    #plots the itterated points
    plt.scatter(transpose(ittpts)[0],transpose(ittpts)[1],alpha=0.5, c='blue', edgecolors='none', s=2)
    
    return
def GenerateFractal(npts,frac,itt,reg=False):
    #Error Control
    if npts < 1 or frac >= 1.0 or frac <= 0.0 or type(npts) is not int or type(frac) is not float or type(itt) is not int:
        print "number of points must be a positive integer, compression fraction must be a positive float less than 1.0, itt must be a positive integer"
        return
    if frac > 0.5:
        print "Warning: compression fractions over 1/2 do not lead to fractals"
    #Initilize Verticies
    if not reg:
        fixedpts = [] #Random Verticies
    else:
        if npts == 3:
            fixedpts = [(0.0,0.0),(1.0,0.0),(0.5,0.5*sqrt(3.0))] #Equilateral Triangle (npts = 3)
        elif npts == 4:
            fixedpts = [(0.0,0.0),(1.0,0.0),(1.0,1.0),(0.0,1.0)] #Square
        elif npts == 5:
            fixedpts = [(0.0,2./(1+sqrt(5.))),(0.5-2./(5+sqrt(5.)),0.0),(0.5,1.0),(0.5+2./(5+sqrt(5.)),0.0),(1.0,2./(1+sqrt(5.)))] #Regular Pentagon
        elif npts == 6:
            fixedpts = [(0.0,0.5),(1./4,0.5+.25*sqrt(3.)),(3./4,0.5+.25*sqrt(3.)),(1.0,0.5),(3./4,0.5-.25*sqrt(3.)),(1./4,0.5-.25*sqrt(3.))] #Regular Hexagon
        elif npts == 2:
            fixedpts = [(0.0,0.0),(1.0,1.0)] #Line
        elif npts == 1:
            fixedpts = [(0.5,0.5)] #Line
        elif npts == 8:
            fixedpts = [(0.0,0.0),(1.0,0.0),(1.0,1.0),(0.0,1.0),(0.5,0.0),(1.0,0.5),(0.5,1.0),(0.0,0.5)] #Carpet
        else:
            print "No regular polygon stored with that many verticies, switching to default with randomly assigned verticies"
            fixedpts = [] #Random Verticies
    #Compression Fraction
#    frac = 1.0/2.0 #Sierpinski's Triangle (npts = 3)
#    frac = 1.0/2.0 #Sierpinski's "Square" (filled square, npts = 4)
#    frac = 1.0/3.0 #Sierpinski's Pentagon (npts = 5)
#    frac = 3.0/8.0 #Sierpinski's Hexagon (npts = 6)
        
    if len(fixedpts) != npts and len(fixedpts) != 0:
        print "The number of verticies don't match the length of the list of verticies. If you want the verticies generated at random, set fixedpts to []"
        return
    if len(fixedpts) != 0:
        print "Fractal Dimension = {}".format(-log(npts)/log(frac))
    
        
    (start, fixedpts) = placeStartpoint(npts,fixedpts)
    
    ittpts = placeItteratePts(npts,itt,start,fixedpts,frac)
    
    plotFractal(start,fixedpts,ittpts)
    
    return
    
    
Explanation: Generating Fractal From Random Points - The Chaos Game
Initial Definitions
End of explanation
# Call the GenerateFractal function with a number of verticies, a number of itterations, and the compression fraction
# The starting verticies are random by default. An optional input of True will set the verticies to those of a regular polygon.
GenerateFractal(3,.5,5000)
Explanation: Make A Fractal
End of explanation
GenerateFractal(3,.5,50000,True)
GenerateFractal(5,1./3,50000,True)
GenerateFractal(6,3./8,50000,True)
GenerateFractal(8,1./3.,50000,True)
Explanation: Regular Polygons
End of explanation
GenerateFractal(1,.5,50000,True)
GenerateFractal(2,.5,50000,True)
GenerateFractal(4,.5,50000,True)
Explanation: Exploring Further: Dimension
End of explanation
GenerateFractal(10,.5,100)
GenerateFractal(10,.5,5000)
GenerateFractal(100,.5,5000)
GenerateFractal(100,.5,100000)
Explanation: Randomness on Large Scales
End of explanation
def makeFern(f,itt):            
    colname = ["percent","a","b","c","d","e","f"]
    print pd.DataFrame(data=np.array(f), columns = colname)
    
    x,y = {0.5,0.0}
    xypts=[]
    if abs(sum(f[j][0] for j in range(len(f)))-1.0) < 10^-10:
        print "Probabilities must sum to 1"
        return
    for i in range(itt):
        rand = (np.random.random())
        cond = 0.0
        for j in range(len(f)):
            if  (cond <= rand) and (rand <= (cond+f[j][0])):
                x = f[j][1]*x+f[j][2]*y+f[j][5]
                y = f[j][3]*x+f[j][4]*y+f[j][6]
                xypts.append((x,y))
            cond = cond + f[j][0]
            
    xmax,ymax = max(abs(transpose(xypts)[0])),max(abs(transpose(xypts)[1]))
    plt.axes().set_aspect('equal')
    color = transpose([[abs(r)/xmax for r in transpose(xypts)[0]],[abs(g)/ymax for g in transpose(xypts)[1]],[b/itt for b in range(itt)]])
    
    plt.scatter(transpose(xypts)[0],transpose(xypts)[1],alpha=0.5, facecolors=color, edgecolors='none', s=1)
    
Explanation: Learn More:
Chaos Game Wiki
Numberphile Video
Chaos in the Classroom
Chaos Rules!
Barnsley Fern
Modeling Life
End of explanation
f = ((0.01,0.0,0.0,0.0,0.16,0.0,0.0),
     (0.85,0.85,0.08,-0.08,0.85,0.0,1.60),
     (0.07,0.20,-0.26,0.23,0.22,0.0,1.60),
     (0.07,-0.15,0.28,0.26,0.24,0.0,0.44))
makeFern(f,5000)
Explanation: For Barnsley's Fern:
Use the following values
|Percent|A|B|C|D|E|F|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|0.01|0.0|0.0|0.0|0.16|0.0|0.0|
|0.85|0.85|0.04|-0.04|0.85|0.0|1.60|
|0.07|0.20|-0.26|0.23|0.22|0.0|1.60|
|0.07|-0.15|0.28|0.26|0.24|0.0|0.44|
Of course, this is only one solution so try as changing the values. Some values modify the curl, some change the thickness, others completely rearrange the structure.
End of explanation
<END_TASK>