Ejemplo n.º 1
0
 def __init__(self,
              width=200,
              height=150,
              pieType="Pie",
              bShowBoundary=False,
              *args,
              **kw):
     Drawing.__init__(self, width, height, *args, **kw)
     if pieType == "Pie":
         self._add(self,
                   Pie(),
                   name='chart',
                   validate=None,
                   desc="The pie object")
     else:  #default to Pie3d
         self._add(self,
                   Pie3d(),
                   name='chart',
                   validate=None,
                   desc="The pie object")
     if bShowBoundary:
         self.background = ShadedRect()
         self.background.fillColorStart = colors.white
         self.background.fillColorEnd = colors.white
         self.background.numShades = 1
         self.background.strokeWidth = 0.5
         self.background.height = height
         self.background.width = width
Ejemplo n.º 2
0
 def __init__(self,width=400,height=200,*args,**kw):
     Drawing.__init__(self,width,height,*args,**kw)
     self.width       = 72
     self.height      = 20
     self._add(self,ShadedRect(),name='sr',validate=None,desc=None)
     self.sr.strokeColor    = None
     self.sr.fillColorEnd   = grey
     self.sr.width=self.width
     self.sr.height=self.height
     self._add(self,String(self.width*0.5,6,'text', textAnchor='middle', fontName='Helvetica-Bold',fontSize=12),name='s',validate=None,desc=None)
Ejemplo n.º 3
0
 def __init__(self,width=200,height=150,*args,**kw):
     Drawing.__init__(self,width,height,*args,**kw)
     self._add(self,Pie(),name='chart',validate=None,desc="The main chart")
     self.chart.width      = 100
     self.chart.height     = 100
     self.chart.x          = 25
     self.chart.y          = 25
     self.chart.slices[0].fillColor = color01
     self.chart.slices[1].fillColor = color02
     self.chart.slices[2].fillColor = color03
     self.chart.slices[3].fillColor = color04
     self.chart.slices[4].fillColor = color05
     self.chart.slices[5].fillColor = color06
     self.chart.slices[6].fillColor = color07
     self.chart.slices[7].fillColor = color08
     self.chart.slices[8].fillColor = color09
     self.chart.slices[9].fillColor = color10
     self.chart.data                = (100, 150, 180)
     self.chart.startAngle          = -90
     self._add(self,Label(),name='Title',validate=None,desc="The title at the top of the chart")
     self.Title.fontName   = 'Helvetica-Bold'
     self.Title.fontSize   = 7
     self.Title.x          = 100
     self.Title.y          = 135
     self.Title._text      = 'Chart Title'
     self.Title.maxWidth   = 180
     self.Title.height     = 20
     self.Title.textAnchor ='middle'
     self._add(self,Legend(),name='Legend',validate=None,desc="The legend or key for the chart")
     self.Legend.colorNamePairs = [(color01, 'North'), (color02, 'South'), (color03, 'Central')]
     self.Legend.fontName       = 'Helvetica'
     self.Legend.fontSize       = 7
     self.Legend.x              = 160
     self.Legend.y              = 85
     self.Legend.dxTextSpace    = 5
     self.Legend.dy             = 5
     self.Legend.dx             = 5
     self.Legend.deltay         = 5
     self.Legend.alignment      ='right'
     self.Legend.columnMaximum  = 10
     self.chart.slices.strokeWidth  = 1
     self.chart.slices.fontName     = 'Helvetica'
     self.background                = ShadedRect()
     self.background.fillColorStart = backgroundGrey
     self.background.fillColorEnd   = backgroundGrey
     self.background.numShades      = 1
     self.background.strokeWidth    = 0.5
     self.background.x              = 20
     self.background.y              = 20
     self.chart.slices.popout       = 5
     self.background.height         = 110
     self.background.width          = 110
     self._add(self,0,name='preview',validate=None,desc=None)
Ejemplo n.º 4
0
    def draw(self):
        g = Group()
        ys = self.bottomPadding + (
            self.triangleHeight /
            2) + self.sourceLabelOffset + self.sourceLabelFontSize
        if self.background:
            x, y = self._getDrawingDimensions()
            g.add(
                Rect(-self.leftPadding,
                     -ys,
                     x,
                     y,
                     strokeColor=None,
                     strokeWidth=0,
                     fillColor=self.background))

        ascent = getFont(self.labelFontName).face.ascent / 1000.
        if ascent == 0: ascent = 0.718  # default (from helvetica)
        ascent = ascent * self.labelFontSize  # normalize

        colorsList = self._getColors()

        # Draw the boxes - now uses ShadedRect from grids
        x = 0
        for f in range(0, self.numberOfBoxes):
            sr = ShadedRect()
            sr.x = x
            sr.y = 0
            sr.width = self.boxWidth
            sr.height = self.boxHeight
            sr.orientation = 'vertical'
            sr.numShades = 30
            sr.fillColorStart = colorsList[f]
            sr.fillColorEnd = colorsList[f + 1]
            sr.strokeColor = None
            sr.strokeWidth = 0

            g.add(sr)

            g.add(
                Rect(x,
                     0,
                     self.boxWidth,
                     self.boxHeight,
                     strokeColor=self.boxOutlineColor,
                     strokeWidth=self.boxOutlineWidth,
                     fillColor=None))

            g.add(
                String(x + self.boxWidth / 2., (self.boxHeight - ascent) / 2.,
                       text=str(f + 1),
                       fillColor=self.labelFillColor,
                       strokeColor=self.labelStrokeColor,
                       textAnchor='middle',
                       fontName=self.labelFontName,
                       fontSize=self.labelFontSize))
            x = x + self.boxWidth + self.boxSpacing

        #do triangles
        xt = (self.trianglePosition * self.boxWidth)
        if self.trianglePosition > 1:
            xt = xt + (self.trianglePosition - 1) * self.boxSpacing
        xt = xt - (self.boxWidth / 2)
        g.add(
            Polygon(strokeColor=self.triangleStrokeColor,
                    strokeWidth=self.triangleStrokeWidth,
                    fillColor=self.triangleFillColor,
                    points=[
                        xt, self.boxHeight - (self.triangleHeight / 2),
                        xt - (self.triangleWidth / 2),
                        self.boxHeight + (self.triangleHeight / 2),
                        xt + (self.triangleWidth / 2),
                        self.boxHeight + (self.triangleHeight / 2), xt,
                        self.boxHeight - (self.triangleHeight / 2)
                    ]))
        g.add(
            Polygon(strokeColor=self.triangleStrokeColor,
                    strokeWidth=self.triangleStrokeWidth,
                    fillColor=self.triangleFillColor,
                    points=[
                        xt, 0 + (self.triangleHeight / 2),
                        xt - (self.triangleWidth / 2),
                        0 - (self.triangleHeight / 2),
                        xt + (self.triangleWidth / 2),
                        0 - (self.triangleHeight / 2), xt,
                        0 + (self.triangleHeight / 2)
                    ]))

        #source label
        if self.sourceLabelText != None:
            g.add(
                String(x - self.boxSpacing,
                       0 - (self.triangleHeight / 2) - self.sourceLabelOffset -
                       (self.sourceLabelFontSize),
                       text=self.sourceLabelText,
                       fillColor=self.sourceLabelFillColor,
                       textAnchor='end',
                       fontName=self.sourceLabelFontName,
                       fontSize=self.sourceLabelFontSize))

        g.shift(self.leftPadding, ys)

        return g
Ejemplo n.º 5
0
def create_single_class_pdf(teacher_name, class_id, class_name, class_average,
                            total_students, total_grades, standards_list,
                            grade_standard_dict, grade_student_dict,
                            standard_total_dict):
    pdfName = class_name + "_CLR" + ".pdf"
    response.headers['Content-Type'] = 'application/pdf'
    response.headers[
        'Content-Disposition'] = 'attachment;filename=%s;' % pdfName
    styles = getSampleStyleSheet()
    HeaderStyle = styles["Heading1"]
    buff = StringIO()
    doc = SimpleDocTemplate(buff,
                            pagesize=letter,
                            rightMargin=72,
                            leftMargin=72,
                            topMargin=72,
                            bottomMargin=18)
    doc.title = pdfName
    Story = []
    Elements = []
    formatted_time = time.ctime()
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
    styles.add(ParagraphStyle(name='Indent', rightIndent=3))
    styles.add(
        ParagraphStyle(
            name='Title2',
            parent=styles['Normal'],
            fontName='DejaVuSansCondensed',
            fontSize=18,
            leading=22,
            #alignment = TA_LEFT,
            spaceAfter=6),
        alias='title2')

    ptext = '<font size=12>%s</font>' % formatted_time

    Story.append(Paragraph(ptext, styles["Normal"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Teacher Name
    ptext = '<font size=12><b>%s %s</b></font>' % (teacher_name.first_name,
                                                   teacher_name.last_name)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Class Name
    ptext = '<font size=12>%s: </font>' % (class_name)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 7))
    Elements.extend(ptext)

    #Class Average
    ptext = '<font size=12>Class Average:%s%%</font>' % (class_average)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Total Students
    ptext = '<font size=12>Total Students:%s</font>' % (total_students)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Total Assignments
    ptext = '<font size=12>Total Assignments:%s</font>' % (total_grades)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 12))
    Story.append(Spacer(1, 40))

    ptext = '<font size=15><b>Standards Progress</b></font>'
    Story.append(Paragraph(ptext, styles["title"]))

    test_values = [[10, 20, 50, 90, 80]]
    standard_table = []
    i = 0
    minimum = 100
    standard_averages = [[]]
    #Go through the standard_total_dict keys and add all the necessary values to the standard_averages 2d list.
    for standard in sorted(standard_total_dict.keys()):
        standard_table.append([])
        current_avg = (standard_total_dict[standard][1] /
                       standard_total_dict[standard][0]) * 100
        if minimum > current_avg:
            minimum = current_avg
        standard_table[i].append(standard_total_dict[standard][3] + ": " +
                                 format((standard_total_dict[standard][1] /
                                         standard_total_dict[standard][0]) *
                                        100, '.2f') + "%")
        standard_averages[0].append(
            int(
                round((standard_total_dict[standard][1] /
                       standard_total_dict[standard][0]) * 100)))

        #add assignments to correct buckets
        for grade in grade_standard_dict.keys():
            for standardId in grade_standard_dict[grade][1]:
                if (standardId == standard):
                    standard_table[i].append(
                        grade_standard_dict[grade][0] + ":" +
                        format((grade_student_dict[grade][1] /
                                grade_student_dict[grade][0]) * 100, '.2f') +
                        "%")
        i += 1
    sorted(standard_table, key=lambda l: l[0])

    #graph
    drawing = Drawing(600, 200)
    data = standard_averages
    bc = VerticalBarChart()

    #location in the document (x,y)
    bc.x = 10
    bc.y = 30

    #width and height of the graph
    bc.height = 225
    bc.width = 400
    bc.data = data
    bc.categoryAxis.drawGridLast = True
    bc.categoryAxis.gridStart = 0
    bc.categoryAxis.gridStrokeLineCap = 2
    bc.categoryAxis.gridEnd = 3
    bc.barLabels = [10, 20, 30, 40, 50]

    #Update colors of the bars in the graph
    bc.bars.symbol = ShadedRect()
    bc.bars.symbol.fillColorStart = colors.lightblue
    bc.bars.symbol.fillColorEnd = colors.lightblue
    bc.bars.symbol.strokeWidth = 0

    #this draws a line at the top of the graph to close it.
    bc.strokeColor = colors.black

    #Y-axis min, max, and steps.
    if minimum != 100:
        bc.valueAxis.valueMin = minimum - 10
    else:
        bc.valueAxis.valueMin = 50
    bc.valueAxis.valueMax = 100
    bc.valueAxis.valueStep = 5

    #where to anchor the origin of the graph
    bc.categoryAxis.labels.boxAnchor = 'ne'

    #Locations of labels for the X-axis
    bc.categoryAxis.labels.dx = 2
    bc.categoryAxis.labels.dy = -2

    #The angle of the lables for the X-axis
    bc.categoryAxis.labels.angle = 30
    #List of the categories to place on the X-axis
    bc.categoryAxis.categoryNames = standards_list
    drawing.add(bc)

    #Graph Legend
    legend = Legend()
    legend.alignment = 'right'
    legend.x = 420
    legend.y = 150
    legend.deltax = 60
    legend.dxTextSpace = 10
    legend.columnMaximum = 4

    legend.colorNamePairs = [(colors.lightblue, 'grade average')]
    drawing.add(legend, 'legend')
    drawing_title = "Bar Graph"
    Story.append(drawing)

    t = Table(standard_table)
    t.setStyle(
        t.setStyle(
            TableStyle([
                ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
                ('FONTSIZE', (0, 0), (-1, -1), 7),
                ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey),
                ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ])))
    Story.append(t)
    doc.build(Story)
    pdf = buff.getvalue()
    buff.close()
    return pdf
Ejemplo n.º 6
0
    def draw(self):
        g = Group()
        ys = self.bottomPadding+(self.triangleHeight/2)+self.sourceLabelOffset+self.sourceLabelFontSize
        if self.background:
            x,y = self._getDrawingDimensions()
            g.add(Rect(-self.leftPadding,-ys,x,y,
                       strokeColor=None,
                       strokeWidth=0,
                       fillColor=self.background))

        ascent=getFont(self.labelFontName).face.ascent/1000.
        if ascent==0: ascent=0.718 # default (from helvetica)
        ascent=ascent*self.labelFontSize # normalize

        colorsList = self._getColors()

        # Draw the boxes - now uses ShadedRect from grids
        x=0
        for f in range (0,self.numberOfBoxes):
            sr=ShadedRect()
            sr.x=x
            sr.y=0
            sr.width=self.boxWidth
            sr.height=self.boxHeight
            sr.orientation = 'vertical'
            sr.numShades = 30
            sr.fillColorStart = colorsList[f]
            sr.fillColorEnd = colorsList[f+1]
            sr.strokeColor = None
            sr.strokeWidth = 0

            g.add(sr)

            g.add(Rect(x,0,self.boxWidth,self.boxHeight,
                   strokeColor=self.boxOutlineColor,
                   strokeWidth=self.boxOutlineWidth,
                   fillColor=None))

            g.add(String(x+self.boxWidth/2.,(self.boxHeight-ascent)/2.,
                   text = str(f+1),
                   fillColor = self.labelFillColor,
                   strokeColor=self.labelStrokeColor,
                   textAnchor = 'middle',
                   fontName = self.labelFontName,
                   fontSize = self.labelFontSize))
            x=x+self.boxWidth+self.boxSpacing

        #do triangles
        xt = (self.trianglePosition*self.boxWidth)
        if self.trianglePosition>1:
            xt = xt+(self.trianglePosition-1)*self.boxSpacing
        xt = xt-(self.boxWidth/2)
        g.add(Polygon(
            strokeColor = self.triangleStrokeColor,
            strokeWidth = self.triangleStrokeWidth,
            fillColor = self.triangleFillColor,
            points=[xt,self.boxHeight-(self.triangleHeight/2),
                    xt-(self.triangleWidth/2),self.boxHeight+(self.triangleHeight/2),
                    xt+(self.triangleWidth/2),self.boxHeight+(self.triangleHeight/2),
                        xt,self.boxHeight-(self.triangleHeight/2)]))
        g.add(Polygon(
            strokeColor = self.triangleStrokeColor,
            strokeWidth = self.triangleStrokeWidth,
            fillColor = self.triangleFillColor,
            points=[xt,0+(self.triangleHeight/2),
                    xt-(self.triangleWidth/2),0-(self.triangleHeight/2),
                    xt+(self.triangleWidth/2),0-(self.triangleHeight/2),
                    xt,0+(self.triangleHeight/2)]))

        #source label
        if self.sourceLabelText != None:
            g.add(String(x-self.boxSpacing,0-(self.triangleHeight/2)-self.sourceLabelOffset-(self.sourceLabelFontSize),
                       text = self.sourceLabelText,
                       fillColor = self.sourceLabelFillColor,
                       textAnchor = 'end',
                       fontName = self.sourceLabelFontName,
                       fontSize = self.sourceLabelFontSize))

        g.shift(self.leftPadding, ys)

        return g
Ejemplo n.º 7
0
def create_single_grade_pdf(grade, content_area_id):
    '''--Variables--'''
    school_level = []
    Story = []
    Elements = []
    contentarea_name = ""
    buff = StringIO()
    formatted_time = time.ctime()
    minimum = 100
    standard_averages = [[]]
    standard_table = []

    content_areas = []
    '''------'''
    styles = getSampleStyleSheet()
    HeaderStyle = styles["Heading1"]

    #get the Content Area Name
    query = ((content_area_id == db.contentarea.id))
    results = db(query).select(db.contentarea.name)
    for row in results:
        contentarea_name = row.name

    #Create the name for the PDf being returned
    pdfName = "Grade_" + str(grade) + "_" + contentarea_name + "_SR" + ".pdf"

    #set up the response headers so the browser knows to return a PDF document
    response.headers['Content-Type'] = 'application/pdf'
    response.headers[
        'Content-Disposition'] = 'attachment;filename=%s;' % pdfName
    doc = SimpleDocTemplate(buff,
                            pagesize=letter,
                            rightMargin=72,
                            leftMargin=72,
                            topMargin=72,
                            bottomMargin=18)
    doc.title = pdfName

    #Set up some styles
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
    styles.add(ParagraphStyle(name='Indent', rightIndent=3))
    styles.add(ParagraphStyle(name='Title2',
                              parent=styles['Normal'],
                              fontName='DejaVuSansCondensed',
                              fontSize=18,
                              leading=22,
                              spaceAfter=6),
               alias='title2')

    #Time-Stamp
    ptext = '<font size=12>%s</font>' % formatted_time
    Story.append(Paragraph(ptext, styles["Normal"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Administrator
    ptext = '<font size=12><b>Administrator</b></font>'
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Grade Number and Content Area
    ptext = '<font size=12><b>Grade %s %s Standards Report</b></font>' % (
        grade, contentarea_name)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 7))
    Elements.extend(ptext)
    Story.append(Spacer(1, 40))

    #Graph Title
    ptext = '<font size=15><b>Standards Progress</b></font>'
    Story.append(Paragraph(ptext, styles["title"]))

    i = 0
    #get all the standards for a specific grade and content area
    standard_query = standard_query = (
        (db.classes.grade_level == grade) &
        (db.classes.id == db.student_classes.class_id) &
        (db.student.id == db.student_classes.student_id) &
        (db.student.id == db.student_grade.student_id) &
        (db.grade.id == db.student_grade.grade_id) &
        (db.grade.id == db.grade_standard.grade_id) &
        (db.standard.id == db.grade_standard.standard_id) &
        (db.classes.id == db.class_grade.class_id) &
        (db.grade.id == db.class_grade.grade_id) &
        (db.standard.content_area == db.contentarea.id) &
        (db.contentarea.id == content_area_id))

    standard_list = db(standard_query).select(
        db.standard.id, db.standard.short_name, db.standard.reference_number,
        db.student_grade.student_score, db.grade.score, db.contentarea.name)
    standard_ref_list = []
    #Setup the Dictionary of standard averages
    standard_dict = {}
    for row in standard_list:
        if row.standard.id in standard_dict.keys():
            if ((row.grade.score != 0.0) |
                (row.student_grade.student_score != 0.0)):
                max_score = standard_dict[row.standard.id][0] + row.grade.score
                student_score = standard_dict[
                    row.standard.id][1] + row.student_grade.student_score
                standard_dict[row.standard.id] = [
                    max_score, student_score, row.standard.reference_number,
                    row.standard.short_name
                ]
        else:
            standard_dict[row.standard.id] = [
                row.grade.score, row.student_grade.student_score,
                row.standard.reference_number, row.standard.short_name
            ]

    standard_table = []
    standard_averages = [[]]

    #set up the 2D list of Standard Averages
    for standard in sorted(standard_dict.keys()):
        standard_ref_list.append(standard_dict[standard][2])
        standard_table.append([])
        current_avg = (standard_dict[standard][1] /
                       standard_dict[standard][0]) * 100
        if minimum > current_avg:
            minimum = current_avg
        standard_table[i].append(standard_dict[standard][3] + ": " + format(
            (standard_dict[standard][1] / standard_dict[standard][0]) *
            100, '.2f') + "%")
        standard_averages[0].append(
            int(
                round(
                    (standard_dict[standard][1] / standard_dict[standard][0]) *
                    100)))
        i += 1
    sorted(standard_table, key=lambda l: l[0])
    '''---Graph---'''
    drawing = Drawing(600, 200)
    data = standard_averages
    bc = VerticalBarChart()

    #location in the document (x,y)
    bc.x = 10
    bc.y = 30

    #width and height of the graph
    bc.height = 225
    bc.width = 400
    bc.data = data
    bc.categoryAxis.drawGridLast = True
    bc.categoryAxis.gridStart = 0
    bc.categoryAxis.gridStrokeLineCap = 2
    bc.categoryAxis.gridEnd = 3
    #bc.barLabels =

    #Update colors of the bars in the graph
    bc.bars.symbol = ShadedRect()
    bc.bars.symbol.fillColorStart = colors.lightblue
    bc.bars.symbol.fillColorEnd = colors.lightblue
    bc.bars.symbol.strokeWidth = 0

    #this draws a line at the top of the graph to close it.
    bc.strokeColor = colors.black

    #Y-axis min, max, and steps.
    if minimum != 100:
        bc.valueAxis.valueMin = minimum - 10
    else:
        bc.valueAxis.valueMin = 50
    bc.valueAxis.valueMax = 100
    bc.valueAxis.valueStep = 5

    #where to anchor the origin of the graph
    bc.categoryAxis.labels.boxAnchor = 'ne'

    #Locations of labels for the X-axis
    bc.categoryAxis.labels.dx = 2
    bc.categoryAxis.labels.dy = -2

    bc.barLabels.nudge = -10
    bc.barLabelFormat = '%0.2f%%'
    bc.barLabels.dx = 0
    bc.barLabels.dy = 0
    #The angle of the lables for the X-axis
    bc.categoryAxis.labels.angle = 30
    #List of the categories to place on the X-axis
    bc.categoryAxis.categoryNames = standard_ref_list
    drawing.add(bc)
    '''------'''
    '''--Graph Legend--'''
    #Graph Legend
    legend = Legend()
    legend.alignment = 'right'
    legend.x = 420
    legend.y = 150
    legend.deltax = 60
    legend.dxTextSpace = 10
    legend.columnMaximum = 4

    legend.colorNamePairs = [(colors.lightblue, 'grade average')]
    drawing.add(legend, 'legend')
    drawing_title = "Bar Graph"
    Story.append(drawing)

    #build PDF document and return it
    doc.build(Story)
    pdf = buff.getvalue()
    buff.close()
    return pdf
Ejemplo n.º 8
0
def create_single_grade_pdf(student_id, class_id, assignment_count,
                            grade_standard_dict, grade_student_dict,
                            assignment_line_all, assignment_names,
                            assignment_dict):
    '''--Variables--'''
    Story = []
    Elements = []
    buff = StringIO()
    formatted_time = time.ctime()
    minimum = 100
    standard_averages = [[]]
    standard_table = []

    #content_areas = []
    '''------'''
    styles = getSampleStyleSheet()
    HeaderStyle = styles["Heading1"]

    #get the student Name

    #Create the name for the PDf being returned
    pdfName = get_student_name(student_id).first_name + "_" + get_student_name(
        student_id).last_name + "_SR" + ".pdf"

    #set up the response headers so the browser knows to return a PDF document
    response.headers['Content-Type'] = 'application/pdf'
    response.headers[
        'Content-Disposition'] = 'attachment;filename=%s;' % pdfName
    doc = SimpleDocTemplate(buff,
                            pagesize=letter,
                            rightMargin=72,
                            leftMargin=72,
                            topMargin=72,
                            bottomMargin=18)
    doc.title = pdfName

    #Set up some styles
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
    styles.add(ParagraphStyle(name='Indent', rightIndent=3))
    styles.add(
        ParagraphStyle(
            name='Title2',
            parent=styles['Normal'],
            fontName='DejaVuSansCondensed',
            fontSize=18,
            leading=22,
            #alignment = TA_LEFT,
            spaceAfter=6),
        alias='title2')

    #Time-Stamp
    ptext = '<font size=12>%s</font>' % formatted_time
    Story.append(Paragraph(ptext, styles["Normal"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Administrator
    ptext = '<font size=12><b>%s %s</b></font>' % (get_student_name(
        student_id).first_name, get_student_name(student_id).last_name)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 12))
    Elements.extend(ptext)

    #Grade Number and Content Area
    ptext = '<font size=12><b>%s Student Report</b></font>' % (
        get_class_name(class_id).name)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 7))
    Elements.extend(ptext)

    #Total Assignments
    ptext = '<font size=12>Total Assignments: %s</font>' % (assignment_count)
    Story.append(Paragraph(ptext, styles["Justify"]))
    Story.append(Spacer(1, 7))
    Elements.extend(ptext)

    Story.append(Spacer(1, 20))
    #Graph Title
    ptext = '<font size=15><b>Current Performance by Standard</b></font>'
    Story.append(Paragraph(ptext, styles["title"]))
    Story.append(Spacer(1, 50))

    #get all the standards for a specific grade and content area
    standard_query = ((db.classes.id == class_id) &
                      (student_id == db.student.id) &
                      (db.classes.id == db.student_classes.class_id) &
                      (db.student.id == db.student_classes.student_id) &
                      (db.student.id == db.student_grade.student_id) &
                      (db.grade.id == db.student_grade.grade_id) &
                      (db.grade.id == db.grade_standard.grade_id) &
                      (db.standard.id == db.grade_standard.standard_id) &
                      (db.classes.id == db.class_grade.class_id) &
                      (db.grade.id == db.class_grade.grade_id) &
                      (db.standard.content_area == db.contentarea.id))

    standard_list = db(standard_query).select(
        db.standard.id, db.standard.short_name, db.standard.reference_number,
        db.student_grade.student_score, db.grade.score, db.contentarea.name)
    standard_ref_list = []
    #Setup the Dictionary of standard averages
    standard_dict = {}
    standard_table = []
    standard_averages = [[]]
    for row in standard_list:
        if row.standard.id in standard_dict.keys():
            if ((row.grade.score != 0.0) |
                (row.student_grade.student_score != 0.0)):
                max_score = standard_dict[row.standard.id][0] + row.grade.score
                student_score = standard_dict[
                    row.standard.id][1] + row.student_grade.student_score
                standard_dict[row.standard.id] = [
                    max_score, student_score, row.standard.reference_number,
                    row.standard.short_name
                ]
        else:
            standard_dict[row.standard.id] = [
                row.grade.score, row.student_grade.student_score,
                row.standard.reference_number, row.standard.short_name
            ]

    i = 0
    #set up the 2D list of Standard Averages
    for standard in sorted(standard_dict.keys()):
        standard_ref_list.append(standard_dict[standard][2])
        standard_table.append([])
        current_avg = (standard_dict[standard][1] /
                       standard_dict[standard][0]) * 100
        if minimum > current_avg:
            minimum = current_avg
        #int/round was here
        standard_table[i].append(standard_dict[standard][3] + ": " + format(
            (standard_dict[standard][1] / standard_dict[standard][0]) *
            100, '.2f') + "%")
        #int/round was here
        standard_averages[0].append(
            (standard_dict[standard][1] / standard_dict[standard][0]) * 100)

        for grade in grade_standard_dict.keys():
            for standardId in grade_standard_dict[grade][1]:
                if (standardId == standard):
                    standard_table[i].append(
                        grade_standard_dict[grade][0] + ":" +
                        format((grade_student_dict[grade][1] /
                                grade_student_dict[grade][0]) * 100, '.2f') +
                        "%")
        i += 1
    sorted(standard_table, key=lambda l: l[0])
    '''---Graph---'''
    drawing = Drawing(600, 200)
    data = standard_averages
    bc = VerticalBarChart()

    #location in the document (x,y)
    bc.x = 10
    bc.y = 30

    #width and height of the graph
    bc.height = 225
    bc.width = 400
    bc.data = data
    bc.categoryAxis.drawGridLast = True
    bc.categoryAxis.gridStart = 0
    bc.categoryAxis.gridStrokeLineCap = 2
    bc.categoryAxis.gridEnd = 3
    #bc.barLabels =

    #Update colors of the bars in the graph
    bc.bars.symbol = ShadedRect()
    bc.bars.symbol.fillColorStart = colors.lightblue
    bc.bars.symbol.fillColorEnd = colors.lightblue
    bc.bars.symbol.strokeWidth = 0

    #this draws a line at the top of the graph to close it.
    bc.strokeColor = colors.black

    #Y-axis min, max, and steps.
    if minimum != 100:
        bc.valueAxis.valueMin = minimum - 10
    else:
        bc.valueAxis.valueMin = 50
    bc.valueAxis.valueMax = 100
    bc.valueAxis.valueStep = 5

    #where to anchor the origin of the graph
    bc.categoryAxis.labels.boxAnchor = 'ne'

    #Locations of labels for the X-axis
    bc.categoryAxis.labels.dx = 2
    bc.categoryAxis.labels.dy = -2

    bc.barLabels.nudge = -10
    bc.barLabelFormat = '%.2f%%'
    bc.barLabels.dx = 0
    bc.barLabels.dy = 0
    #The angle of the lables for the X-axis
    bc.categoryAxis.labels.angle = 30
    #List of the categories to place on the X-axis
    bc.categoryAxis.categoryNames = standard_ref_list
    drawing.add(bc)
    '''------'''
    '''--Graph Legend--'''
    #Graph Legend
    legend = Legend()
    legend.alignment = 'right'
    legend.x = 420
    legend.y = 150
    legend.deltax = 60
    legend.dxTextSpace = 10
    legend.columnMaximum = 4

    legend.colorNamePairs = [(colors.lightblue, 'grade average')]
    drawing.add(legend, 'legend')
    drawing_title = "Bar Graph"

    Story.append(drawing)
    Story.append(Spacer(1, 15))
    #LineGraph Title
    ptext = '<font size=15><b>Class Performance by Assignment</b></font>'
    Story.append(Paragraph(ptext, styles["title"]))
    Story.append(Spacer(1, 30))
    '''
    Line Plot Graph ------
    '''
    assignment_data_all = [[], []]
    for key in assignment_dict.keys():
        assignment_data_all[0].append(assignment_dict[key][2])
        assignment_data_all[1].append(assignment_dict[key][1])
    drawing2 = Drawing(600, 200)
    data2 = assignment_data_all
    #lp = LinePlot()

    #data[0] = preprocessData(data[0])
    lp = HorizontalLineChart()
    lp.x = -20
    lp.y = 0
    lp.height = 225
    lp.width = 500
    lp.data = data2
    lp.joinedLines = 1
    lp.lines.symbol = makeMarker('FilledCircle')
    lp.lines[0].strokeColor = colors.grey
    lp.lines[1].strokeColor = colors.lightblue
    lp.strokeColor = colors.black
    lp.categoryAxis.labels.fontSize = 7
    lp.categoryAxis.categoryNames = assignment_names
    lp.categoryAxis.labels.boxAnchor = 'ne'
    lp.categoryAxis.labels.angle = 30
    lp.categoryAxis.drawGridLast = True
    #lp.categoryAxis.gridStart=0
    lp.categoryAxis.gridStrokeLineCap = 2
    #lp.categoryAxis.gridEnd=3
    #lp.categoryAxis.visibleGrid           = 1
    lp.valueAxis.visibleGrid = 1
    lp.valueAxis.visible = 1
    lp.valueAxis.drawGridLast = False
    #lp.valueAxis.gridStart = 0
    #lp.valueAxis.gridEnd = 100
    lp.valueAxis.gridStrokeColor = colors.black
    lp.valueAxis.valueMin = 0
    lp.valueAxis.valueMax = 105
    lp.valueAxis.valueStep = 10
    lp.lineLabelFormat = '%2.0f'
    lp.strokeColor = colors.black
    lp.fillColor = colors.white
    drawing2.add(lp)

    legend = Legend()
    legend.alignment = 'right'
    legend.x = 482
    legend.y = 150
    legend.deltax = 60
    legend.dxTextSpace = 2
    legend.colorNamePairs = [(colors.lightblue, 'Student'),
                             (colors.grey, 'Class')]
    drawing2.add(legend, 'legend')

    Story.append(drawing2)
    Story.append(Spacer(1, 30))
    ptext = '<font size=15><b>Assignments by Standard</b></font>'
    Story.append(Paragraph(ptext, styles["title"]))
    Story.append(Spacer(1, 10))
    t = Table(standard_table)
    t.setStyle(
        t.setStyle(
            TableStyle([
                ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
                ('FONTSIZE', (0, 0), (-1, -1), 7),
                ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey),
                ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ])))
    Story.append(t)
    #build PDF document and return it
    doc.build(Story)
    pdf = buff.getvalue()
    buff.close()
    return pdf