Streamlined plotting program for functions

This version of the program has some unnecessary parts of the program from Wednesday's class cleaned out. It also has some comments added, and the actual printing is done differently. It should be easier to understand.

#!/usr/bin/env python3
'''
Streamlined function-plotting program.
2021-04-14
'''
import math
import shutil

# This is a GLOBAL variable!
# It gets its value in main(),
# while myftn() and expftn() use its value.
scale = None

# Lots of interpolation between the range and domain
# (x- and y- values) of the functions, and the number
# of rows and columns of the display.
# This function does all those interpolations:
def interpolate(xmid, xa, xb, ya, yb):
    return ya + (yb - ya) * (xmid - xa)/(xb - xa)
#--------


# Two example functions to plot:

def myftn(x):
    return (math.sin(x) * math.cos(scale * x))
#--------

def expftn(x):
    return (x**2 * math.exp(-scale * (x**0.8)))
#--------


# Make a horizontal plot of two lists of x- and y- values.
def plot_xy(yvals, n_rows):
    n_cols = len(yvals)
    ymin, ymax = min(yvals), max(yvals)

    # Count down from top row to bottom row:
    for r in range(n_rows-1, -1, -1):
        y_r = interpolate(r, 0, n_rows, ymin, ymax)

        for c,  in range(n_cols):
            # Build an entire row's worth of characters into
            # a single string, then print that string all at once:
            rowstring = ''

            # if y-for-this-row is between 0 and y-for-this-column,
            # draw a character
            y_c = yvals[c]
            if y_c >= y_r >= 0  or  y_c <= y_r  <= 0:
                rowstring += '*'
            else:
                rowstring += ' '

        print(rowstring)
#--------

# Given an arbitrary function and the size of
# the display space, build the list of x-values
# for each column and the list of corresponding y-values.
# Then call "plot_xy()" to display them.

# Also, show how to use list comprehensions in place of loops.
#
def draw_function(xmin, xmax, n_cols, n_rows, y_ftn):
    #xvals = []
    #for c in range(n_cols):
    #    xvals.append( interpolate(c, 0, n_cols, xmin, xmax))
    xvals = [ interpolate(c, 0,n_cols, xmin,xmax) for c in range(n_cols) ]

    #yvals = []
    #for x in xvals:
    #    yvals.append( y_ftn(x) )
    yvals = [ y_ftn(x) for x in xvals ]

    plot_xy(yvals, n_rows)
#--------


def main(argv=[__name__]):
    global scale

    n_cols = shutil.get_terminal_size()[0] - 6
    n_rows = shutil.get_terminal_size()[1] - 4
    if len(argv) == 3:
        xrange = float(argv[1])
        scale = float(argv[2])
    else:
        xrange = float(input('x_range? '))
        scale = float(input('Scale? '))

    x = 1e-99
    xmax = xrange * math.pi

    # Provide a function, and plot it of the x range:
    draw_function(x, xmax, n_cols, n_rows, expftn )
#--------

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))
#--------