# Lab 4 - Lists
<p class="part" data-startline="7" data-endline="7" data-position="70" data-size="0"><span data-position="70" data-size="189">In this lab, you’ll be using everything you’ve learned about tables (and some of what you’ve learned about lists) to create a data visualization tool. Specifically, you’ll use a dataset of </span><strong data-position="259" data-size="0"><span data-position="261" data-size="35">active Providence business licenses</span></strong><span data-position="298" data-size="69"> published by the Rhode Island government to mark locations on a map.</span></p><h2 class="part" data-startline="9" data-endline="9" id="Learning-Objective" data-id="Learning-Objective"><a class="anchor hidden-xs" href="#Learning-Objective" title="Learning-Objective" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="372" data-size="18">Learning Objective</span></h2><p class="part" data-startline="11" data-endline="11" data-position="392" data-size="0"><span data-position="392" data-size="289">A key goal of this lab is to give you practice breaking large problems into separate tasks, each of which gets handled with its own collection of functions, expressions, and operators. As you work on the problems, practice writing out the lists of tasks and using those to guide your work.</span></p><h2 class="part" data-startline="13" data-endline="13" id="Resources" data-id="Resources"><a class="anchor hidden-xs" href="#Resources" title="Resources" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="686" data-size="9">Resources</span></h2><p class="part" data-startline="14" data-endline="16" data-position="696" data-size="0"><a href="https://www.pyret.org/docs/latest/lists.html#%28part._lists_.List_shared._methods_filter%29" target="_blank" rel="noopener"><span data-position="697" data-size="24">Pyret List documentation</span><br>
</a></p><h2 class="part" data-startline="17" data-endline="17" id="Part-1-Warm-up-with-Lists" data-id="Part-1-Warm-up-with-Lists"><a class="anchor hidden-xs" href="#Part-1-Warm-up-with-Lists" title="Part-1-Warm-up-with-Lists" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="821" data-size="26">Part 1: Warm up with Lists</span></h2><p class="part" data-startline="19" data-endline="19" data-position="849" data-size="0"><span data-position="849" data-size="184">Before we get into maps, however, let’s practice writing functions with lists. We’re going to do a set of problems that involve processing emails. Your goal is to use a combination of </span><code data-position="1034" data-size="6">filter</code><span data-position="1041" data-size="2">, </span><code data-position="1044" data-size="3">map</code><span data-position="1048" data-size="2">, </span><code data-position="1051" data-size="8">distinct</code><span data-position="1060" data-size="2">, </span><code data-position="1063" data-size="6">length</code><span data-position="1070" data-size="6">, and </span><code data-position="1077" data-size="4">.get</code><span data-position="1082" data-size="34"> on lists to solve these problems.</span></p><p class="part" data-startline="21" data-endline="21" data-position="1118" data-size="0"><strong data-position="1118" data-size="0"><span data-position="1120" data-size="5">Task:</span></strong><span data-position="1127" data-size="76"> Define two lists of strings, one that has all valid email addresses (like “</span><a href="mailto:kathi@jpgacademy.org" target="_blank" rel="noopener"><span data-position="1203" data-size="15">kathi@jpgacademy.org</span></a><span data-position="1218" data-size="4">”, “</span><a href="mailto:ice@google.com" target="_blank" rel="noopener"><span data-position="1222" data-size="14">ice@google.com</span></a><span data-position="1236" data-size="124">”, etc) and one that also has some invalid ones (missing @, anything after the username, etc). You’ll use these for testing.</span></p><p class="part" data-startline="23" data-endline="23" data-position="1362" data-size="0"><strong data-position="1362" data-size="0"><span data-position="1364" data-size="5">Task:</span></strong><span data-position="1371" data-size="91"> Write a function that takes a list of email addresses and counts the number that are from </span><code data-position="1463" data-size="4">.edu</code><span data-position="1468" data-size="34"> addresses (it’s okay to just use </span><code data-position="1503" data-size="15">string-contains</code><span data-position="1519" data-size="33"> here, rather than checking that </span><code data-position="1553" data-size="4">.edu</code><span data-position="1558" data-size="31"> is at the end of the address).</span></p><p class="part" data-startline="25" data-endline="25" data-position="1591" data-size="0"><strong data-position="1591" data-size="0"><span data-position="1593" data-size="5">Task:</span></strong><span data-position="1600" data-size="90"> Write a function that takes a list of emails and returns the ones that lack the “@” sign.</span></p><p class="part" data-startline="27" data-endline="27" data-position="1692" data-size="0"><strong data-position="1692" data-size="0"><span data-position="1694" data-size="5">Task:</span></strong><span data-position="1701" data-size="146"> Write a function that takes a list of email addresses and returns just a list of the usernames (dropping everything starting from the @. Look up </span><code data-position="1848" data-size="12">string-split</code><span data-position="1861" data-size="15">; there’s also </span><code data-position="1877" data-size="11">LIST.get(n)</code><span data-position="1889" data-size="55"> which gets the nth item from a list, starting from 0).</span></p><p class="part" data-startline="29" data-endline="29" data-position="1946" data-size="0"><span data-position="1946" data-size="93">If you have time (meaning you are less than 40 minutes into lab) also try the following task:</span></p><p class="part" data-startline="31" data-endline="31" data-position="2041" data-size="0"><strong data-position="2041" data-size="0"><span data-position="2043" data-size="5">Task:</span></strong><span data-position="2050" data-size="149"> Return a list of unique school names represented in a list of email addresses. The school names appear between the “@” and “.edu” in .edu addresses.</span></p><h2 class="part" data-startline="35" data-endline="35" id="Part-2-Making-a-Simple-Map" data-id="Part-2-Making-a-Simple-Map"><a class="anchor hidden-xs" href="#Part-2-Making-a-Simple-Map" title="Part-2-Making-a-Simple-Map" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="2206" data-size="27">Part 2: Making a Simple Map</span></h2><h3 class="part" data-startline="37" data-endline="37" id="Question-21-Loading-the-data" data-id="Question-21-Loading-the-data"><a class="anchor hidden-xs" href="#Question-21-Loading-the-data" title="Question-21-Loading-the-data" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="2239" data-size="30">Question 2.1: Loading the data</span></h3><p class="part" data-startline="38" data-endline="38" data-position="2270" data-size="0"><span data-position="2271" data-size="55">Before you start working with the data, take a look at </span><a href="https://docs.google.com/spreadsheets/d/18eKc_o-eZ8TWno6ePYkcMGKhx-Y2Fe8LEERqV5gClaU/edit#gid=1437433378" target="_blank" rel="noopener"><span data-position="2326" data-size="39">the Providence Business License dataset</span></a><span data-position="2471" data-size="241">. The first sheet (inside the file) is the original dataset, and the second sheet is a pruned version with only the columns you’ll need for this lab. Load the pruned sheet into Pyret by pasting the following code into the definitions window:</span></p><pre class="part" data-startline="40" data-endline="69" data-position="2714"><code class="include hljs">include shared<span class="hljs-operator">-</span>gdrive(<span class="hljs-string">"dcic-2021"</span>, <span class="hljs-string">"1wyQZj_L0qqV9Ekgr9au6RX2iqt2Ga8Ep"</span>)
include gdrive<span class="hljs-operator">-</span>sheets
<span class="hljs-keyword">import</span> <span class="hljs-title">data</span><span class="hljs-operator">-</span><span class="hljs-title">source</span> <span class="hljs-title"><span class="hljs-keyword">as</span></span> <span class="hljs-title">ds</span>
<span class="hljs-title">include</span> <span class="hljs-title">shared</span><span class="hljs-operator">-</span><span class="hljs-title">gdrive</span>(<span class="hljs-string">"stencil.arr"</span>, <span class="hljs-string">"1W61RYJDms4y-1tP_oQ9igydaYr-nmHCr"</span>)
<span class="hljs-title">include</span> <span class="hljs-title">image</span><span class="hljs-operator">-</span><span class="hljs-title">structs</span>
<span class="hljs-title"><span class="hljs-keyword">import</span></span> <span class="hljs-title">lists</span> <span class="hljs-title"><span class="hljs-keyword">as</span></span> <span class="hljs-title">L</span>
##############
# <span class="hljs-title">SETUP</span> <span class="hljs-title">CODE</span> #
##############
<span class="hljs-title">ssid</span> <span class="hljs-operator">=</span> <span class="hljs-string">"18eKc_o-eZ8TWno6ePYkcMGKhx-Y2Fe8LEERqV5gClaU"</span>
<span class="hljs-title">data</span><span class="hljs-operator">-</span><span class="hljs-title">sheet</span> <span class="hljs-operator">=</span> <span class="hljs-title">load</span><span class="hljs-operator">-</span><span class="hljs-title">spreadsheet</span>(<span class="hljs-title">ssid</span>)
<span class="hljs-title">pvd</span><span class="hljs-operator">-</span><span class="hljs-title">businesses</span> <span class="hljs-operator">=</span>
<span class="hljs-title">load</span><span class="hljs-operator">-</span><span class="hljs-title">table</span>: <span class="hljs-title">license</span><span class="hljs-operator">-</span><span class="hljs-title">id</span>, <span class="hljs-title">name</span>, <span class="hljs-title">extended</span><span class="hljs-operator">-</span><span class="hljs-title"><span class="hljs-literal">hours</span></span>, <span class="hljs-title">hotel</span>, <span class="hljs-title">parking</span>,
<span class="hljs-title">restaurant</span>, <span class="hljs-title">food</span><span class="hljs-operator">-</span><span class="hljs-title">and</span><span class="hljs-operator">-</span><span class="hljs-title">liquor</span>, <span class="hljs-title">food</span><span class="hljs-operator">-</span><span class="hljs-title">dispenser</span>, <span class="hljs-title">lat</span>, <span class="hljs-title">long</span>
<span class="hljs-title">source</span>: <span class="hljs-title">data</span><span class="hljs-operator">-</span><span class="hljs-title">sheet</span>.<span class="hljs-title">sheet</span><span class="hljs-operator">-</span><span class="hljs-title">by</span><span class="hljs-operator">-</span><span class="hljs-title">name</span>(<span class="hljs-string">"Licenses_Pruned"</span>, <span class="hljs-title"><span class="hljs-literal">true</span></span>)
<span class="hljs-title">sanitize</span> <span class="hljs-title">license</span><span class="hljs-operator">-</span><span class="hljs-title">id</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">string</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">name</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">string</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">extended</span><span class="hljs-operator">-</span><span class="hljs-title"><span class="hljs-literal">hours</span></span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">bool</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">hotel</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">bool</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">parking</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">bool</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">restaurant</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">bool</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">food</span><span class="hljs-operator">-</span><span class="hljs-title">and</span><span class="hljs-operator">-</span><span class="hljs-title">liquor</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">bool</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">food</span><span class="hljs-operator">-</span><span class="hljs-title">dispenser</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title"><span class="hljs-keyword">bool</span></span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">lat</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title">num</span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">sanitize</span> <span class="hljs-title">long</span> <span class="hljs-title"><span class="hljs-keyword">using</span></span> <span class="hljs-title">ds</span>.<span class="hljs-title">num</span><span class="hljs-operator">-</span><span class="hljs-title">sanitizer</span>
<span class="hljs-title">end</span>
</code></pre><h3 class="part" data-startline="71" data-endline="71" id="Question-22-Generate-a-Map" data-id="Question-22-Generate-a-Map"><a class="anchor hidden-xs" href="#Question-22-Generate-a-Map" title="Question-22-Generate-a-Map" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="3789" data-size="28">Question 2.2: Generate a Map</span></h3><p class="part" data-startline="72" data-endline="72" data-position="3818" data-size="0"><span data-position="3818" data-size="37">We have provided you with a function </span><code data-position="3856" data-size="33">table-to-map(t :: Table) -> Image</code><span data-position="3890" data-size="87">, which takes in a table and plots rows as dots on a map of Providence, based on their </span><code data-position="3978" data-size="3">"x"</code><span data-position="3982" data-size="2">, </span><code data-position="3985" data-size="3">"y"</code><span data-position="3989" data-size="6">, and </span><code data-position="3996" data-size="7">"color"</code><span data-position="4004" data-size="10"> columns. </span><strong data-position="4014" data-size="0"><span data-position="4016" data-size="6">Treat </span><code data-position="4023" data-size="12">table-to-map</code><span data-position="4036" data-size="25"> like a built-in function</span></strong><span data-position="4063" data-size="39">; you can call it just like you called </span><code data-position="4103" data-size="9">filter-by</code><span data-position="4113" data-size="49"> or any other built-in function in previous labs.</span></p><p class="part" data-startline="74" data-endline="74" data-position="4164" data-size="0"><span data-position="4164" data-size="7">To use </span><code data-position="4172" data-size="12">table-to-map</code><span data-position="4185" data-size="50"> to map the locations of the businesses listed in </span><code data-position="4236" data-size="14">pvd-businesses</code><span data-position="4251" data-size="186">, you will need to convert the longitude and latitude values in the table to x- and y-coordinate values. Only locations that fit within the bounds of the Providence map can be included (</span><code data-position="4438" data-size="12">table-to-map</code><span data-position="4451" data-size="89"> will account for this automatically). We’ve defined the following values for you in the </span><code data-position="4541" data-size="11">stencil.arr</code><span data-position="4553" data-size="35"> file that the setup code includes:</span></p><ul class="part" data-startline="76" data-endline="83">
<li class="" data-startline="76" data-endline="76" data-position="4592" data-size="0"><code data-position="4593" data-size="7">LAT-MIN</code><span data-position="4601" data-size="41"> - the minimum latitude that fits the map</span></li>
<li class="" data-startline="77" data-endline="77" data-position="4645" data-size="0"><code data-position="4646" data-size="7">LAT-MAX</code><span data-position="4654" data-size="41"> - the maximum latitude that fits the map</span></li>
<li class="" data-startline="78" data-endline="78" data-position="4698" data-size="0"><code data-position="4699" data-size="7">LON-MIN</code><span data-position="4707" data-size="42"> - the minimum longitude that fits the map</span></li>
<li class="" data-startline="79" data-endline="79" data-position="4752" data-size="0"><code data-position="4753" data-size="7">LON-MAX</code><span data-position="4761" data-size="42"> - the maximum longitude that fits the map</span></li>
<li class="" data-startline="80" data-endline="80" data-position="4806" data-size="0"><code data-position="4807" data-size="6">HEIGHT</code><span data-position="4814" data-size="24"> - the height of the map</span></li>
<li class="" data-startline="81" data-endline="83" data-position="4841" data-size="0"><code data-position="4842" data-size="5">WIDTH</code><span data-position="4848" data-size="23"> - the width of the map</span></li>
</ul><div class="alert alert-info part" data-startline="84" data-endline="85" data-position="4874" data-size="161">
<p data-position="4882" data-size="0"><span data-position="4882" data-size="11">Try typing </span><code data-position="4894" data-size="7">LAT-MIN</code><span data-position="4902" data-size="129"> or any of these values in the interactions window, you should see they are predefined values that you can use in your functions.</span></p>
</div><p class="part" data-startline="88" data-endline="88" data-position="5037" data-size="0"><span data-position="5037" data-size="41">Use these values to write functions that </span><strong data-position="5078" data-size="0"><span data-position="5080" data-size="5">scale</span></strong><span data-position="5087" data-size="14"> latitudes to </span><code data-position="5102" data-size="1">y</code><span data-position="5104" data-size="26"> values and longitudes to </span><code data-position="5131" data-size="1">x</code><span data-position="5133" data-size="8"> values </span><strong data-position="5141" data-size="0"><span data-position="5143" data-size="30">relative to the map dimensions</span></strong><span data-position="5175" data-size="49">. You must proportionally scale the businesses’ (</span><code data-position="5225" data-size="4">long</code><span data-position="5230" data-size="2">, </span><code data-position="5233" data-size="3">lat</code><span data-position="5237" data-size="18">) coordinates to (</span><code data-position="5256" data-size="1">x</code><span data-position="5258" data-size="2">, </span><code data-position="5261" data-size="1">y</code><span data-position="5263" data-size="54">) coordinates in order for the rows to be read by the </span><code data-position="5318" data-size="12">table-to-map</code><span data-position="5331" data-size="20"> function correctly.</span></p><p class="part" data-startline="90" data-endline="90" data-position="5354" data-size="0"><span data-position="5354" data-size="63">To make things easier for you, we’ve included scaling formulas!</span></p><p class="part" data-startline="92" data-endline="92" data-position="5419" data-size="0"><img src="https://i.imgur.com/or0UFi2.png" alt="" class="" data-position="5419" data-size="36" loading="lazy"></p><p class="part" data-startline="95" data-endline="95" data-position="5458" data-size="0"><strong data-position="5458" data-size="0"><span data-position="5460" data-size="5">TASK:</span></strong><span data-position="5467" data-size="50"> Use these scaling functions to add columns named </span><code data-position="5518" data-size="1">x</code><span data-position="5520" data-size="5"> and </span><code data-position="5526" data-size="1">y</code><span data-position="5528" data-size="8"> to the </span><code data-position="5537" data-size="14">pvd-businesses</code><span data-position="5552" data-size="32"> table with these scaled values.</span></p><p class="part" data-startline="97" data-endline="97" data-position="5587" data-size="0"><strong data-position="5587" data-size="0"><span data-position="5589" data-size="5">TASK:</span></strong><span data-position="5596" data-size="22"> Add a column labeled </span><code data-position="5619" data-size="5">color</code><span data-position="5625" data-size="117"> and set each row’s color to “black.” After adding these columns, the computed table can then be used as an input to </span><code data-position="5743" data-size="12">table-to-map</code><span data-position="5756" data-size="1">.</span></p><p class="part" data-startline="99" data-endline="99" data-position="5760" data-size="0"><strong data-position="5760" data-size="0"><span data-position="5762" data-size="5">HINT:</span></strong><span data-position="5769" data-size="121"> Think about whether the output for this column is dependent on each specific row. How can we generate this column using </span><code data-position="5891" data-size="12">build-column</code><span data-position="5904" data-size="1">?</span></p><p class="part" data-startline="101" data-endline="101" data-position="5907" data-size="0"><span data-position="5907" data-size="55">Complete the tasks and pass the transformed table into </span><code data-position="5963" data-size="12">table-to-map</code><span data-position="5976" data-size="45">. The output should look something like this:</span></p><p class="part" data-startline="103" data-endline="103" data-position="6023" data-size="0"><img src="https://i.imgur.com/6rfakrA.jpg" alt="" class="" data-position="6023" data-size="36" loading="lazy"></p><hr><h3 class="part" data-startline="107" data-endline="107" id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point" data-id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point"><a class="anchor hidden-xs" href="#CHECKPOINT-Call-over-a-TA-once-you-reach-this-point" title="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point" smoothhashscroll=""><span class="octicon octicon-link"></span></a><em data-position="6070" data-size="0"><span data-position="6071" data-size="11">CHECKPOINT:</span></em><span data-position="6083" data-size="42"> Call over the teacher once you reach this point.</span></h3><hr><h2 class="part" data-startline="110" data-endline="110" id="Part-3-Analyzing-the-Data" data-id="Part-3-Analyzing-the-Data"><a class="anchor hidden-xs" href="#Part-3-Analyzing-the-Data" title="Part-3-Analyzing-the-Data" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="6134" data-size="26">Part 3: Analyzing the Data</span></h2><p class="part" data-startline="112" data-endline="112" data-position="6162" data-size="0"><span data-position="6162" data-size="254">Now that you have a map of Providence (albeit not a very pretty one), we need to put it to good use. Your friend Sofia has taken you up on your invitation to visit and has just arrived in Providence. She wants to know what she should do while she’s here!</span></p><h3 class="part" data-startline="114" data-endline="114" id="Question-31-Generate-a-tourist-map" data-id="Question-31-Generate-a-tourist-map"><a class="anchor hidden-xs" href="#Question-31-Generate-a-tourist-map" title="Question-31-Generate-a-tourist-map" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="6422" data-size="36">Question 3.1: Generate a tourist map</span></h3><p class="part" data-startline="116" data-endline="117" data-position="6460" data-size="0"><span data-position="6460" data-size="17">Write a function </span><code data-position="6478" data-size="142">generate-tourist-map(needs-hotel :: Boolean, has-car :: Boolean, stays-up-late :: Boolean, eats-out :: Boolean, businesses :: Table) -> Image</code><span data-position="6621" data-size="53"> that takes in a series of Booleans and the original </span><code data-position="6675" data-size="14">pvd-businesses</code><span data-position="6690" data-size="79"> table and returns a map marked with the places that Sofia might want to visit.</span></p><ul class="part" data-startline="119" data-endline="123">
<li class="" data-startline="119" data-endline="119" data-position="6773" data-size="0"><code data-position="6774" data-size="11">needs-hotel</code><span data-position="6786" data-size="21">: If this Boolean is </span><code data-position="6808" data-size="4">true</code><span data-position="6813" data-size="94">, Sofia needs a hotel to stay at! Mark all of the inns on the map with a color of your choice.</span></li>
<li class="" data-startline="120" data-endline="120" data-position="6911" data-size="0"><code data-position="6912" data-size="7">has-car</code><span data-position="6920" data-size="5">: If </span><code data-position="6926" data-size="4">true</code><span data-position="6931" data-size="121">, Sofia has decided to drive and will need to find places with parking. Mark all places with parking with a second color.</span></li>
<li class="" data-startline="121" data-endline="121" data-position="7055" data-size="0"><code data-position="7056" data-size="13">stays-up-late</code><span data-position="7070" data-size="5">: If </span><code data-position="7076" data-size="4">true</code><span data-position="7081" data-size="99">, Sofia is ready for a night out! Mark all places with extended hours (Look at the column entitled </span><code data-position="7181" data-size="14">extended-hours</code><span data-position="7196" data-size="21">) with a third color.</span></li>
<li class="" data-startline="122" data-endline="123" data-position="7220" data-size="0"><code data-position="7221" data-size="8">eats-out</code><span data-position="7230" data-size="5">: If </span><code data-position="7236" data-size="4">true</code><span data-position="7241" data-size="104">, Sofia has given up on cooking for herself and wants to eat out. Mark all eateries with a fourth color.</span></li>
</ul><div class="alert alert-info part" data-startline="124" data-endline="125" data-position="7347" data-size="153">
<p data-position="7355" data-size="0"><span data-position="7355" data-size="19">Remember that your </span><code data-position="7375" data-size="20">generate-tourist-map</code><span data-position="7396" data-size="29"> function should take in the </span><strong data-position="7425" data-size="0"><span data-position="7427" data-size="8">original</span></strong><span data-position="7437" data-size="59"> pvd-businesses table, not the modified one made in Part 1.</span></p>
</div><p class="part" data-startline="128" data-endline="128" data-position="7502" data-size="0"><span data-position="7502" data-size="54">If a place has more than one relevant characteristic, </span><strong data-position="7556" data-size="0"><span data-position="7558" data-size="74">it should be colored according to the characteristic that’s most important</span></strong><span data-position="7634" data-size="228"> to Sofia. Any non-relevant places should be colored black. Starting with the most important characteristic, Sofia cares first about hotels, then eating out, then places that have parking, and lastly, places that stay open late.</span></p><p class="part" data-startline="130" data-endline="130" data-position="7865" data-size="0"><em data-position="7865" data-size="0"><span data-position="7866" data-size="43">Depending on the values of the parameters (</span><code data-position="7910" data-size="11">needs-hotel</code><span data-position="7922" data-size="2">, </span><code data-position="7925" data-size="7">has-car</code><span data-position="7933" data-size="2">, </span><code data-position="7936" data-size="13">stays-up-late</code><span data-position="7950" data-size="2">, </span><code data-position="7953" data-size="8">eats-out</code><span data-position="7962" data-size="125">), the computed colors for places will be different. Think about how you can accomplish this behavior with a nested function.</span></em></p><p class="part" data-startline="132" data-endline="132" data-position="8090" data-size="0"><strong data-position="8090" data-size="0"><span data-position="8092" data-size="5">NOTE:</span></strong><span data-position="8100" data-size="46"> Look at the list of predefined colors in the </span><a href="https://www.pyret.org/docs/latest/image-structs.html#%28part._image-structs_.Color%29" target="_blank" rel="noopener"><span data-position="8146" data-size="19">Pyret Documentation</span></a><span data-position="8253" data-size="30"> to see what options you have.</span></p><hr><h3 class="part" data-startline="136" data-endline="136" id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point1" data-id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point"><a class="anchor hidden-xs" href="#CHECKPOINT-Call-over-a-TA-once-you-reach-this-point1" title="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point1" smoothhashscroll=""><span class="octicon octicon-link"></span></a><em data-position="8294" data-size="0"><span data-position="8295" data-size="11">CHECKPOINT:</span></em><span data-position="8307" data-size="42"> Call over the teacher once you reach this point.</span></h3><hr><h2 class="part" data-startline="139" data-endline="139" id="Part-4-Games-Games-Games" data-id="Part-4-Games-Games-Games"><a class="anchor hidden-xs" href="#Part-4-Games-Games-Games" title="Part-4-Games-Games-Games" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="8358" data-size="26">Part 4: Games Games Games!</span></h2><p class="part" data-startline="140" data-endline="140" data-position="8385" data-size="0"><span data-position="8385" data-size="311">It turns out that your game-enthusiast friend Sofia wants nothing more than to buy and play Monopoly. However, before she can buy Monopoly, Sofia would like a doughnut (everyone gets hungry!). Good thing Sofia is a big advocate for local businesses and wants to visit all the local doughnut shops in Providence!</span></p><p class="part" data-startline="142" data-endline="142" data-position="8698" data-size="0"><span data-position="8698" data-size="418">How do we distinguish local shops from those in national chains? One way is to find all the doughnut shops and see which ones have names that appear many times in the data—local shops will have fewer entries in the list. A frequency-bar chart would show us this answer visually, but what if we had to compute this information from a list of names of doughnut shops, rather than read it off of a frequency-bar-chart?</span></p><h3 class="part" data-startline="144" data-endline="144" id="Question-41" data-id="Question-41"><a class="anchor hidden-xs" href="#Question-41" title="Question-41" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="9122" data-size="12">Question 4.1</span></h3><p class="part" data-startline="146" data-endline="146" data-position="9136" data-size="0"><em data-position="9136" data-size="0"><strong data-position="9136" data-size="0"><span data-position="9139" data-size="5">TASK:</span></strong></em><span data-position="9147" data-size="83"> Write an expression that gets the list of all donut shops from the original table.</span></p><div class="alert alert-info part" data-startline="148" data-endline="149" data-position="9232" data-size="171">
<p data-position="9240" data-size="0"><span data-position="9240" data-size="159">Something to keep in mind: There are two spellings for the tasty dessert of interest: donut and doughnut. Be aware of this when you are looking for businesses.</span></p>
</div><p class="part" data-startline="152" data-endline="152" data-position="9405" data-size="0"><em data-position="9405" data-size="0"><strong data-position="9405" data-size="0"><span data-position="9408" data-size="5">TASK:</span></strong></em><span data-position="9416" data-size="143"> Based on inspecting the list of donut shops, determine which shops are local or a chain. We’ll consider a doughnut shop to be local if it has </span><strong data-position="9559" data-size="0"><span data-position="9561" data-size="24">no more than 2 locations</span></strong><span data-position="9587" data-size="8"> in the </span><code data-position="9596" data-size="14">pvd-businesses</code><span data-position="9611" data-size="7"> table.</span></p><p class="part" data-startline="154" data-endline="154" data-position="9620" data-size="0"><span data-position="9620" data-size="57">Filter out the chain donut shops to create a list called </span><code data-position="9678" data-size="10">donuts-lst</code><span data-position="9689" data-size="35"> of names of local doughnut shops.</span></p><p class="part" data-startline="157" data-endline="157" data-position="9728" data-size="0"><em data-position="9728" data-size="0"><span data-position="9729" data-size="79">Remember to write out your list of tasks first and use that to guide your work.</span></em></p><h3 class="part" data-startline="159" data-endline="159" id="Question-42" data-id="Question-42"><a class="anchor hidden-xs" href="#Question-42" title="Question-42" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="9815" data-size="12">Question 4.2</span></h3><p class="part" data-startline="160" data-endline="160" data-position="9828" data-size="0"><em data-position="9828" data-size="0"><strong data-position="9828" data-size="0"><span data-position="9831" data-size="5">TASK:</span></strong></em><span data-position="9839" data-size="21"> Filter the original </span><code data-position="9861" data-size="14">pvd-businesses</code><span data-position="9876" data-size="58"> table to only include donut shops (both local and chain).</span></p><p class="part" data-startline="163" data-endline="163" data-position="9937" data-size="0"><em data-position="9937" data-size="0"><strong data-position="9937" data-size="0"><span data-position="9940" data-size="5">TASK:</span></strong></em><span data-position="9948" data-size="67"> On this filtered table, add a color column where local stores are </span><strong data-position="10015" data-size="0"><span data-position="10017" data-size="3">red</span></strong><span data-position="10022" data-size="22"> and chain stores are </span><strong data-position="10044" data-size="0"><span data-position="10046" data-size="5">black</span></strong><span data-position="10053" data-size="1">.</span></p><p class="part" data-startline="165" data-endline="165" data-position="10056" data-size="0"><em data-position="10056" data-size="0"><strong data-position="10056" data-size="0"><span data-position="10059" data-size="5">TASK:</span></strong></em><span data-position="10067" data-size="11"> Using the </span><code data-position="10079" data-size="12">table-to-map</code><span data-position="10092" data-size="110"> function and your updated table, create a map that highlights all of the donut shops in their correct colors.</span></p><hr><h3 class="part" data-startline="170" data-endline="170" id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point2" data-id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point"><a class="anchor hidden-xs" href="#CHECKPOINT-Call-over-a-TA-once-you-reach-this-point2" title="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point2" smoothhashscroll=""><span class="octicon octicon-link"></span></a><em data-position="10214" data-size="0"><span data-position="10215" data-size="11">CHECKPOINT:</span></em><span data-position="10227" data-size="42"> Call over the teacher once you reach this point.</span></h3><hr><h2 class="part" data-startline="173" data-endline="173" id="Part-5-A-Different-Kind-of-Map" data-id="Part-5-A-Different-Kind-of-Map"><a class="anchor hidden-xs" href="#Part-5-A-Different-Kind-of-Map" title="Part-5-A-Different-Kind-of-Map" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="10278" data-size="31">Part 5: A Different Kind of Map</span></h2><p class="part" data-startline="175" data-endline="175" data-position="10312" data-size="0"><span data-position="10312" data-size="310">Now that Sofia got her doughnut, she is ready to purchase Monopoly. Unsatisfied with how few stores sell them in Providence, Sofia decides to open her own game store. After conducting a survey of existing options, she’s created a list of the most popular board games. With Monopoly, Sofia can finally have fun!</span></p><h3 class="part" data-startline="178" data-endline="178" id="Question-51" data-id="Question-51"><a class="anchor hidden-xs" href="#Question-51" title="Question-51" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="10629" data-size="12">Question 5.1</span></h3><p class="part" data-startline="179" data-endline="179" data-position="10642" data-size="0"><span data-position="10642" data-size="17">Write a function </span><code data-position="10660" data-size="57">create-token(token-colors :: List<String>) -> List<Image></code><span data-position="10718" data-size="198"> that takes in a list of strings representing valid colors and produces a list of game tokens of these colors. Each token should have this shape, but with its index-specific color and a yellow star:</span></p><p class="part" data-startline="181" data-endline="181" data-position="10918" data-size="0"><img src="https://i.imgur.com/fch3Dxl.png" alt="" class="" data-position="10918" data-size="36" loading="lazy"></p><p class="part" data-startline="184" data-endline="184" data-position="10957" data-size="0"><span data-position="10957" data-size="99">Each token should also have a randomly generated size, such that its radius is between 15-35 units.</span></p><p class="part" data-startline="186" data-endline="186" data-position="11058" data-size="0"><strong data-position="11058" data-size="0"><span data-position="11060" data-size="5">HINT:</span></strong><span data-position="11067" data-size="50"> Take a look at the List operations from part 3.1.</span></p><p class="part" data-startline="188" data-endline="188" data-position="11119" data-size="0"><em data-position="11119" data-size="0"><span data-position="11120" data-size="134">Discuss why you think lists are being used in this problem as opposed to tables. When would it be preferable to use tables over lists?</span></em></p><h3 class="part" data-startline="191" data-endline="191" id="Question-52" data-id="Question-52"><a class="anchor hidden-xs" href="#Question-52" title="Question-52" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="11262" data-size="12">Question 5.2</span></h3><p class="part" data-startline="192" data-endline="192" data-position="11275" data-size="0"><span data-position="11275" data-size="189">Sofia has discovered that the ideal token size has a radius within 20-30. She wants to discard all of the token images that are outside of that range and make display signs out of the rest.</span></p><p class="part" data-startline="195" data-endline="195" data-position="11467" data-size="0"><span data-position="11467" data-size="17">Write a function </span><code data-position="11485" data-size="64">generate-token-signs(token-images :: List<Image>) -> List<Image></code><span data-position="11550" data-size="36"> that takes in the output list from </span><code data-position="11587" data-size="12">create-token</code><span data-position="11600" data-size="184">. This function should remove all of the tokens that lie outside of the size range and put the remaining token on square backgrounds. This is what an output list item should look like:</span></p><p class="part" data-startline="197" data-endline="197" data-position="11786" data-size="0"><img src="https://i.imgur.com/tLx0v0H.png" alt="" class="" data-position="11786" data-size="36" loading="lazy"></p><p class="part" data-startline="200" data-endline="200" data-position="11825" data-size="0"><em data-position="11825" data-size="0"><strong data-position="11825" data-size="0"><span data-position="11828" data-size="5">HINT:</span></strong></em><span data-position="11836" data-size="13"> look at the </span><code data-position="11850" data-size="11">image-width</code><span data-position="11862" data-size="55"> function in the documentation when making the function</span></p><hr><h3 class="part" data-startline="204" data-endline="204" id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point3" data-id="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point"><a class="anchor hidden-xs" href="#CHECKPOINT-Call-over-a-TA-once-you-reach-this-point3" title="CHECKPOINT-Call-over-a-TA-once-you-reach-this-point3" smoothhashscroll=""><span class="octicon octicon-link"></span></a><em data-position="11928" data-size="0"><span data-position="11929" data-size="11">CHECKPOINT:</span></em><span data-position="11941" data-size="42"> Call over the teacher once you reach this point.</span></h3><hr><h2 class="part" data-startline="207" data-endline="207" id="Success" data-id="Success"><a class="anchor hidden-xs" href="#Success" title="Success" smoothhashscroll=""><span class="octicon octicon-link"></span></a><span data-position="11992" data-size="8">Success!</span></h2><p class="part" data-startline="209" data-endline="209" data-position="12002" data-size="0"><span data-position="12002" data-size="172">Sofia finally bought her new token! Hooray! As a gift, she has provided you with a $5 gift card for her game store! Business at Sofia’s store is booming, all thanks to you.</span></p><hr><blockquote class="part" data-startline="214" data-endline="215">
<p data-position="12187" data-size="0"></p>
</blockquote>