|
| 1 | +<html> |
| 2 | + <head> |
| 3 | + <title>Assignment 2: Quest for the 🦄</title> |
| 4 | + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> |
| 5 | + </head> |
| 6 | + <body> |
| 7 | + <div class="container mt-4"> |
| 8 | + <h2>Problem Setup</h2> |
| 9 | + <p>For this phase of the assignment, you will use the Python requests library to retrieve segments of an audio file which we have hidden throughout the course website, then use NumPy to reconstruct the file. The contents of the audio file contain verbal directions to the next phase of your quest.</p> |
| 10 | + |
| 11 | + <b>The starter code is located here: <a href='https://www.stanfordpython.com/row-of-puzzles/audio/audio_startercode.py'>https://www.stanfordpython.com/row-of-puzzles/audio/audio_startercode.py</a></b> |
| 12 | + |
| 13 | + <p>We have represented the audio signal as an (1,366,000 x 2) matrix, which we will henceforth denote <code>M</code>. The element of <code>M</code> in row <code>i</code> and column <code>j</code> represents the output pitch at time <code>i</code> (where time is measured relative to sampling frequency at the time the audio is played) along channel <code>j</code> (our signal only has a left channel and a right channel, hence two columns).</p> |
| 14 | + |
| 15 | + <p>We have divided <code>M</code> up into 100 components, each an (13,660 x 2) matrix (where rows 1-13,660 of <code>M</code> make up the first component, 13,661-27,320 make up the second component, etc.). We have then encoded each matrix as comma-delimited plaintext and placing it at a specified URL on the course website.</p> |
| 16 | + |
| 17 | + <p>To orient yourself to the problem, use your browser to navigate to <a href='https://www.stanfordpython.com/row-of-puzzles/audio/audio_start.json'>https://www.stanfordpython.com/row-of-puzzles/audio/audio_start.json</a>. You should be greeted by a JSON file of the following format: |
| 18 | + </p> |
| 19 | + <pre><code> |
| 20 | + { |
| 21 | + "matrix": "RMJWW5KqXAIVKd7AxMGtuUmRV.txt", "next": "s5X9Qi6aBbL9C618tIAtepbGz.json" |
| 22 | + } |
| 23 | + </code></pre> |
| 24 | + |
| 25 | + <p>The "matrix" parameter gives you a filename hosted on the Stanford Python website: navigating to <a href='https://stanfordpython.com/row-of-puzzles/audio/RMJWW5KqXAIVKd7AxMGtuUmRV.txt'>https://stanfordpython.com/row-of-puzzles/audio/RMJWW5KqXAIVKd7AxMGtuUmRV.txt</a> presents us with a text file representation of the first component of the matrix.</p> |
| 26 | + |
| 27 | + <p>The "next" parameter gives you the JSON file which refers to the second component of the matrix: here, we see that it is located at <a href='https://stanfordpython.com/row-of-puzzles/audio/s5X9Qi6aBbL9C618tIAtepbGz.json'>https://stanfordpython.com/row-of-puzzles/audio/s5X9Qi6aBbL9C618tIAtepbGz.json</a>.</p> |
| 28 | + |
| 29 | + <p>Below, we will walk you through the function definitions provided in the starter code so that you may write a Python script to retrieve the audio signal from the course website.</p> |
| 30 | + |
| 31 | + <h2>Solution Guidance</h2> |
| 32 | + <p>We would recommend reading the below, then perusing the starter code - more detail about the functions to implement are located in function-level comments in the starter code.</p> |
| 33 | + <h5><code>get_url_data(url)</code></h5> |
| 34 | + <p>We recommend first implementing the <code>get_url_data</code> function in </requests_audio.py</, because we will be using this function to extract unformation from each .json file we visit on the Python site.</p> |
| 35 | + |
| 36 | + <p>This function takes in a url (which, for our purposes, we assume points to a JSON file), then uses the <code>requests</code> library to extract the content from the url and convert the contents of the extracted JSON to a Python dictionary.</p> |
| 37 | + |
| 38 | + <p>Don't overthink this one! The <code>requests</code> library enables the functionality that you're looking for in a nice elegant manner. There is a valid implementation of this function which is one line long. 😊</p> |
| 39 | + |
| 40 | + <h5><code>obtain_matrix(textfile_url)</code></h5> |
| 41 | + <p>We've just dealt with parsing information from an online JSON file, so the next step is to write a function to parse data from an online <code>numpy</code> matrix. Since your sneaky course staff originally stored each </numpy</ matrix as a text flie by calling </np.savetxt</, you're going to need to use the </np.genfromtxt</ function in order to rehydrate the matrix.</p> |
| 42 | + |
| 43 | + <p>The <code>np.genfromtxt</code> function accepts <code>BytesIO</code> data from which it can rehydrate the matrix. Your task, then, is to obtain the content of a web request to the URL, cast it as <code>BytesIO</code> data (which, assuming the content is named <code>data</code>, can be done as <code>BytesIO(data)</code>, and then pass the bytes data into <code>np.genfromtxt</code> to rehydrate the matrix.</p> |
| 44 | + |
| 45 | + <p>Important note - the course staff has comma-delimited their original matrix, so make sure to appropriately incorporate the <code>delimeter</code> argument into your </np.genfromtxt</ call!</p> |
| 46 | + |
| 47 | + <h5><code>parse_site()</code></h5> |
| 48 | + <p>Now is where we put everything together - exciting!</p> |
| 49 | + |
| 50 | + <p>We're going to start by examining the JSON file at <a href='https://www.stanfordpython.com/row-of-puzzles/audio/audio_start.json'>https://www.stanfordpython.com/row-of-puzzles/audio/audio_start.json</a>. Then, loop over the chain of JSONs stored on the course site, and within each loop, perform the following:</p> |
| 51 | + |
| 52 | + <ul> |
| 53 | + <li>Access the data stored within the current JSON</li> |
| 54 | + <li>Access the matrix component referenced by the current JSON, and append it, row-wise, to the prior component(s) to construct the complete audio matrix.</li> |
| 55 | + |
| 56 | + </ul> |
| 57 | + |
| 58 | + <p>Once you've finished constructing the full audio matrix (sanity check: you should have a 1,366,000 x 2 matrix!), return it as a NumPy object from <code>parse_site()</code>. If you then run the command, </code>$ python3 requests_audio.py</code>, the code will then parse the site, construct the audio matrix, and save it as </out.wav</ (it will be saved in the same directory as the starter code on your machine), which you can then play out loud! The audio should be clearly intelligible and will contain your next clue on the path to the unicorn.</p> |
| 59 | + |
| 60 | + <h2>Conclusion</h2> |
| 61 | + |
| 62 | + <p>Good luck! Remember - if you're stuck with anything, we're only a Piazza post away. 😊</p> |
| 63 | + </div> |
| 64 | + </body> |
| 65 | +</html> |
0 commit comments