Difference between revisions of "CSC111 Lab 5 2014"
(→Solutions) |
|||
(49 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
--[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 18:16, 25 February 2014 (EST) | --[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 18:16, 25 February 2014 (EST) | ||
---- | ---- | ||
− | |||
<br /> | <br /> | ||
+ | <bluebox> | ||
+ | This lab presents JES as a practical way of manipulating sound files. This requires only single for-loops. The remaining part of the lab contains many small exercises dealing with for-loop with the intent of mastering the use of single for loops in many different situations. | ||
+ | </bluebox> | ||
+ | <br /> | ||
+ | __TOC__ | ||
+ | <br /> | ||
+ | |||
+ | =Single for-loops= | ||
+ | <br /> | ||
+ | * Create a new program called '''lab5.py''' | ||
+ | <br /> | ||
+ | :<source lang="python"> | ||
+ | # lab5.py | ||
+ | |||
+ | for i in range( 3, 8 ): | ||
+ | print( i ) | ||
+ | </source> | ||
+ | <br /> | ||
+ | * Verify that you get the correct output: | ||
+ | |||
+ | <u>'''python3 lab5.py'''</u> | ||
+ | 3 | ||
+ | 4 | ||
+ | 5 | ||
+ | 6 | ||
+ | 7 | ||
+ | |||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ==Challenge Block 1== | ||
+ | |} | ||
+ | [[Image:QuestionMark4.jpg|right|120px]] | ||
+ | |||
+ | * Now, your turn! | ||
+ | |||
+ | ;List of numbers, Version 2 | ||
+ | : Modify your loop so that it does not use the ''range( )'' function (Hint: you have to list all the values) | ||
+ | |||
+ | ; List of even numbers: | ||
+ | : write a loop that prints all the even numbers between 4 and 20, 4, and 20 included (you can use range or list all the numbers). | ||
+ | |||
+ | ;List of odd numbers: | ||
+ | :write a loop that prints all the odd numbers between -3 and 19, -3, and 19 included. | ||
+ | |||
+ | ;User-controlled loops (more difficult): | ||
+ | :Write a new Python program that prints a series of numbers, after having asked the user where the series should start, and where it should end. | ||
+ | |||
+ | :Here is an example of how it should run (the user input is underlined): | ||
+ | |||
+ | <U>'''python3 userLoop.py'''</U> | ||
+ | |||
+ | I will print a list of numbers for you. | ||
+ | |||
+ | Where should I start? <u>'''3'''</u> | ||
+ | |||
+ | What is the last number of the series? <u>'''10'''</u> | ||
+ | |||
+ | 3 4 5 6 7 8 9 10 | ||
+ | |||
+ | :Go ahead and write it. What happens if you ask the program to count from -5 to 5? Does it work correctly? | ||
+ | |||
+ | :Does your program work if you ask your program to go from 1 to 1? | ||
+ | |||
+ | :Can you predict what will be printed if you ask your program to count from 10 to 1? | ||
+ | <br /> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ==Challenge 2== | ||
+ | |} | ||
+ | [[Image:QuestionMark5.jpg|right|120px]] | ||
+ | * Make the last program you wrote print the series numbers between the two numbers entered by the user, wether the first one is less than the second one, or vice versa. | ||
+ | <br /> | ||
+ | For example, here's an example of how the program could work: | ||
+ | |||
+ | Where should I start? '''3''' | ||
+ | What is the last number of the series? '''10''' | ||
+ | 3 4 5 6 7 8 9 10 | ||
+ | |||
+ | :and if the user enters a larger number for the first number, it still prints the numbers in between: | ||
+ | |||
+ | Where should I start? '''7''' | ||
+ | What is the last number of the series? '''2''' | ||
+ | 7 6 5 4 3 2 | ||
+ | |||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | |||
+ | ==Challenge 3== | ||
+ | |} | ||
+ | [[Image:QuestionMark6.jpg|right|120px]] | ||
+ | |||
+ | Write a program that prints the pattern shown below. Do not start right away! Instead read the directions, please! | ||
+ | |||
+ | <code><pre> | ||
+ | >>> ================================ RESTART ================================ | ||
+ | >>> | ||
+ | ---- | ||
+ | *..-----?? | ||
+ | **....------???? | ||
+ | ***......-------?????? | ||
+ | ****........--------???????? | ||
+ | *****..........---------?????????? | ||
+ | ******............----------???????????? | ||
+ | *******..............-----------?????????????? | ||
+ | ********................------------???????????????? | ||
+ | *********..................-------------?????????????????? | ||
+ | **********....................--------------???????????????????? | ||
+ | >>> | ||
+ | </pre></code> | ||
+ | |||
+ | |||
+ | * Instead of starting to program, write down on a piece of paper the number of symbols on each line. For example, | ||
+ | ** on the first line, zero stars, zero dots, four minuses, zero question marks. | ||
+ | ** on the 2nd line, two dots, two question marks. | ||
+ | ** keep on writing how many characters appear on each line. | ||
+ | ** then write a program with a loop that will print just the number of stars on each line. | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <!-- | ||
+ | =Nested For-Loops= | ||
+ | <br /> | ||
+ | |||
+ | This is taken from Section 4.7 in the textbook: | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | for i in range(4): | ||
+ | for j in range( i+1 ): | ||
+ | print( "*", end="" ) | ||
+ | print() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | The output is | ||
+ | <br /> | ||
+ | <source lang="text"> | ||
+ | * | ||
+ | ** | ||
+ | *** | ||
+ | **** | ||
+ | </source> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ==Challenge 3== | ||
+ | |} | ||
+ | [[Image:QuestionMark4.jpg|right|120px]] | ||
+ | |||
+ | * Modify the program so that it outputs this pattern | ||
+ | <br /> | ||
+ | <source lang="text"> | ||
+ | **** | ||
+ | *** | ||
+ | ** | ||
+ | * | ||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ==Challenge 4== | ||
+ | |} | ||
+ | [[Image:QuestionMark9.jpg|right|120px]] | ||
+ | *Modify the program so that it outputs this pattern: | ||
+ | |||
+ | <source lang="text"> | ||
+ | * | ||
+ | ** | ||
+ | *** | ||
+ | **** | ||
+ | </source> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ==Challenge 5== | ||
+ | |} | ||
+ | * Now try this pattern: | ||
+ | <source lang="text"> | ||
+ | **** | ||
+ | *** | ||
+ | ** | ||
+ | * | ||
+ | </source> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | * What about this one? | ||
+ | <source lang="text"> | ||
+ | 1234 | ||
+ | 567 | ||
+ | 89 | ||
+ | 10 | ||
+ | </source> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | --> | ||
+ | |||
=JES= | =JES= | ||
+ | <br /> | ||
+ | <center>[[File:SoundWave.jpg|250px]]</center> | ||
<br /> | <br /> | ||
==Download JES== | ==Download JES== | ||
− | [[File:JESicon.png| | + | [[File:JESicon.png|50px|right]] |
* Download JES 4-3 to your computer from [https://code.google.com/p/mediacomp-jes/downloads/list https://code.google.com/p/mediacomp-jes/downloads/list]. | * Download JES 4-3 to your computer from [https://code.google.com/p/mediacomp-jes/downloads/list https://code.google.com/p/mediacomp-jes/downloads/list]. | ||
− | * If you are running Windows, pick '''jes-4-3.exe'''. Once downloaded, click on the exe file to start JES. | + | * If you are running Windows, pick '''jes-4-3.exe'''. Once downloaded, click on the exe file to start JES. <font color="red">You cannot install JES on one of the Lab computers running Windows. You have to boot them as Mac machines to install it</font>. |
* If you are running Mac OS X, pick '''jes-4-3-mac.zip''', click on the downloaded zip file. Then click on the extracted file to start JES. | * If you are running Mac OS X, pick '''jes-4-3-mac.zip''', click on the downloaded zip file. Then click on the extracted file to start JES. | ||
<br /> | <br /> | ||
+ | <tanbox>For reference, you may want to take a peek from time to time to programs similar to the one we covered in class on Wednesday. They can be found [[CSC111 Sound Modification Exercises| here]]. | ||
+ | </tanbox> | ||
+ | <br /> | ||
+ | |||
==Download a Sound File== | ==Download a Sound File== | ||
<br /> | <br /> | ||
* Download the following file to your computer: | * Download the following file to your computer: | ||
− | ** [[media: | + | ** [[media:force.wav|force.wav]] |
<!-- * [[media:goodbye.wav|goodbye.wav]] | <!-- * [[media:goodbye.wav|goodbye.wav]] | ||
* [[media:dratcomp.wav|dratcomp.wav]] | * [[media:dratcomp.wav|dratcomp.wav]] | ||
− | * [[media: | + | * [[media:hello.wav |hello.wav]] |
* [[media:takeover.wav|takeover.wav]] | * [[media:takeover.wav|takeover.wav]] | ||
* [[Media:guitar.wav | guitar.wav]] --> | * [[Media:guitar.wav | guitar.wav]] --> | ||
<br /> | <br /> | ||
+ | ==Writing Your First JES Program== | ||
+ | <br /> | ||
+ | * Note, you can call your program '''lab5b.py''' if you have used '''lab5.py''' for the first part of this lab. | ||
+ | * Open JES | ||
+ | * Type the following program in the top window: | ||
+ | <br /> | ||
+ | :<source lang="python"> | ||
+ | file = pickAFile() | ||
+ | sound = makeSound( file ) | ||
+ | blockingPlay( sound ) | ||
+ | </source> | ||
+ | <br /> | ||
+ | <center>[[Image:JES1.png|400px]]</center> | ||
+ | <br /> | ||
+ | * click on "Load Program" and save the program in the folder of your choice (a good place would be where you saved the Force.wav file). | ||
+ | * When prompted to enter a file in the '''Pick A File''' window, navigate through your folders and pick '''force.wav''' or '''Force.wav''', which ever way you named it. | ||
+ | * Make sure the speakers are on so that you can hear your computer play the file. Don't worry about making sounds in this lab: this is what this lab is about! | ||
+ | <br /> | ||
+ | |||
+ | ==Visualizing the Waveform of the Sound File== | ||
+ | <br /> | ||
+ | * Once you have played a sound in JES you can access its waveform using the '''Sound Tool''' of the '''MediaTools''' menu at the top of the window (or the screen). | ||
+ | * Open the Sound Tool. This is what you should see: | ||
+ | <br /> | ||
+ | <center>[[Image:SoundToolTheForceWillBeWithYou.png]]</center> | ||
+ | <br /> | ||
+ | * Move the cursor around the waveform and click on different buttons (Play before, Play after, Play selection, etc.) | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <tanbox> | ||
+ | Remember that if you are having trouble writing a for-loop to work on the samples, it is easier to solve a much simpler program in Idle with Python with an array of just a few numbers. So '''do not hesitate to use Idle to generate first solutions before you implement them in JES'''! | ||
+ | </tanbox> | ||
+ | <br /> | ||
+ | ==Clearing Part Of The Waveform== | ||
+ | <br /> | ||
+ | * Position the cursor in the waveform as shown in the image above, just before the words "the force" are uttered by Sir Alec Guinness. Note the ''index'' of the sample where the cursor and assign it to a variable in your JES program, as shown below. Just replace the ... with the actual number | ||
+ | <br /> | ||
+ | :<source lang="python"> | ||
+ | file = pickAFile() | ||
+ | sound = makeSound( file ) | ||
+ | blockingPlay( sound ) | ||
+ | |||
+ | # get start index for clearing | ||
+ | startIndex = ... # index just before "the force..." | ||
+ | </source> | ||
+ | <br /> | ||
+ | * Now that you have the beginning index of the phrase "the force will be with you, always", you can clear it by setting all the samples to 0, as follows: | ||
+ | <br /> | ||
+ | :<source lang="python"> | ||
+ | # clear all the samples from startIndex to end: | ||
+ | noSamples = getLength( sound ) | ||
+ | for i in range( startIndex, noSamples ): | ||
+ | setSampleValueAt( sound, i, 0 ) | ||
+ | |||
+ | # play sound again | ||
+ | blockingPlay( sound ) | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | * Add this new code to the end of your program and run it. It should just play "Remember" and nothing else. Look at the new waveform of your sound with the '''Sound Tool''' (close it first to get rid of the original waveform and reopen it). | ||
+ | |||
+ | <br /> | ||
+ | |||
+ | ==Copying Parts of the Waveform== | ||
+ | <br /> | ||
+ | * The goal of this part is to copy the samples corresponding to "Remember" so that the waveform becomes "Remember Remember". | ||
+ | * You need two functions to perform this operation: | ||
+ | |||
+ | value = '''getSampleValueAt'''( sound, i ) | ||
+ | |||
+ | :which gets the sample at Index '''i''' and stores it in the variable '''value''', and | ||
+ | |||
+ | '''setSampleValueAt'''( sound, i, value ) | ||
+ | |||
+ | :which sets the sample at Index '''i''' to value. | ||
+ | <br /> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ===Challenge #6=== | ||
+ | |} | ||
+ | [[Image:QuestionMark1.jpg|right|120px]] | ||
+ | Add a for loop that copies all the samples of "remember" and duplicates them in the waveform, so that when you play it you hear two "remember" words. | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ===Challenge #7=== | ||
+ | |} | ||
+ | [[Image:QuestionMark2.jpg|right|120px]] | ||
+ | Modify your program so that it transforms the waveform in such a way that when you play it at then end of the transformation it will play "Remember, always!" | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | ===Challenge #8=== | ||
+ | |} | ||
+ | [[Image:QuestionMark8.jpg|right|120px]] | ||
+ | Modify the last waveform ("Remember always") and reverse it so that it plays "backwards" when you play it. | ||
+ | You have two ways of performing it. One simpler than the other one. | ||
+ | * Simpler method: Assume the following numbers represent the samples of the waveform: | ||
+ | |||
+ | 17 18 17 16 11 0 0 0 0 0 0 0 0 0 | ||
+ | |||
+ | :then reversing it would yield: | ||
+ | |||
+ | 0 0 0 0 0 0 0 0 0 11 16 17 18 17 | ||
+ | |||
+ | * The more elegant method (feel free to attempt it) would yield the reversed numbers in the following way: | ||
+ | |||
+ | 11 16 17 18 17 0 0 0 0 0 0 0 0 0 | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | {| style="width:100%; background:silver" | ||
+ | |- | ||
+ | | | ||
+ | |||
+ | ===Challenge #9 (Optional)=== | ||
+ | |} | ||
+ | [[Image:QuestionMark9.jpg|right|120px]] | ||
+ | Modify your program so that it transforms the waveform in such a way that when you play it at then end of the transformation it will play "Remember" with an echo! (Remember, member, mber, ber...). | ||
+ | Be sure to make me listen to this new waveform before you move on to the next part! | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /><br /><br /><br /> | ||
+ | <br /><br /> | ||
+ | |||
+ | =Submission= | ||
+ | <br /> | ||
+ | Copy/paste your JES program into Idle and save the file as '''lab5.py'''. Submit it to this URL: [http://cs.smith.edu/~dthiebaut/111b/submitL5.php http://cs.smith.edu/~dthiebaut/111b/submitL5.php] | ||
+ | |||
+ | <br /> | ||
+ | <br /> | ||
+ | |||
+ | =Solutions= | ||
+ | <source lang="python"> | ||
+ | # lab5 solution programs (loops) | ||
+ | # D. Thiebaut | ||
+ | |||
+ | # single For-Loops | ||
+ | """ | ||
+ | for i in range( 3, 8 ): | ||
+ | print( i, end=" ") | ||
+ | print() | ||
+ | |||
+ | for i in [3, 4, 5, 6, 7]: | ||
+ | print( i, end=" " ) | ||
+ | print() | ||
+ | |||
+ | |||
+ | for i in range( 4, 20+1, 2 ): | ||
+ | print( i, end=" " ) | ||
+ | print() | ||
+ | |||
+ | |||
+ | for i in range( -3, 19+1, 2 ): | ||
+ | print( i, end=" " ) | ||
+ | print() | ||
+ | |||
+ | start = int( input( "start where? " ) ) | ||
+ | end = int( input( "end where? " ) ) | ||
+ | if start <= end: | ||
+ | for i in range( start, end+1 ): | ||
+ | print( i, end=" " ) | ||
+ | else: | ||
+ | for i in range( start, end-1, -1 ): | ||
+ | print( i, end=" " ) | ||
+ | print() | ||
+ | |||
+ | for i in range( 11 ): | ||
+ | print( "%s%s----%s%s" % ( i*'*', i*'..', i*'-', i*'??' ) ) | ||
+ | |||
+ | """ | ||
+ | # Nested For-Loops | ||
+ | for i in range(4): | ||
+ | for j in range( i+1 ): | ||
+ | print( "*", end="" ) | ||
+ | print() | ||
+ | |||
+ | print() | ||
+ | |||
+ | for i in range( 4-1, 0-1, -1): | ||
+ | for j in range( i+1 ): | ||
+ | print( "*", end="" ) | ||
+ | print() | ||
+ | |||
+ | print() | ||
+ | |||
+ | for i in range(4): | ||
+ | print( ' ' * (3-i), end="" ) | ||
+ | for j in range( i+1 ): | ||
+ | print( "*", end="" ) | ||
+ | print() | ||
+ | |||
+ | print() | ||
+ | |||
+ | for i in range(4-1, 0-1, -1): | ||
+ | print( ' ' * (3-i), end="" ) | ||
+ | for j in range( i+1 ): | ||
+ | print( "*", end="" ) | ||
+ | print() | ||
+ | |||
+ | print() | ||
+ | |||
+ | count = 1 | ||
+ | for i in range(4-1, 0-1, -1): | ||
+ | print( ' ' * (3-i), end="" ) | ||
+ | for j in range( i+1 ): | ||
+ | print( count, end="" ) | ||
+ | count = count + 1 | ||
+ | print() | ||
+ | |||
+ | print() | ||
+ | |||
+ | |||
+ | # JES Program | ||
+ | # JES program to take a sound file and play with it | ||
+ | # D. Thiebaut | ||
+ | # | ||
+ | |||
+ | file = pickAFile() | ||
+ | sound = makeSound( file ) | ||
+ | blockingPlay( sound ) | ||
+ | |||
+ | # ======================================================= | ||
+ | # clear waveform after "Remember" | ||
+ | # get start index for clearing | ||
+ | startIndex = 13393 # index just before "the force..." | ||
+ | |||
+ | # get the number of samples in the sound file | ||
+ | noSamples = getLength( sound ) | ||
+ | |||
+ | # clear all the samples from startIndex to end: | ||
+ | for i in range( startIndex, noSamples ): | ||
+ | setSampleValueAt( sound, i, 0 ) | ||
+ | |||
+ | # play sound again | ||
+ | #blockingPlay( sound ) | ||
+ | |||
+ | # ======================================================= | ||
+ | # Copy "remember" to the end of itself in the waveform | ||
+ | rememberLength = startIndex # that's the length of the word "remember" | ||
+ | for i in range( 0, startIndex ): | ||
+ | value = getSampleValueAt( sound, i ) | ||
+ | setSampleValueAt( sound, i+rememberLength, value ) | ||
+ | |||
+ | # play sound: "remember, remember" | ||
+ | blockingPlay( sound ) | ||
+ | |||
+ | # get the original sound again | ||
+ | sound = makeSound( file ) | ||
+ | blockingPlay( sound ) | ||
+ | |||
+ | # ======================================================= | ||
+ | # copy Always right after Remember | ||
+ | startAlways = 30444 # index just before "Always" | ||
+ | endRemember = 8968 | ||
+ | |||
+ | # set j to the end of Remember | ||
+ | j = endRemember | ||
+ | for i in range( startAlways, noSamples ): | ||
+ | # copy from Always | ||
+ | value = getSampleValueAt( sound, i ) | ||
+ | # into waveform after Remember | ||
+ | setSampleValueAt( sound, j, value ) | ||
+ | # advance j by 1 | ||
+ | j = j+1 | ||
+ | |||
+ | # now j points to the end of the moved "Always" | ||
+ | endRememberAlways = j | ||
+ | |||
+ | # clear from the end of RememberAlways to the end of the waveform | ||
+ | for i in range( endRememberAlways, noSamples ): | ||
+ | setSampleValueAt( sound, i, 0 ) | ||
+ | |||
+ | blockingPlay( sound ) | ||
+ | |||
+ | """ | ||
+ | # ======================================================= | ||
+ | # create an echo | ||
+ | |||
+ | startIndex = 13393 # index just before "the force..." | ||
+ | noSamples = getLength( sound ) | ||
+ | |||
+ | # clear all the samples from startIndex to end: | ||
+ | for i in range( startIndex, noSamples ): | ||
+ | setSampleValueAt( sound, i, 0 ) | ||
+ | |||
+ | # overlap remember on top of itself, starting at Index 6000 | ||
+ | # which is roughly half the length of the word | ||
+ | endOfRemember = 13393 | ||
+ | offset = 6000 | ||
+ | for i in range( endOfRemember, 0, -1 ): | ||
+ | sourceValue = getSampleValueAt( sound, i) | ||
+ | destValue = getSampleValueAt( sound, i+offset ) | ||
+ | setSampleValueAt( sound, i+offset, sourceValue//3 + destValue ) | ||
+ | |||
+ | blockingPlay( sound ) | ||
+ | """ | ||
+ | |||
+ | |||
+ | # ======================================================= | ||
+ | # reverse the whole waveform | ||
+ | file = pickAFile() | ||
+ | sound = makeSound( file ) | ||
+ | blockingPlay( sound ) | ||
+ | |||
+ | # make j the index of the last sample in the sound | ||
+ | j = getLength(sound)-1 | ||
+ | |||
+ | # make i go from beginning of sound to half way. | ||
+ | for i in range( getLength( sound ) // 2 ): | ||
+ | # get the two samples at Index i and at Index j | ||
+ | valueAti = getSampleValueAt( sound, i ) | ||
+ | valueAtj = getSampleValueAt( sound, j ) | ||
+ | |||
+ | # swap them | ||
+ | temp = valueAti | ||
+ | valueAti = valueAtj | ||
+ | valueAtj = temp | ||
+ | |||
+ | # put the swapped versions back in sound | ||
+ | setSampleValueAt( sound, i, valueAti ) | ||
+ | setSampleValueAt( sound, j, valueAtj ) | ||
+ | |||
+ | # move j to the left by 1. The for loop moves i to the right | ||
+ | j = j-1 | ||
+ | |||
+ | blockingPlay( sound ) | ||
+ | </source> | ||
+ | |||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | [[Category:CSC111]][[Category:Labs]][[Category:Python]] |
Latest revision as of 16:54, 28 February 2014
--D. Thiebaut (talk) 18:16, 25 February 2014 (EST)
This lab presents JES as a practical way of manipulating sound files. This requires only single for-loops. The remaining part of the lab contains many small exercises dealing with for-loop with the intent of mastering the use of single for loops in many different situations.
Contents
Single for-loops
- Create a new program called lab5.py
# lab5.py for i in range( 3, 8 ): print( i )
- Verify that you get the correct output:
python3 lab5.py 3 4 5 6 7
Challenge Block 1 |
- Now, your turn!
- List of numbers, Version 2
- Modify your loop so that it does not use the range( ) function (Hint: you have to list all the values)
- List of even numbers
- write a loop that prints all the even numbers between 4 and 20, 4, and 20 included (you can use range or list all the numbers).
- List of odd numbers
- write a loop that prints all the odd numbers between -3 and 19, -3, and 19 included.
- User-controlled loops (more difficult)
- Write a new Python program that prints a series of numbers, after having asked the user where the series should start, and where it should end.
- Here is an example of how it should run (the user input is underlined):
python3 userLoop.py I will print a list of numbers for you. Where should I start? 3 What is the last number of the series? 10 3 4 5 6 7 8 9 10
- Go ahead and write it. What happens if you ask the program to count from -5 to 5? Does it work correctly?
- Does your program work if you ask your program to go from 1 to 1?
- Can you predict what will be printed if you ask your program to count from 10 to 1?
Challenge 2 |
- Make the last program you wrote print the series numbers between the two numbers entered by the user, wether the first one is less than the second one, or vice versa.
For example, here's an example of how the program could work:
Where should I start? 3 What is the last number of the series? 10 3 4 5 6 7 8 9 10
- and if the user enters a larger number for the first number, it still prints the numbers in between:
Where should I start? 7 What is the last number of the series? 2 7 6 5 4 3 2
Challenge 3 |
Write a program that prints the pattern shown below. Do not start right away! Instead read the directions, please!
>>> ================================ RESTART ================================
>>>
----
*..-----??
**....------????
***......-------??????
****........--------????????
*****..........---------??????????
******............----------????????????
*******..............-----------??????????????
********................------------????????????????
*********..................-------------??????????????????
**********....................--------------????????????????????
>>>
- Instead of starting to program, write down on a piece of paper the number of symbols on each line. For example,
- on the first line, zero stars, zero dots, four minuses, zero question marks.
- on the 2nd line, two dots, two question marks.
- keep on writing how many characters appear on each line.
- then write a program with a loop that will print just the number of stars on each line.
JES
Download JES
- Download JES 4-3 to your computer from https://code.google.com/p/mediacomp-jes/downloads/list.
- If you are running Windows, pick jes-4-3.exe. Once downloaded, click on the exe file to start JES. You cannot install JES on one of the Lab computers running Windows. You have to boot them as Mac machines to install it.
- If you are running Mac OS X, pick jes-4-3-mac.zip, click on the downloaded zip file. Then click on the extracted file to start JES.
Download a Sound File
- Download the following file to your computer:
Writing Your First JES Program
- Note, you can call your program lab5b.py if you have used lab5.py for the first part of this lab.
- Open JES
- Type the following program in the top window:
file = pickAFile() sound = makeSound( file ) blockingPlay( sound )
- click on "Load Program" and save the program in the folder of your choice (a good place would be where you saved the Force.wav file).
- When prompted to enter a file in the Pick A File window, navigate through your folders and pick force.wav or Force.wav, which ever way you named it.
- Make sure the speakers are on so that you can hear your computer play the file. Don't worry about making sounds in this lab: this is what this lab is about!
Visualizing the Waveform of the Sound File
- Once you have played a sound in JES you can access its waveform using the Sound Tool of the MediaTools menu at the top of the window (or the screen).
- Open the Sound Tool. This is what you should see:
- Move the cursor around the waveform and click on different buttons (Play before, Play after, Play selection, etc.)
Remember that if you are having trouble writing a for-loop to work on the samples, it is easier to solve a much simpler program in Idle with Python with an array of just a few numbers. So do not hesitate to use Idle to generate first solutions before you implement them in JES!
Clearing Part Of The Waveform
- Position the cursor in the waveform as shown in the image above, just before the words "the force" are uttered by Sir Alec Guinness. Note the index of the sample where the cursor and assign it to a variable in your JES program, as shown below. Just replace the ... with the actual number
file = pickAFile() sound = makeSound( file ) blockingPlay( sound ) # get start index for clearing startIndex = ... # index just before "the force..."
- Now that you have the beginning index of the phrase "the force will be with you, always", you can clear it by setting all the samples to 0, as follows:
# clear all the samples from startIndex to end: noSamples = getLength( sound ) for i in range( startIndex, noSamples ): setSampleValueAt( sound, i, 0 ) # play sound again blockingPlay( sound )
- Add this new code to the end of your program and run it. It should just play "Remember" and nothing else. Look at the new waveform of your sound with the Sound Tool (close it first to get rid of the original waveform and reopen it).
Copying Parts of the Waveform
- The goal of this part is to copy the samples corresponding to "Remember" so that the waveform becomes "Remember Remember".
- You need two functions to perform this operation:
value = getSampleValueAt( sound, i )
- which gets the sample at Index i and stores it in the variable value, and
setSampleValueAt( sound, i, value )
- which sets the sample at Index i to value.
Challenge #6 |
Add a for loop that copies all the samples of "remember" and duplicates them in the waveform, so that when you play it you hear two "remember" words.
Challenge #7 |
Modify your program so that it transforms the waveform in such a way that when you play it at then end of the transformation it will play "Remember, always!"
Challenge #8 |
Modify the last waveform ("Remember always") and reverse it so that it plays "backwards" when you play it. You have two ways of performing it. One simpler than the other one.
- Simpler method: Assume the following numbers represent the samples of the waveform:
17 18 17 16 11 0 0 0 0 0 0 0 0 0
- then reversing it would yield:
0 0 0 0 0 0 0 0 0 11 16 17 18 17
- The more elegant method (feel free to attempt it) would yield the reversed numbers in the following way:
11 16 17 18 17 0 0 0 0 0 0 0 0 0
Challenge #9 (Optional) |
Modify your program so that it transforms the waveform in such a way that when you play it at then end of the transformation it will play "Remember" with an echo! (Remember, member, mber, ber...).
Be sure to make me listen to this new waveform before you move on to the next part!
Submission
Copy/paste your JES program into Idle and save the file as lab5.py. Submit it to this URL: http://cs.smith.edu/~dthiebaut/111b/submitL5.php
Solutions
# lab5 solution programs (loops)
# D. Thiebaut
# single For-Loops
"""
for i in range( 3, 8 ):
print( i, end=" ")
print()
for i in [3, 4, 5, 6, 7]:
print( i, end=" " )
print()
for i in range( 4, 20+1, 2 ):
print( i, end=" " )
print()
for i in range( -3, 19+1, 2 ):
print( i, end=" " )
print()
start = int( input( "start where? " ) )
end = int( input( "end where? " ) )
if start <= end:
for i in range( start, end+1 ):
print( i, end=" " )
else:
for i in range( start, end-1, -1 ):
print( i, end=" " )
print()
for i in range( 11 ):
print( "%s%s----%s%s" % ( i*'*', i*'..', i*'-', i*'??' ) )
"""
# Nested For-Loops
for i in range(4):
for j in range( i+1 ):
print( "*", end="" )
print()
print()
for i in range( 4-1, 0-1, -1):
for j in range( i+1 ):
print( "*", end="" )
print()
print()
for i in range(4):
print( ' ' * (3-i), end="" )
for j in range( i+1 ):
print( "*", end="" )
print()
print()
for i in range(4-1, 0-1, -1):
print( ' ' * (3-i), end="" )
for j in range( i+1 ):
print( "*", end="" )
print()
print()
count = 1
for i in range(4-1, 0-1, -1):
print( ' ' * (3-i), end="" )
for j in range( i+1 ):
print( count, end="" )
count = count + 1
print()
print()
# JES Program
# JES program to take a sound file and play with it
# D. Thiebaut
#
file = pickAFile()
sound = makeSound( file )
blockingPlay( sound )
# =======================================================
# clear waveform after "Remember"
# get start index for clearing
startIndex = 13393 # index just before "the force..."
# get the number of samples in the sound file
noSamples = getLength( sound )
# clear all the samples from startIndex to end:
for i in range( startIndex, noSamples ):
setSampleValueAt( sound, i, 0 )
# play sound again
#blockingPlay( sound )
# =======================================================
# Copy "remember" to the end of itself in the waveform
rememberLength = startIndex # that's the length of the word "remember"
for i in range( 0, startIndex ):
value = getSampleValueAt( sound, i )
setSampleValueAt( sound, i+rememberLength, value )
# play sound: "remember, remember"
blockingPlay( sound )
# get the original sound again
sound = makeSound( file )
blockingPlay( sound )
# =======================================================
# copy Always right after Remember
startAlways = 30444 # index just before "Always"
endRemember = 8968
# set j to the end of Remember
j = endRemember
for i in range( startAlways, noSamples ):
# copy from Always
value = getSampleValueAt( sound, i )
# into waveform after Remember
setSampleValueAt( sound, j, value )
# advance j by 1
j = j+1
# now j points to the end of the moved "Always"
endRememberAlways = j
# clear from the end of RememberAlways to the end of the waveform
for i in range( endRememberAlways, noSamples ):
setSampleValueAt( sound, i, 0 )
blockingPlay( sound )
"""
# =======================================================
# create an echo
startIndex = 13393 # index just before "the force..."
noSamples = getLength( sound )
# clear all the samples from startIndex to end:
for i in range( startIndex, noSamples ):
setSampleValueAt( sound, i, 0 )
# overlap remember on top of itself, starting at Index 6000
# which is roughly half the length of the word
endOfRemember = 13393
offset = 6000
for i in range( endOfRemember, 0, -1 ):
sourceValue = getSampleValueAt( sound, i)
destValue = getSampleValueAt( sound, i+offset )
setSampleValueAt( sound, i+offset, sourceValue//3 + destValue )
blockingPlay( sound )
"""
# =======================================================
# reverse the whole waveform
file = pickAFile()
sound = makeSound( file )
blockingPlay( sound )
# make j the index of the last sample in the sound
j = getLength(sound)-1
# make i go from beginning of sound to half way.
for i in range( getLength( sound ) // 2 ):
# get the two samples at Index i and at Index j
valueAti = getSampleValueAt( sound, i )
valueAtj = getSampleValueAt( sound, j )
# swap them
temp = valueAti
valueAti = valueAtj
valueAtj = temp
# put the swapped versions back in sound
setSampleValueAt( sound, i, valueAti )
setSampleValueAt( sound, j, valueAtj )
# move j to the left by 1. The for loop moves i to the right
j = j-1
blockingPlay( sound )