Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
of values that represent a single<br />
sinewave cycle and then clocks those<br />
samples through a digital-to-analog<br />
converter (DAC) at a particular rate,<br />
the clock rate determining the output<br />
sinewave frequency. For example, if<br />
you have one complete sinewave cycle<br />
stored as 1,000 digital samples and<br />
play those samples through a DAC at<br />
the rate of 1,000 samples per second<br />
(1,000Hz), it’d take one second to<br />
output that complete cycle, so the<br />
output frequency of that sinewave<br />
would be one cycle per second or 1Hz.<br />
But if we played out those 1,000<br />
samples at the rate of 1MHz<br />
(1,000,000Hz), it would take only one<br />
millisecond to play the stored cycle,<br />
giving an output frequency of 1/0.001 =<br />
1,000Hz. Now I don’t want to have to<br />
calculate the sinewave value table for<br />
all 1,000 samples by hand, so we’ll get<br />
Python to calculate it instead.<br />
Go the source code zip file again and<br />
this time, load up ‘dds.py’. What we<br />
need in this example is to divide a full<br />
sinewave into 1,000 discrete values.<br />
If you remember back to school maths,<br />
a full sinewave cycle occurs over a<br />
360-degree range, so if we divide that<br />
360-degrees into 1,000 steps and store<br />
away the sine value of each one in<br />
turn, we’ll have our DDS value table.<br />
In fact, our dds.py source code goes<br />
a step further by allowing you to enter<br />
the number of samples you require<br />
and generating a value table based on<br />
that sample count, printing the values<br />
to the console. If you copy and paste<br />
the table values into Excel, you can<br />
create a simple line chart showing<br />
Replicate the same<br />
random-number<br />
sequence by using<br />
random.seed().<br />
Python needs help to<br />
determine equality<br />
of decimal numbers.<br />
the sinewave the table generates —<br />
we’ve done this over 6, 12, 18, 24, 30<br />
and 36 samples and as you might<br />
expect, the more samples you create,<br />
the greater the sinewave accuracy<br />
(the smoother it looks).<br />
FREQUENCY RESPONSE<br />
One of the more basic things you learn<br />
in electronics is how to make a circuit<br />
element called a ‘filter’ using just a<br />
resistor and a capacitor — connected<br />
one way, the circuit allows highpitched<br />
frequencies to pass and<br />
progressively blocks lower<br />
frequencies; connected the other way,<br />
it’s ‘vice-versa’. Either way, there’s a<br />
simple mathematical formula<br />
governing how the basic resistorcapacitor<br />
or ‘RC’ filter works:<br />
3dB cutoff-frequency =<br />
1 / (2 x pi x R x C)<br />
where ‘pi’ is 3.1415..., ‘R’ is the<br />
resistor value in ohms and ‘C’ is<br />
the value of capacitance in farads.<br />
The cutoff point is the frequency<br />
at which the signal amplitude drops<br />
by 3dB from its peak (beyond the 3dB<br />
point, it falls away at the rate of 6dB<br />
per octave).<br />
Load up ‘filter.py’ from the source<br />
code zip and you’ll find a simple 3dB<br />
frequency calculator that uses the<br />
math.pi constant. Python has a<br />
number of math module constants<br />
including Euler’s constant ‘e’ (math.e,<br />
2.718...) and math.tau or pi*2.<br />
To make the app easier to use,<br />
we’ve set the input required to<br />
kiloohms (kΩ) and microfarads (uF),<br />
which are much common units<br />
(at least for audio-frequency work)<br />
than standard ‘ohms’ and ‘farads’.<br />
RANDOM NUMBERS<br />
Random numbers are a vital part of<br />
most computer games — they create<br />
the ‘randomness’ in the action you<br />
need for a game not to become too<br />
predictable. They’re also important<br />
to computer security, but you need<br />
to understand how they work in<br />
Python, especially their limitations.<br />
Python’s ‘random’ module is<br />
separate from the math module and<br />
uses a random number generation<br />
algorithm called the ‘Mersenne<br />
Twister’ to create floating-point<br />
random numbers between 0.0 and 1.0.<br />
However, they’re not strictly ‘random’<br />
— the Mersenne Twister algorithm<br />
will eventually begin repeating<br />
itself, although not until after<br />
2^19,937 iterations. Even so, that<br />
makes the Python ‘random’ module<br />
a ‘no-go’ for security applications.<br />
Here, Python recommends you use<br />
the ‘secrets’ module instead.<br />
But one particularly useful feature<br />
with the random module is the ability<br />
to seed the random number<br />
progression, enabling you to create<br />
a repeatable random number series,<br />
useful in debugging and data mining.<br />
For example, run the code:<br />
random.seed(4)<br />
print(random.random())<br />
print(random.random())<br />
print(random.random())<br />
And then run it again. Note the two<br />
sets of random numbers generated<br />
— they should be exactly the same.<br />
If you don’t start random() with a<br />
seed, Python will use the current<br />
time as a seed instead, ensuring the<br />
random number stream won’t repeat<br />
for some time.<br />
The other thing that random() does<br />
is produce pseudo-random numbers<br />
that are of ‘uniform distribution’ —<br />
that means any number between 0.0<br />
and 1.0 is equally likely to be chosen.<br />
But there are many other<br />
distribution ‘shapes’ you can<br />
generate, including triangular,<br />
betavariate, expovariate and<br />
Gaussian, all useful for statistical<br />
applications.<br />
GIVE IT A GO<br />
Whether it’s in science, technology<br />
or engineering, mathematics really<br />
is a fundamental part of life — and<br />
with Python’s collection of mathsbased<br />
modules, you can quickly<br />
incorporate all sorts of mathematical<br />
functions into your apps.<br />
www.apcmag.com 109