# Graphing expressions

### Assignment Overview

In this assignment, you will create a program for graphing simple functions. You will make heavy use of interfaces, both your own interfaces and ones provided by the Go standard library. There are two main components:

1. An `Expr` (or expression) type, which represents a mathematical function of one variable, for example, `x + 2`, or `3 * x * (x + 7)`. An expression can `Eval` itself on a particular value of `x`, returning a number, and it can `String` itself (producing a string like “x + 2”).

2. A `Graph` struct that implements the `image.Image` interface. A `Graph` holds an `Expr` and some settings, like how big the graph should be and how its axes are arranged.

### Instructions

#### 1The expression interface

Declare an interface for expressions, `Expr`. An expression should be able to `String() string` itself, and `Eval(x float64) float64` its value at a certain float64 value of x.

#### 2The concrete expression types

Implement each of the following expression types as you please:

• `Constant`, an expression representing a constant number, like 2.3 or -50. This should `Eval` to itself, no matter what `x` is. The `String` function should just return a String version of this number. (Use `fmt.Sprintf`.)

• `Negative`, an expression representing the negation of another expression. (You must, of course, store that other expression.) This should print out as `-BLAH`, where `BLAH` is whatever the subexpression prints out as. It should evaluate to the negative of whatever the other expression evaluates to.

• `BinaryOperation`, an expression consisting of two sub-expressions and a binary operation, either `+`, `-`, `*`, or `/`. This should print as `(e1 op e2)`, where `e1` and `e2` are the string versions of the two sub-expressions, and `op` is the operation.

• `Variable`, which represents a variable. (You might choose to implement this as `type Variable string`, where the string is the name of the variable, like “x” or “y”. Just note that your program only supports one variable; you can call it `x` or `y` or whatever, but it’s all the same thing.) It evaluates to whatever `x` is passed into the `Eval` method; it prints out as `x` (or whatever the variable name is).

#### 3The Graph type

Write a struct type, `Graph`, that stores an expression, and some settings: a height and width in pixels, as well as a MinX, MaxX, MinY, and MaxY for the “axes” of the graph. Implement the three methods required for the Image interface:

1. `ColorModel() color.Model`–you can just return `color.GrayModel`.

2. `Bounds() Rectangel`–use `image.Rect(0, 0, w, h)` to return the width and height of your image in pixels.

3. `At(x, y int) color.Color`–the hard one. Given an (x, y) coordinate, decide what color to paint that pixel of the image. To do this, you need to first figure out what “real value” x corresponds to. If x is the 5th pixel in a 100-pixel image, and the axis goes from MinX = 0 to MaxX = 20, then x = 5 really corresponds to x = 1, 1/20th of the way across the axis. Once you have this, you need to evaluate your Expr at this point. This will give you a y value. Calculate what pixel that y value would land on, based on the y axis’s scale. If that pixel number is the y value passed in to you, return black (`color.Gray{0}`). Otherwise, return white (`color.Gray{255}`).

#### 4Main function

In your main function, create a few expressions, and save them to files using code like the following:

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21``` ```func main() { var e1 Expr = ... var e2 Expr = ... var graph1 = Graph{e1, 100, 100, ..., ..., ..., ...} var graph2 = Graph{e2, 100, 100, ..., ..., ..., ...} f1, err := os.Create("graph1.png") if err != nil { panic("Error opening graph1.png") } png.Encode(f1, graph1) f1.Close() f2, err := os.Create("graph2.png") if err != nil { panic("Error opening graph2.png") } png.Encode(f2, graph2) f2.Close() } ```