Code explaination:
1)
Import Python’s libraries:
- “[Link]” to plot the graph
- “numpy” used for numerical operations, generating number sequences
- “math” to use mathematical functions like sin, cos, tan, sqrt, and
constant like pi, e
2)
Create a dictionary that user can type expressions like (e**x, ln(x), pi*x,…)
- Line 5: contains math modules (sin, cos, sqrt,…) and numpy functions
(exponent, log10, log2, ln,…)
- Line 6, 7: defining “ln” as [Link] (natural log); “log10”, “log2” as
np.log10 (log base 10) and np.log2 (log base 2) respectively; “[Link]”
and “math.e” makes sure to be used directly
3)
Defines a function that safely evaluate the input like (e+5) or (pi/4)
- eval(expression, {“__builtins__”: None, **math_dict}):
o evaluate the input expression
o “__builtins__”: None = disable all built-in function in Python
o **math_dict = only allow math fucntions, constants from
math_dict
- Return the eval() function as a float data type
for example: input: 2*pi will return as 6.2831…)
- If fail, print error and exit
4)
Ask user to input a function and an interval
5)
- Line 25 to 27: check if the user input valid interval
- Line 28 to 31: check if b – a < 100, then we’ll generate 100 000 points
in an interval to plot the graph smoother, otherwise, 90 000 points will
be generated
6)
- [Link](a, b, n): generates an array of evenly spaced numbers over
interval [a, b]
- y = []: assign an empty list to y
- Line 36 to 45:
o a for-loop to loop every value (val) in array x
o “try:” used to test a block of code for error, “except Exception as
e:” used to handle error when an error occurs within the “try:”
block and append [Link] to y (nan = not a number).
o result = eval(expression, {“__builtins__”: None, **math_dict,
“x”: val})
evaluate the input expression
“__builtins__”: None = disable all built-in function in
Python
**math_dict = only allow math fucntions, constants from
math_dict
“x”: val = substitute the current x value
Assign the eval() to result
o “if not [Link](result) or abs(result) > 1e6”: is used to check if
the result is a none finite result or a really large number, then
append [Link] to y. Otherwise, append the result to y (In general,
eliminate infinite and extremely large value)
- Line 47 to 51:
o Convert y from list to array
o Compute the difference between two consecutive value of y, for
example, y = [1, 2, 5] => dy = [Link](y) = [2-1, 5-2] = [1, 3]
o large_jump = [Link](abs(dy) > 1e4)[0]:
detect where the graph jump too much
[Link]()[0] will return the array if the condition
abs(dy) > 1e4 is True. For example, dy = [-10004, 5,
2, 20000] => [Link](abs(dy) > 1e4) will return [0, 3]
(first and fourth element of the array)
y[large_jump], y[large_jump + 1] will be assigned to nan
since the discontinuity affects both sides of the jump
- the except block will not stop the plotting process, just skipping invalid
point.
7)
Line 53 to 58, code to plot the graph using matplotlib:
- plot(): to draw a line from point to point in a diagram
o x = all points on the x-axis, y = all points of the y-axis
o color=“green” mean the line will be colored green
- title(): set a title of the plot
- xlabel(), ylabel(): set a label (name) for x and y axis
- grid(): create a grid line for the plot
- show(): show the plot
8) Some test cases:
a) f(x) = tan(x) in [0, pi/2]
b) f(x) = (x^2 + 3x – 5)/(x – 1) in [-20, 20]
c) f(x) = ln(pi*x) in [-15, 20]