#!/usr/bin/python3

from math import exp, factorial

xmin = -6
xmax = 0.2
ymin = -5
ymax = 1.1
wd = 1280
ht = 960
res = (xmax - xmin) / 10000

def point_to_coord(x, y):
    # (xmin, ymin) should map to (0, ht)
    # (xmax, ymax) should map to (wd, 0)
    x_scaled = (x - xmin) / (xmax - xmin) * wd
    y_scaled = (1 - (y - ymin) / (ymax - ymin)) * ht
    return (x_scaled, y_scaled)

def svg_line(x1, y1, x2, y2, **kwargs):
    (x3, y3) = point_to_coord(x1, y1)
    (x4, y4) = point_to_coord(x2, y2)
    attr = set_defaults(kwargs.copy())
    attr["d"] = f"M {x3} {y3} L {x4} {y4}"

    return svg_path(attr)

def set_defaults(attr):
    if "fill" not in attr:
        attr["fill"] = "none"
    if "stroke" not in attr:
        attr["stroke"] = "black"
    if "style" not in attr:
        attr["style"] = f"stroke-width: 2;"
    return attr

def gen_path(f, a, b, k):
    points = []
    x = a
    while x <= b:
        points.append(point_to_coord(x, f(x)))
        x += k
    return points

def path_to_svg_dir(path):
    lines = [ f"M {path[0][0]} {path[0][1]}" ]
    for i in range(1, len(path)):
        lines.append(f"T {path[i][0]} {path[i][1]}")
    return lines

def plot(f, **kwargs):
    attr = kwargs.copy()
    set_defaults(attr)
    attr["d"] = " ".join(path_to_svg_dir(gen_path(f, xmin, xmax, res)))
    return svg_path(attr)

def svg_path(attr):
    return "<path " + " ".join([f'{k}="{attr[k]}"' for k in attr.keys() ]) + "/>"

def frame(which_mac):
    lines = []
    lines.append(f'<svg viewBox="0 0 {wd} {ht}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">')
    lines.append('<g>')
    lines.append(f'<rect width="{wd}" height="{ht}" fill="white" />')
    lines.append(svg_line(xmin, 0, xmax, 0, stroke="gray"))
    lines.append(svg_line(0, ymin, 0, ymax, stroke="gray"))
    lines.append(plot(exp, stroke="lightblue", style="stroke-width: 4;"))
    lines.append(plot(macpoly(which_mac), stroke="red", fill="none"))
    lines.append('</g>')
    lines.append('</svg>')
    return lines

def macpoly(n):
    def _f(x):
        sum = 0
        term = 1
        for i in range(0, n+1):
            sum += term
            term *= x
            term /= (i+1)
        return sum
    return _f

def sq(x):
    return x*x

from sys import argv

print("\n".join(frame(int(argv[1]))))
