solution_154e.py

#!/usr/bin/python3
# ====================================================================
# test sawrooth wave
# https://en.wikipedia.org/wiki/sawtooth_wave
# ====================================================================

import math
import matplotlib.pyplot as plt

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

class sawtoothWave:

    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
        period = 1/freq
        v = 2*(t/period - math.floor((1/2) + (t/period)))
        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

# --------------------------------------------------------------------
# ---- 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     = 10        # 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)

    print(f'tlst len={len(tlst)} [0]={tlst[0]}')

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

    sawtooth_wave = sawtoothWave(t0,hz)
    
    vlst = calculate_wave_values(tlst,sawtooth_wave)

    print(f'vlst len={len(vlst)} [0]={vlst[0]}')

    # ---- plot data

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