solution_154c.py

#!/usr/bin/python3
# ====================================================================
# test sgn function and square wave
# https://en.wikipedia.org/wiki/Square_wave
# ====================================================================

import math
import matplotlib.pyplot as plt

# --------------------------------------------------------------------
# ---- class - square wave object
# ---- t0   start (time +/- ? if random)
# ---- hz   frequency (hertz) (cycles/second)
# ---- ran  randomize start time
# --------------------------------------------------------------------

class squareWave:

    def __init__(self,t0,hz):
        self.t0   = t0
        self.hz   = hz

    # ---- return wave's size/value/magnitude/strength at
    # ---- time t (seconds since t0)

    def value(self,t):
        freq = self.hz
        rad = 2.0*math.pi*freq*t
        v = sgn(math.sin(rad))
        return v

# -------------------------------------------------------------------
# ---- float range generator (start and end inclusive)
# -------------------------------------------------------------------

def frange(start,end,steps):
    step = abs((end-start)/(steps))
    f = start
    while True:
        yield(f)
        if f is not None: f += step
        if f > end:       f = None

# --------------------------------------------------------------------
# ---- my sign function
# --------------------------------------------------------------------

def sgn(x):
    if x  > 0: return 1
    if x == 0: return 0
    return -1

# --------------------------------------------------------------------
# ---- calculate/generate a list of values
# ----
# ---- tlst is a list of sample times within the sample
# ---- range. Every wave function should use the same tlst.
# ---- Sample times are monotonically increasing from sample
# ---- start time to sample end time (inclusive).
# --------------------------------------------------------------------

def calculate_wave_values(tlst,wave):
    slst = []
    for t in tlst:
        s = wave.value(t)
        slst.append(s)
    return slst

# --------------------------------------------------------------------
# ---- create a list of sample times
# ---- based on the sample start and end time, and the sample size
# ---- Note: the time list is a monotonic increasing list
# --------------------------------------------------------------------

def time_list(sstart,send,ssize):
    tlst = []
    for t in frange(sstart,send,ssize):
        if t is None: break     # end of range?
        tlst.append(t)
    return tlst

# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------

if __name__ == '__main__':

    # ---- required: t0 < tstart < tend

    hz     = 1.0       # wave frequency (hertz) (cycles/second)
    t0     = 0.0       # wave start time    (second)
    sstart = 0.0       # sample start time  (second)
    send   = 2.0       # sample end time    (second)
    ssize  = 1000      # sample size
    
    print(f't0     = {t0}')
    print(f'hz     = {hz}')
    print(f'sstart = {sstart}')
    print(f'send   = {send}')
    print(f'ssize  = {ssize}')

    # ---- get a list of sample time values
    
    tlst = time_list(sstart,send,ssize)

    # ---- get a list of value samples for each time in tlst

    square_wave = squareWave(t0,hz)
    
    vlst = calculate_wave_values(tlst,square_wave)

    # ---- plot data

    plt.figure(figsize=(10,4))
    plt.title('Square Wave')
    plt.xlabel('sample time', fontsize=14)
    plt.ylabel('sample value', fontsize=14)
    plt.plot(tlst,vlst,'black')
    plt.grid()
    plt.show()