Selecting Specific Data
Purpose (do/learn; why this/here): Create a "Find Contact" button that uses a find contacts
block to select items from the contact list based on the contact's name. Students get practice with list processing, navigating abstract data types, and using the higher order function, keep
.
BH: Ditto. (I still want given and family names! We can make it doable.)
- Mary and Brian agreed to do this as a TIF. BH will write it onto this page in a TIF, and Mary will review/edit. --MF, 4/9/19
On this page, you will develop code for a "Find Contact" button to locate contacts in the list.
As you add more contacts to your list, it will become less and less realistic to find the one you want by reading through the whole list. So building a search feature will become essential for finding the desired information efficiently. Lists, adding and removing items from lists, and searching lists are common features in many programs.
BH and Mary want to use this again and mention tables and include images of both in snap and discuss how to change back and forth between the two views. --MF, 4/9/19
Each new contact is a list (item 1 is a name and item 2 should be a phone number), so the list of contacts is a list of lists.
- If it isn't open already, open your U3L1-ContactList project.
-
Write a
block that takes a text string as input and reports either a list of the contacts whose name includes that string or an empty list if no such name is in contact list.
Use these blocks:
, which reports true
if the first string (for example, a contact's name in the list) contains the second string (for example, a name or part of a name)
, which reports only the items that make the function true
, which returns true
if the list is empty and false
otherwise
- Selector
-
Develop a "Find Contact" button.
- Make the script ask the user whose contact to search for and have the sprite
say
each of the matching contacts.
- If the contact is not in the list, make the sprite say "not found."
- Debug. Make sure everything works the way you want it to before going on.
What is the output of this program?
On the previous page, you built code to add a contact to your app. On this page, you built code to find contacts. This process of breaking a programming project up into separate sub-problems is called modularity.
-
Develop a "Delete Contact" button.
- Move the "Delete Contact" button onto the stage.
- Make the script ask the user to "Enter the name of the contact(s) you wish to delete."
- Then, use your
find contacts
block to find all the matching contacts.
- Give the user the list of matching contacts and ask them for confirmation to delete (so the user won't accidentally delete their contact).
- If the user confirms that they want to delete these contacts, replace the contact list with a list of all contacts whose name does not match the input name.
- Modify your "Delete Contact" script so that it lets the user choose which contact they want to delete when
find
reports more than one.
This requires that you've already done the TIF on the previous
page.
- Write a predicate function that takes two contacts
as inputs. It should return True if the first contact
belongs before the second one in a sorted contact list.
That is, you'll have to extract the names (in sorted form)
from the two contacts, and then use
<
to compare them. Respect the data abstractions.
- Make a block to sort the contact list. To do
the actual sorting, you can load the "List utilities"
library. It has a block
.
Use the contact list as the first input. The second
input should be the predicate function you just wrote.
(Leave its two input slots empty.) The sort
block will report a new, sorted contact list.
- Test what you've done so far.
We've been sloppy so far in talking about name formats.
Most people in the United States say their given name (the one
their parents chose for them) first, and their family name
last. But in China, for example, the family name comes first.
So "Sun Yat-sen" is a member of the Sun family.
- How should his name be displayed to the user?
- How should his name look to sort contacts by family name?
- What about someone with a middle name, such as
Martin Luther King? Is the middle name a family name or a
given name?
Here's the tricky part: To make this all work correctly, a
name (as defined by the Name ADT) has to know whether it's a
given-first name such as Betsy Anderson or a family-first
name such as Sun Yat-Sen. Redefine your Name ADT
to make it
a list of three items. The first will be either
given-first
or family-first
. This
first item is called a type tag. The second will be
the given name (or names, if there's a middle name), and the
third will be the family name.
You've been using type tags all along without knowing it.
Many programming languages, including Snap!, attach
type tags to every value, saying "I am a list" or "I am a
number" and so on. The user (i.e., you) doesn't see the
type tags, unless you provide a bad input to a
primitive block, and you see a message like "Expecting
list but getting text."
Reading a name: Find where you ask the user
for first and last name, and change the code to ask for
given name(s) and family name. Also ask which comes first.
You might want to have two name constructors,
given-first name from given: family:
and
family-first name from given: family:
.
Writing a name: Modify your
name (display form) from contact
and
name (sort form) from contact
so that they
check the type tag of the name (the first item) when
necessary. Be careful about when to add a comma.
Make sure your
find contacts
block
and your sorting of the contact list still work with
a contact list containing both kinds of names.