Fun with Python: an Input Game

I know, I know. It’s not Mathematica, but please bear with me.

Python vs. Mathematica

For starters, it wouldn’t be fair for me to compare them for several reasons:

  1. I have years of experience with Mathematica vs. the few weeks I’ve been working with Python.
  2. The two languages were created for very different purposes.

I’ll try anyway, if only for fun.

It’s interesting to see how different it is from Mathematica. For example, whitespace characters (i.e. tabs) actually have a function. Unlike Mathematica, I can’t haphazardly put enters wherever I want, nor is it automatic! I also need to keep my code well-organized because it takes so many more lines to write what could be one function in Mathematica, and Canopy (my Python interpreter) lacks the organization and aesthetic beauty of notebooks.

pythoninputs1.png
Compare and contrast.

At the same time, Python seems to be much faster than Mathematica at running code, even though both are higher level languages; they probably wouldn’t compare with something like C in terms of speed. And although Mathematica is more intuitive with pulling off calculations and visualizing data, Python has much greater flexibility and readability for other kinds of tasks. There probably many more things Python can do that I’m not aware of. Otherwise, why would it be so popular?

Defining Essential Functions

Many of Python’s more useful functions come in modules. We should all thank the generous individuals who have created these functions for us. We will use the sys module for the function sys.exit().

import sys

This program relies on counting the number of characters in each input and determining whether they are odd or even and, in the case of the user’s name, whether it is prime. We could use len() by itself, but the problem is that it does not subtract spaces. We can define a simple function named character() just in case someone uses their full name.

def character(word):
    return len(word) - word.count(' ')

The next step is to define a function that can determine whether a number is prime. Technically, we could use an existing library of prime numbers, which would be faster. Instead of importing a library, how about we make something that can check if a number is prime on the go? Let’s make a series of tests:

  1. Is the number (we’ll call it “n”) less than 2? If so, it is not prime. This automatically excludes 0 and 1. Negative numbers cannot be prime, either, but that does not matter because we cannot have a string of negative length.
  2. If n is greater than 2, is it divisible every number between 2 and itself? A prime number is defined as something that can only be divided by 1 and itself. We’ll use a for loop to test every number. Remember that range() does not include the second parameter/final number.
  3. If n passes the above tests, return True. Otherwise, return False.
def primeQ(n):
    if n < 2:
        return False
    else:
        for i in range(2,n):
            if n % i == 0:
               return False
        return True
Creating the Story

Now that everything is in place, we can begin making the actual program. Start by taking the user’s name, birth month, and favorite color. Use raw_input() to turn the input into a string; using input() will try to run the input as a function. For example, entering “Ellen” as the name will store a string for raw_input() but will cause an error for input() if there is no variable called “Ellen.” Use the character() function we defined earlier to store the number of letters in each input as a variable.

name = raw_input('Enter your name: ')
nameLetters = character(name)
month = raw_input('Enter your birth month: ')
monthLetters = character(month)
color = raw_input('Enter your favorite color: ')
colorLetters = character(color)

Then, determine if the number of characters in “name” is prime, odd, or even.Because we’ll need this information later, we’ll create a variable to store a value that shows what kind of number it is.

if primeQ(nameLetters) == True:
    nameValue = 1
elif nameLetters % 2 == 0:
    nameValue = 2
else:
    nameValue = 3

Before we create the story, we’ll have to make sure the user entered the right information.

  1. Ask the user if the information they entered is correct in a way that is readable with rawinput(). Because the user could answer “yes” or “no” in many different ways, ask them to enter “Y” or “N.”
  2. If the answer is “Y” for “yes,” continue to the story.
  3. If the answer is “N” for “no,” end the program. We could use quit() or exit(), but it is better to explicitly import the sys module and use sys.exit(), which functions pretty much the same way. Using quit() or exit() relies on the site module, which might not always be there, unlike sys.
answer = raw_input('This is what you entered:\n'
+ 'name: ' + name + '\nmonth: ' + month + '\ncolor: ' + color
+ '\nIs this correct? Enter Y or N.\n')

if answer == 'Y':
    print('Beginning...\n')
else:
    print('Sorry. Please try again.')
    sys.exit()

The rest of the code is a bunch of if statements that check whether monthLetters() and colorLetters are odd or even. For example, the following code checks whether the remainder of colorLetters and 2 is zero (if it’s even). If so, it prints a certain line of text that incorporates the user’s name. A different line of text is produced if it is odd.

if colorLetters % 2 == 0:
    print(name + ' is removed from school for their concerningly erratic behavior. '
    + name + ' burns down the psychiatric ward and escapes to Europe with a fake identity.')
else:
    print(name + "'s teachers say that they are gifted. " + name + ' becomes a young oil tycoon'
    + ' and becomes the youngest billionaire in the world. Climate change worsens.')

Finally, we can test the code. Here’s a run with my information (the bolded words are my inputs).


Enter your name: Ellen

Enter your birth month: February

Enter your favorite color: purple

This is what you entered:
name: Ellen
month: February
color: purple
Is this correct? Enter Y or N.
Y
Beginning…

Ellen is synthetically created on a cloudy February day.
Ellen is actually a robot. Ellen is mistakenly adopted by their current family.
Ellen is removed from school for their concerningly erratic behavior. Ellen burns down the psychiatric ward and escapes to Europe with a fake identity.
Ellen gets married and has 6 children.
Ellen pokes a button and accidentally kills 6.5 billion people. The world is in a crisis.
Ellen falls in a pool and dies at the age of 72.
Ellen will be greatly missed. The end.


As usual, everything is here, on Pastebin. There’s a collapsed preformatted block of text at the bottom. Look! Now that I’m using Python, I can take full advantage of the preformatted function on WordPress!

"""
This project outputs a story based on the character length of their inputs.
Visit my WordPress at ellenleescience.wordpress.com
"""
import sys
def character(word):
    return len(word) - word.count(' ')
    # subtract the number of empty spaces just in case someone puts their full name
def primeQ(n):
    # we need to find whether the number of letters if prime for later
    # 1 and 0 are not prime, and negatives are impossible
    if n < 2:
        return False
    else:
        # divide n by every number from 2 to n, since a prime can only be divided by 1 itself
        for i in range(2,n):
            # if the remainder is zero for any number, it is not a prime number
            if n % i == 0:
               return False
        return True
        # if n passes every test, it is prime

name = raw_input('Enter your name: ')
nameLetters = character(name)
month = raw_input('Enter your birth month: ')
monthLetters = character(month)
color = raw_input('Enter your favorite color: ')
colorLetters = character(color)

# now we determine if nameLetters is prime for later
if primeQ(nameLetters) == True:
    nameValue = 1
elif nameLetters % 2 == 0:
    nameValue = 2
else:
    nameValue = 3

answer = raw_input('This is what you entered:\n'
+ 'name: ' + name + '\nmonth: ' + month + '\ncolor: ' + color
+ '\nIs this correct? Enter Y or N.\n')

if answer == 'Y':
    print('Beginning...\n')
else:
    print('Sorry. Please try again.')
    sys.exit()

# the rest of the story is determined by nameValue and whether each Letters value is odd or even
if nameValue == 1:
    print(name + ' is synthetically created on a cloudy ' + month + ' day.')
    print(name + ' is actually a robot. ' + name + ' is mistakenly adopted by their current family.')
elif nameValue == 2:
    print(name + ' is born on a stormy ' + month + ' night.')
    print(name + ' is abandoned by their family. They are raised by stray dogs.')
else:
    print(name + ' is born on a sunny ' + month + ' day.')
    print(name + ' lives with a happy family until their parents die in an accident in the lab.')

if colorLetters % 2 == 0:
    print(name + ' is removed from school for their concerningly erratic behavior. '
    + name + ' burns down the psychiatric ward and escapes to Europe with a fake identity.')
else:
    print(name + "'s teachers say that they are gifted. " + name + ' becomes a young oil tycoon'
    + ' and becomes the youngest billionaire in the world. Climate change worsens.')

print(name + ' gets married and has ' + str(colorLetters) + ' children.')
if monthLetters % 2 == 0:
    print(name + ' pokes a button and accidentally kills 6.5 billion people. The world is in a crisis.')
else:
    print(name + ' finds a cure to rabies, but their research is stolen. They never recieve credit.')

if nameValue != 1:
    print(name + ' lives to the ripe age of ' + str(monthLetters*9) + '.')
    print("Cause of death:")
    if colorLetters % 2 == 0:
        print('tripped on a banana peel')
    else:
        print('hit by a meteor')
else:
    print(name + ' falls in a pool and dies at the age of ' + str(monthLetters*9) + '.')

print(name + ' will be greatly missed. The end.')

P.S.: How does the Python logo work?

Advertisements

Sampling Error in Mathematica

Happy Halloween!

In the spirit of Halloween, it seems that my Mathematica stopped functioning for the past week (too spooky for me :O). Manipulate[], arguably the most useful function in the program, refused to work. It got to the point where something as simple as this

Manipulate[ToString[a], {a, 0, 1}]

would not work at all!

Thankfully, we’re back up and running. Off to sampling errors!

Sampling Sound Waves

Although we often like to think that sampling will always yield accurate results, this often is not the case. Consider the images below:

sampling1

The red points represent how often a point from the function is taken. The first example shows that the predicted red function matches the actual wave. However, the next one shows how it seems as if the amplitude of the function is changing. And the last one shows that by taking samples 2Pi increments away from each other, you get a straight line. It should be noted that the sampling itself is a flaw caused by human error; this error is very much different from the fact that there is “infinite precision” for vector graphs.

Such is the danger of interpolating data without sufficient sampling. An interactive version of the above and the code for the images themselves can be found here.

Sampling errors are present in our daily lives as well! The most intuitive example is with sound. Hypothetically, a higher frequency means a higher pitched sound.

(Note: I actually wasn’t aware that you could play sounds in Mathematica until a little less than a year after I started using it. That just goes to show that there are so many unexplored features of this program… I wonder how many people specialize in fields that I’m not even aware of? I feel as if I am pulling so many layers off this onion that the pile of onion shavings is hundreds of times larger than what would seem possible for its size. /rant)

sampling2

And for a while, the sounds actually do get higher pitched. If you look at the wave with a frequency of 20,000, you can see that Mathematica is struggling.

sampling3But if you suddenly increase the frequency to 256,000, the pitch dramatically decreases. So what gives?

sampling4

This is actually a problem concerning hardware. By trying to play this sound, you’re literally forcing your headphones (or speakers) to vibrate so quickly that there is now way for it to keep up. By trying to oscillate quickly, it downgrades the frequency of its pitch to a harmonic of 256,000; if you want to see a really good example of this, set the interactive code’s sampling value at 5.5.

sampling5.png

Everything suddenly seems lower pitched. If there’s a lesson here, I guess it’s that you should always be careful how you sample… You may even end up with a flat line.

sampling6.png
Probably not how this works, but still.

P.S.: Many of the ideas for this post came from my research mentor Dr. James Choi. I am very grateful for his help!

Update: New Pages and Polar Coordinates

Hello! I have been busy this month with science fair and with making new pages for this blog. I have added a page for the project my partner, Azja Czajkowski, and I brought to the Greater San Diego Science and Engineering Fair. I also added a page for my (actual) experiments. Although there currently is not much on that page, I will be uploading more files there soon. Please check out those pages by following the links above!

I also have something else that was too short to be worthy of its own post.

Polar vs. Cartesian Coordinates

When I was learning Calculus BC, I was confused by polar coordinates. Although I understood how to plot points, trigonometric functions confused me. How could a sine function become a circle? How did shifting the sine function up or down in Cartesian coordinates cause the polar graph to turn into an odd loop shape? This program (link to code) helped me understand how polar coordinates worked. The reason why a loop shape comes out of a vertically shifted sine function is because a normal sine function actually drew the circle twice. Shifting the function up or down would shift where the point was drawn (the radius). I could also understand the parallels between polar and Cartesian coordinates, and it helped me realize how easy polar coordinates were.

Here is a video demonstration of the program (link).polar

Mathematica is not just an “Expensive Calculator” (pt. 2): Calculus-Based “Calculators”

(part 1)

It would be a waste to make a Riemann sum finder and not make more calculus-related “calculators.”

The Equation of a Tangent Line

We can find the equation of a function’s various tangent lines using the function’s derivative. This tool allows the user to manipulate the point where the tangent line hits any given function. Here is a video demonstration (link) and the source code (link). This is how the code was constructed:

  1. use Plot[] to draw the original function and the general equation for a tangent line (I used “n” as a placeholder for the x-value)
  2. use Epilog to draw the point where the tangent line meets the graph
  3. PlotLabel (in the graph) will equation of the tangent line, so use a combination of <> and ToString[]
  4. display the contact point’s coordinates next to the point using Text[] (tip: to get the position of the text, take the original point and offset it by a small amount)
  5. optional: change the colors to make it look cool

tangent

Revolution of Solids

The volume of a solid found by rotating a graph around the x-axis, y-axis, or another line can be found using integrals. This small widget displays the graph of the function, its revolution, and the area. The degree of revolution can be manipulated and a function can be entered. Here is a demonstration (link) and here is the source code (link). The following steps show how the code was created:

  1. plot a function using RevolutionPlot3D[]
  2. change the degree of revolution to 0 to “a” (the letter “a” will be manipulated as the degree of revolution)
  3. calculate the area of the solid for the PlotLabel (tip: the area should be pi times the integral of the function squared, from 0 to “a”)
  4. make sure the code works, then replace the function with the letter “f” (you should be able to enter the function, but make sure that there is an initial function)
  5. use Manipulate[] to change the values of “a” and “f” – make sure that “a” starts from a number close to but not equal to zero

revolution1.png

freetime

 

Mathematica is not just an “Expensive Calculator” (pt. 1): Making a Few Small Widgets

I am putting the survey analysis on hold for a little while, because this is a bit more interesting. It’s quite different from what I have done on this blog up to this point.

People often joke that Mathematica is just an expensive calculator, even though it is capable of so much more. Here are a few small widgets just to humor these critics.

A Basic, One-Digit Calculator

Now we will reconstruct a basic, one-digit calculator. Here’s the code (link), and here’s the calculator in action (link). The process is listed below:

  1. create a grid of buttons using Column[], Row[], and Button[], and put a frame around it to make it look cool
  2. make 2 chosen variables equal “Null” (num1 and num2 for the two numbers that will be operated upon)
  3. make the button change the value of the 2 variables based on their value using If[]
  4. make operation buttons that will only act upon the variables if they are numbers

Here is a picture of the finished calculator, in case you can’t click the links. The second link (above) will show it in action.

calculator

Riemann Sum Finder

How about something more sophisticated, like a widget that will draw and find the Riemann sum of a function? Here’s the code (link), and here is are two demonstrations of the program (link 1, link 2). The process is listed below:

  1. make a plot that will draw a given function
  2. use Graphics[] to draw rectangles: the height should be based on the output of the function and the width should be 1 divided by the number of desired rectangles (tip: start with a constant number of rectangles before using Manipulate[])
  3. the height of the rectangles should be able to shift from left to middle to right by shifting the inputted value
  4. use Show[] to plot the function with the rectangle graphics and add Manipulate[] to make it interactive

riemann

CASnope