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.)

On this page, you will develop code for a "Find Contact" button to locate contacts in the list.
find contacts with name: (Alphie) reporting

You learned about keep in Unit 2.
DAT-2.D.3

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.

photo of Farida Bedwei

Farida Bedwei (born in 1979) is a software engineer and the co-founder/Chief Technology Officer of Logiciel, a financial technology company based in Ghana. Due to difficulties in muscle control as a result of cerebral palsy, she began using a typewriter as an alternative to writing at an early age. Badwei attributes her future interest in computers to this early reliance on technology. In addition to being named as one of the most successful women in finance technology in Africa, Bedwei is a powerful advocate and role model for girls in STEM and for people with disabilities.

Article: The inspirational tech guru who’s owning cerebral palsy like a boss

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.

  1. If it isn't open already, open your U3L2-ContactList project.
  2. Write a find contacts with name: () 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:
    1. string () contains () ?, 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)
    2. keep items 'predicate input slot' from 'list input slot', which reports only the items that make the function true
    3. is 'list input slot' empty?, which returns true if the list is empty and false otherwise
    4. Selector name from contact: ()
  3. Develop a "Find Contact" button.
    1. Make the script ask the user whose contact to search for and have the sprite say each of the matching contacts.
    2. If the contact is not in the list, make the sprite say "not found."
  4. Debug. Make sure everything works the way you want it to before going on.
  5. CRD-2.D
    Save your work
  6. Write In Your JournalWhat is the output of this program?
AAP-3.B.2, AAP-3.B.3

Modularity is the process of breaking a programming project up into separate sub-problems. For example on page 2 of this lab, you built code to add a contact to your app, and on this page, you built code to find contacts.

  1. Develop a "Delete Contact" button.
    1. Move the "Delete Contact" button onto the stage.
    2. Make the script ask the user to "Enter the name of the contact(s) you wish to delete."
    3. Then, use your find contacts block to find all the matching contacts.
    4. Give the user the list of matching contacts and ask them for confirmation to delete (so the user won't accidentally delete their contact).
    5. 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.
  2. Modify your "Delete Contact" script so that it lets the user choose which contact they want to delete when find reports more than one.
    1. Write a helper block delete contact that takes a contact as input and removes that contact from contact list.
    2. Modify "Delete Contact" so that, if more than one contact matches the user's name input, it displays a list of the matching names and asks the user to select one by number. (The item numbers are automatically displayed in the name list, so you don't have to worry about that part.) Give the user a way to cancel the request instead of choosing a name.
    3. If exactly one contact matches, instead of displaying the one-item list of names, just ask the user to confirm or cancel deleting it. (Optional.)

This set of exercises requires that you've already done the Take It Further exercises on page 2. Open your project U3L2-TIF.

  1. 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.
  2. Make a block to sort the contact list. To do the actual sorting, you can load the "List utilities" library. It has a block sort 'list input slot' ordering with 'predicate input slot'. 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.
  3. Test what you've done so far.
  4. Tough Stuff 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 the name "Sun Yat-sen" be displayed to the user?
    • How should "Sun Yat-sen" look in order 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?
  5. Tough Stuff 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 the text 'given-first' or 'family-first'. This first item is called a type tag. The second item will be the given name (or names), and the third will be the family name (or names).
    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."
  6. Tough Stuff 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, contact name, given-first, from given: () family: () and contact name, family-first, from given: () family: ().
  7. Tough StuffWriting a name: Modify your name, display form, from contact 'list input slot and name, sort form, from contact 'list input slot' so that they check the type tag of the name (the first item) when necessary. Be careful about when to add a comma.
  8. Tough Stuff Make sure your find contacts block and your sorting of the contact list still work with a contact list containing both kinds of names.