SATSHELL Example |
|
Home | SATGUI | SATSHELL | SATFORM | SATFILTER | SATREPORT | SATMYSQL | License | Download | Examples | Contact |
A simple address book utility. It is assumed that the Address Book data file sataddress.dat is located in the "current" directory.
User Guide |
The following example assumes that the directories for both satshell and sataddress are included in the PATH environment variable.
To start the application enter:
satshell sataddress
When the application has started a screen similar to the following is displayed:
Button | Action |
![]() | Add Address screen. |
![]() | Edit Address screen. Edit selected address. |
![]() | Delete Address. Delete selected address. |
![]() | Exit the application. |
To display all details held in the "Address Book" for a particular person, double-click anywhere on the line for the required person. The Address Book - Display screen is displayed.
The buttons labeled with letters can be used to limit the display range to show only names beginning with the letters shown on the button. Pressing the blue labeled "A-Z" will display all names in the Address Book. The sort order also depends on the Name Format setting. When "First,Last" Name Format is selected the names will be sorted by first name.
For example: To display all names beginning "S", "T" or "U" press the "STU" button:-
To display the names in reverse alphabetic order press the "Z-A" radio button, then the letter button for the range of names to be displayed.
For example: To display all names in reverse order, select "Z-A" Order, then press the blue "A-Z" range button:-
To change the name format to show the First Name first, press the "First,Last" radio button, then the letter button for the range of names to be displayed.
For example: To display all names in "First,Last" name format, select "First,Last" Name Format, then press the blue "A-Z" range button:-
Button | Action |
![]() | Back to the list of addresses. |
![]() | Edit Address screen. |
![]() | Delete Address. |
![]() | Exit the application. |
Button | Action |
![]() | Back to the list of addresses (Without saving). |
![]() | Save Address screen. |
![]() | Exit the application. |
The following conditions apply when adding a new address:-
The validated conditions will generate a red error message on the message line if the condition is not met:-
For example: "Invalid First Name", "Person already exists in Address Book
".
Button | Action |
![]() | Back to the list of addresses (Without saving). |
![]() | Save Address screen. |
![]() | Exit the application. |
The following conditions apply when adding a new address:-
The validated conditions will generate a red error message on the message line if the condition is not met:-
For example: "Invalid Address".
Source Code |
#===========================================================# # SCRIPT : sataddress # # PURPOSE : Address Book application. # #===========================================================# #----------------------------------------------------------# # Display main screen: List of names and telephone numbers # #----------------------------------------------------------# main() { cat << ! newScreen {{"Address Book"} 57x23} addToolbar {raised {person help(Add_Address) add} {pen help(Edit_Address) {edit list(0)}} {trash help(Delete_Address) confirm(Delete_Address?) {delete list(0)}} {} {stop help(Exit) exit} } addGrid {show 1,2 2 { {ABC DEF GHI JKL MNO PGR STU VWX YZ {A-Z blue}} } {refresh name_format order %} } addMultiList {list 1,4 12 {Name,30 Telephone,20} outline yscroll {display list(0)}} addRadioButtons {Order 1,20 {+A-Z Z-A} outline title horizontal} addRadioButtons {Name_Format 20,20 {+Last,First First,Last} outline title horizontal} ! refresh $NameFormat $Order $Range } #----------------------------------------------------------------# # Display add screen: Form to enter new name, number and address # #----------------------------------------------------------------# add() { cat << ! newScreen {{"Address Book - Add"} 45x18} addToolbar {raised {back help(Back) main} {disk help(Save_Address) validate {save title first_name last_name telephone address address2 address3}} {} {stop help(Exit) exit} } addLabel {label1 1,3 10 "Title" noborder} addPickList {Title 12,3 6,4 {+Mr Mrs Miss Ms Dr}} addEntries {1,5 {10,30 {First_Name valid_name} {Last_Name valid_name} {Telephone no_colon} {Address no_colon} {!address2 no_colon} {!address3 no_colon} } } unlock ! } #--------------------------------# # Delete selected address action # #--------------------------------# delete() { if [ -z "$1" ] then echo 'setMessage {"No address selected for delete" red};unlock' return fi if [ $NameFormat = "last,first" ] then grep -v "^.*:$1:" sataddress.dat > sataddress.tmp.dat else grep -v "^$1:" sataddress.dat > sataddress.tmp.dat fi mv sataddress.tmp.dat sataddress.dat main } #----------------------------------------------------------# # Display details screen: All details for selected address # #----------------------------------------------------------# display() { setrecord "$1" cat << ! newScreen {{"Address Book - Display"} 45x15} addData {this_record "$1"} addToolbar {raised {back help(Back) main} {pen help(Edit_Address) {edit this_record}} {trash help(Delete_Address) confirm(Delete_Address?) {delete this_record}} {} {stop help(Exit) exit} } addLabel {label1 1,2 10 " Name Telephone Address" bold } addLabel {label2 15,2 30 { $Title $FirstName $LastName $Telephone $Address $Address2 $Address3} } unlock ! } #----------------------------------------------------# # Display edit screen: Form to edit selected address # #----------------------------------------------------# edit() { if [ -z "$1" ] then echo 'setMessage {"No address selected for edit" red};unlock' return fi setrecord "$1" cat << ! newScreen {{"Address Book - Edit"} 45x18} addToolbar {raised {back help(Back) main} {disk help(Save_Address) validate {update title first_name last_name telephone address address2 address3}} {} {stop help(Exit) exit} } addLabel {label1 1,3 10 "Title" noborder} addPickList {Title 12,3 6,4 {Mr Mrs Miss Ms Dr}} addEntries {1,5 {10,30 -First_Name -Last_Name {Telephone no_colon} {Address no_colon} {!address2 no_colon} {!address3 no_colon} } } setItems { {title {$Title}} {first_name {$FirstName}} {last_name {$LastName}} {telephone {$Telephone}} {address {$Address}} {address2 {$Address2}} {address3 {$Address3}} } unlock ! } #---------------------------------------# # Refresh addresses list display action # #---------------------------------------# refresh() { NameFormat=$1 Order=$2 Range=$3 if [ $Order = "a-z" ] then SortOrder="" else SortOrder="-r" fi gawk -F: ' { if (NameFormat == "last,first") print $2 "\t" $6 else print $1 "\t" $6 }' NameFormat=$NameFormat sataddress.dat | sort $SortOrder | gawk ' BEGIN {print "setItem {list "} /^['$Range']/ {print "{" $0 "} "} END {print "};unlock"}' } #-----------------------------# # Save address details action # #-----------------------------# save() { if grep "^$2, $3:" test3.dat > /dev/null 2>&1 then echo 'setMessage {"Person already exists in Address Book" red};unlock' else echo "$2, $3:$3, $2:$1:$2:$3:$4:$5:$6:$7" >> sataddress.dat main fi } #-------------------------------------------------------# # Set record function: Read record and assign variables # #-------------------------------------------------------# setrecord() { if [ $NameFormat = "last,first" ] then Record=`grep "^.*:$1:" sataddress.dat` else Record=`grep "^$1:" sataddress.dat` fi Title=`echo "$Record" | cut -f3 -d:` FirstName=`echo "$Record" | cut -f4 -d:` LastName=`echo "$Record" | cut -f5 -d:` Telephone=`echo "$Record" | cut -f6 -d:` Address=`echo "$Record" | cut -f7 -d:` Address2=`echo "$Record" | cut -f8 -d:` Address3=`echo "$Record" | cut -f9 -d:` } #-------------------------------# # Update address details action # #-------------------------------# update() { grep -v "^$2, $3:" sataddress.dat > sataddress.tmp.dat echo "$2, $3:$3, $2:$1:$2:$3:$4:$5:$6:$7" >> sataddress.tmp.dat mv sataddress.tmp.dat sataddress.dat main } #------------# # Initialise # #------------# NameFormat="last,first" Order=a-z Range=A-Z [ ! -f sataddress.dat ] && touch sataddress.dat main echo 'addValidation {valid_name "^[A-Z][^:]*$"};addValidation {no_colon "^[^:]*$"}' #------------# # Main Loop # #------------# while true do read Command [ -z "$Command" ] && exit eval "$Command" done #---------------# # End of script # #---------------#
Comments |
This application consists of eleven sections:
main - Displays a list of all names and telephone numbers in a scrollable multi-column list.
main() {
Define the main function.
cat << !
A shell script "here" document is used to write SAT/DL commands to Standard Output.
This will be read and interpreted by SATSHELL.
Clear the screen/message line, set the application screen size to 57 characters by 23
rows, and set the window title to "Address Book".
Add a toolbar with a raised style at the top of the application window (row 0).
The toolbar has four buttons: "Add" (With person icon, "Add Address"
balloon help, runs the add function). "Edit" (With pen icon,
"Edit Address" balloon help, runs the edit function using
the first column (list(0)) of the selected address). "Delete" (With trash icon,
"Delete Address" balloon help, runs the delete function
using the first column (list(0)) of the selected address, displays a "Delete
Address?" confirmation dialog). "Exit" (With stop icon, "Exit" balloon
help, exit the application). The empty button definition ({}) creates a space
in the toolbar.
Add a grid of buttons with its top left corner at column 1, row 2.
Each grid cell has width 2. The grid has a single row. Each cell contains a
button labeled ABC, DEF ... A-Z. The A-Z button has blue text. When a button
is pressed the refresh function is run using the values of the
name_format and order radio buttons and the label text of the button (%).
Add a multi-column list box called list with its top left corner at column
1, row 4 which is 12 lines deep. The list box has two columns:
"Name" (30 characters) and "Telephone" (20 characters).
When an address is selected by double-click, the display
function is run with the first column (list(0)) of the selected list line
being passed as a parameter. The list box has an outline and a vertical scrollbar
(yscroll).
Add a group of radio buttons called Order with its top left corner at column 1,
row 20. The group has two buttons: A-Z and Z-A. The "+"
prefix causes the A-Z button to be activated. The radiobuttons have an outline
and the title option is set, which displays the name of the radio buttons (Order)
overlayed at its top left. The radio buttons are displayed horizontal (The default is
vertical).
Add a group of radio buttons called Name_Format with its top left corner at column
20, row 20. The group has two buttons: Last,First and First,Last.
The "+" prefix causes the Last,First button to be activated. The radiobuttons have
an outline and the title option is set, which displays the name of the radio buttons
("Name Format") overlayed at its top left. The radio buttons are displayed horizontal
(The default is vertical).
End the "here" document.
Run the refresh function (to populate the address list)
using the values of the NameFormat, Order and Range variables.
End the function definition.
add - Display form for entering new address.
Define the add function.
cat << !
A shell script "here" document is used to write SAT/DL commands to Standard Output.
This will be read and interpreted by SATSHELL.
Clear the screen/message line, set the application screen size to 45 characters by 18
rows, and set the window title to "Address Book - Add".
Add a toolbar with a raised style at the top of the application window (row 0).
The toolbar has three buttons: "Back" (With back icon, "Back"
balloon help, runs the main function). "Save" (With
disk icon, "Save Address" balloon help, validates all entry fields,
runs the save function using the values of the title,
first_name, last_name, telephone, address, address2 and address3 entry fields).
"Exit" (With stop icon, "Exit" balloon help, exit the application).
The empty button definition ({}) creates a space in the toolbar.
Add a label called label1 with its top left corner at column 1,
row 3 and a width of 10 characters. The label will display the text
"Title". By default a label has some padding around it to allow for a titled
border. The noborder removes the padding so that it lines up properly with the
entry field labels.
Add a pick list called title with its top left corner at column 12,
row 3. The pick list display is 6 characters wide and will display
a drop down list showing 4 lines, with Mr, Mrs, Miss, Ms, and Dr
options. As there are more options than display lines a scrollbar will automatically be
added. The "+" prefix causes the Mr option to be selected.
Add one column of entry fields with its top left corner at column 1, row 5.
All entry fields in the column have a label text width of 10 characters and an entry
width of 30 characters.
The "First Name" and "Last Name" fields have a valid_name
validation. The "Telephone" and "Address" labels have a no_colon validation.
The "!address2" and "!address3" use the "!" prefix to
supress display of the label text and also have a no_colon validation.
The validations used here are defined in the Initialise
section. The validations are checked when an entry field loses focus and when the
"Save" button is pressed.
The unlock is required because SATSHELL "locks" the application window when an
Action is triggered to prevent new Actions while the current is being processed.
End the "here" document.
End the function definition.
delete - Delete a selected address from the Address Book.
NOTE: This function requires one parameter ($1): The selected address.
Define the delete function.
If $1 is null display "No address selected for delete" in red text on the
message line. The unlock is required because SATSHELL "locks" the application
window when an Action is triggered to prevent new Actions while the current is being processed.
Create a temporary file (sataddress.tmp.dat) containing all records except
for the selected address. The grep pattern depends on the value of the NameFormat
variable.
Rename the temporary file to the name of the Address Book file (sataddress.dat).
Run the main function to display the name/number list.
End the function definition.
display - Display all information held in the Address Book for a selected address.
NOTE: This function requires one parameter ($1): The selected address.
Define the display function.
Run the setrecord function using the first parameter
($1), the name of an address, to read an Address Book record and set variables
containing data from the record.
A shell script "here" document is used to write SAT/DL commands to Standard Output.
This will be read and interpreted by SATSHELL.
Clear the screen/message line, set the application screen size to 45 characters by 15
rows, and set the window title to "Address Book - Display".
Add a data item called this_record using the first parameter ($1).
This is necessary for the toolbar "Edit" and "Delete" options because $1 contains
spaces and so cannot be passed as a literal
parameter value.
Add a toolbar with a raised style at the top of the application window (row 0).
The toolbar has four buttons: "Back" (With back icon, "Back"
balloon help, runs the main function). "Edit" (With pen
icon, "Edit Address" balloon help, runs the edit
function using the value of the this_record data item). "Delete" (With trash
icon, "Delete Address" balloon help, runs the delete
function using the value of the this_record data item, displays a "Delete
Address?" confirmation dialog). "Exit" (With stop icon, "Exit" balloon
help, exit the application). The empty button definition ({}) creates a space
in the toolbar.
Add a label called label1 with its top left corner at column 1,
row 2 and a width of 10 characters. The label will display the text
Name, Telephone and Address in bold text.
Add a label called label2 with its top left corner at column 15,
row 2 and a width of 30 characters. The label will display text
with the values of the Title, FirstName, LastName, Telephone, Address, Address2
and Address3 variables.
The unlock is required because SATSHELL "locks" the application window when an
Action is triggered to prevent new Actions while the current is being processed.
End the "here" document.
End the function definition.
edit - Display a form for editing a selected address.
NOTE: This function requires one parameter ($1): The selected address.
Define the edit function.
If $1 is null display "No address selected for edit" in red text on the
message line. The unlock is required because SATSHELL "locks" the application
window when an Action is triggered to prevent new Actions while the current is being processed.
Run the setrecord function using the first parameter
($1), the name of an address, to read an Address Book record and set variables
containing data from the record.
A shell script "here" document is used to write SAT/DL commands to Standard Output.
This will be read and interpreted by SATSHELL.
Clear the screen/message line, set the application screen size to 45 characters by 18
rows, and set the window title to "Address Book - Edit".
Add a toolbar with a raised style at the top of the application window (row 0).
The toolbar has three buttons: "Back" (With back icon, "Back"
balloon help, runs the main function). "Save" (With disk
icon, "Save Address" balloon help, validates all entry fields, runs the
save function using the values of the title, first_name, last_name, telephone,
address, address2 and address3 entry fields)."Exit" (With stop icon,
"Exit" balloon help, exit the application). The empty button definition
({}) creates a space in the toolbar.
Add a label called label1 with its top left corner at column 1,
row 3 and a width of 10 characters. The label will display the text
"Title". By default a label has some padding around it to allow for a titled
border. The noborder removes the padding so that it lines up properly with the
entry field labels.
Add a pick list called title with its top left corner at column 12,
row 3. The pick list display is 6 characters wide and will display
a drop down list showing 4 lines, with Mr, Mrs, Miss, Ms, and Dr
options. As there are more options than display lines a scrollbar will automatically be
added.
Add one column of entry fields with its top left corner at column 1, row 5.
All entry fields in the column have a label text width of 10 characters and an entry
width of 30 characters.
The "First Name" and "Last Name" use the "-" prefix which casues them
to be disabled/read-only. The "Telephone" and "Address" labels have a no_colon
validation. The "!address2" and "!address3" use the "!" prefix
to supress display of the label text and also have a no_colon validation.
Note: If, like the First_Name and Last_Name fields here, there
are no options to specify, the braces ({}) are optional.
The validations used here are defined in the Initialise
section. The validations are checked when an entry field loses focus and when the
"Save" button is pressed.
Set the title picklist and the entry fields to the values os the Title,
FirstName, LastName, Telephone, Address, Address2 and Address3 variables.
The unlock is required because SATSHELL "locks" the application window when an
Action is triggered to prevent new Actions while the current is being processed.
End the "here" document.
End the function definition.
refresh - Refresh the names/number (main) screen.
NOTE: This function requires three parameters ($1): The name format.
($2): The sort order for the names. ($3): The range of names to be displayed.
Define the refresh function.
Set the NameFormat, Order and Range variables to the values of the
function parameters.
Set the SortOrder variable depending on Order variable.
NOTE: Although the text on the Order radiobuttons is uppercase, the
value returned is always lowercase.
Extract the name/number information from the Address Book depending on the value of
the NameFormat variable.
Sort the name/number information according to the value of SortOrder.
Format the name/number information into a SAT/DL setItem command, selecting
only records specified in the Range variable. The unlock is required
because SATSHELL "locks" the application window when an Action is triggered to prevent
new Actions while the current is being processed.
End the function definition.
save - Save a new address in the Address Book.
NOTE: This function requires seven parameters ($1): Title ("Mr, Mrs" etc.)
($2): First name. ($3): Last name. ($4): Telephone number ($5): First address line.
($6): Second address line. ($7): Third address line.
Define the save function.
If a record already exists for this name, display "Person already exists in Address
Book" in red text on the message line. The unlock is required because
SATSHELL "locks" the application window when an Action is triggered to prevent new
Actions while the current is being processed.
If the record does not exist append a new Address Book record to sataddress.dat,
and run the main function to display the name/number list.
End function definition.
update - Save an edited address in the Address Book.
NOTE: This function requires seven parameters ($1): Title ("Mr, Mrs" etc.)
($2): First name. ($3): Last name. ($4): Telephone number ($5): First address line.
($6): Second address line. ($7): Third address line.
Define the update function.
Create a temporary file (sataddress.tmp.dat) containing all records except
for the selected address.
Append a new Address Book record containing the edited information to sataddress.dat.
Rename the temporary file to the name of the Address Book file (sataddress.dat).
Run the main function to display the name/number list.
End function definition.
setrecord - Set an Address Book record into variables.
Define the setrecord function.
Read an Address Book record. The grep pattern depends on the value of the
NameFormat variable.
Set variables for the Title, FirstName, LastName, Telephone, Address, Address2
and Address3 fields.
End function definition.
"Initialise" - Initialise the application and display the names/number (main) screen.
Initialise the NameFormat, Order and Range variables.
If the Address Book file (sataddress.dat) does not exist create one.
Run the main function to display the name/number list.
Add two validations: valid_name (Must begin with an uppercase letter, and must
not contain a colon). no_colon (Must not contain a colon).
newScreen {{"Address Book"} 57x23}
addToolbar {raised
{person help(Add_Address) add}
{pen help(Edit_Address) {edit list(0)}}
{trash help(Delete_Address) confirm(Delete_Address?) {delete list(0)}}
{}
{stop help(Exit) exit}
}
addGrid {show 1,2 2 {
{ABC DEF GHI JKL MNO PGR STU VWX YZ {A-Z blue}}
}
{refresh name_format order %}
}
addMultiList {list 1,4 12 {Name,30 Telephone,20} outline yscroll {display list(0)}}
addRadioButtons {Order 1,20 {+A-Z Z-A} outline title horizontal}
addRadioButtons {Name_Format 20,20 {+Last,First First,Last} outline title horizontal}
!
refresh $NameFormat $Order $Range
}
add() {
newScreen {{"Address Book - Add"} 45x18}
addToolbar {raised
{back help(Back) main}
{disk help(Save_Address) validate {save title first_name last_name telephone address address2 address3}}
{}
{stop help(Exit) exit}
}
addLabel {label1 1,3 10 "Title" noborder}
addPickList {title 12,3 6,4 {+Mr Mrs Miss Ms Dr}}
addEntries {1,5
{10,30
{First_Name valid_name}
{Last_Name valid_name}
{Telephone no_colon}
{Address no_colon}
{!address2 no_colon}
{!address3 no_colon}
}
}
unlock
!
}
delete() {
if [ -z "$1" ]
then
echo 'setMessage {"No address selected for delete" red};unlock'
return
fi
if [ $NameFormat = "last,first" ]
then
grep -v "^.*:$1:" sataddress.dat > sataddress.tmp.dat
else
grep -v "^$1:" sataddress.dat > sataddress.tmp.dat
fi
mv sataddress.tmp.dat sataddress.dat
main
}
display() {
setrecord "$1"
cat << !
newScreen {{"Address Book - Display"} 45x15}
addData {this_record "$1"}
addToolbar {raised
{back help(Back) main}
{pen help(Edit_Address) {edit this_record}}
{trash help(Delete_Address) confirm(Delete_Address?) {delete this_record}}
{}
{stop help(Exit) exit}
}
addLabel {label1 1,2 10 "
Name
Telephone
Address"
bold
}
addLabel {label2 15,2 30 {
$Title $FirstName $LastName
$Telephone
$Address
$Address2
$Address3}
}
unlock
!
}
edit() {
if [ -z "$1" ]
then
echo 'setMessage {"No address selected for edit" red};unlock'
return
fi
setrecord "$1"
cat << !
newScreen {{"Address Book - Edit"} 45x18}
addToolbar {raised
{back help(Back) main}
{disk help(Save_Address) validate {update title first_name last_name telephone address address2 address3}}
{}
{stop help(Exit) exit}
}
addLabel {label1 1,3 10 "Title" noborder}
addPickList {Title 12,3 6,4 {Mr Mrs Miss Ms Dr}}
addEntries {1,5
{10,30
-First_Name
-Last_Name
{Telephone no_colon}
{Address no_colon}
{!address2 no_colon}
{!address3 no_colon}
}
}
setItems {
{title {$Title}}
{first_name {$FirstName}}
{last_name {$LastName}}
{telephone {$Telephone}}
{address {$Address}}
{address2 {$Address2}}
{address3 {$Address3}}
}
unlock
!
}
refresh() {
NameFormat=$1
Order=$2
Range=$3
if [ $Order = "a-z" ]
then
SortOrder=""
else
SortOrder="-r"
fi
gawk -F: '
{
if (NameFormat == "last,first")
print $2 "\t" $6
else
print $1 "\t" $6
}' NameFormat=$NameFormat sataddress.dat |
sort $SortOrder |
gawk '
BEGIN {print "setItem {list "}
/^['$Range']/ {print "{" $0 "} "}
END {print "};unlock"}'
}
save() {
if grep "^$2, $3:" sataddress.dat > /dev/null 2>&1
then
echo 'setMessage {"Person already exists in Address Book" red};unlock'
else
echo "$2, $3:$3, $2:$1:$2:$3:$4:$5:$6:$7" >> sataddress.dat
main
fi
}
update() {
grep -v "^$2, $3:" sataddress.dat > sataddress.tmp.dat
echo "$2, $3:$3, $2:$1:$2:$3:$4:$5:$6:$7" >> sataddress.tmp.dat
mv sataddress.tmp.dat sataddress.dat
main
}
setrecord() {
if [ $NameFormat = "last,first" ]
then
Record=`grep "^.*:$1:" sataddress.dat`
else
Record=`grep "^$1:" sataddress.dat`
fi
Title=`echo "$Record" | cut -f3 -d:`
FirstName=`echo "$Record" | cut -f4 -d:`
LastName=`echo "$Record" | cut -f5 -d:`
Telephone=`echo "$Record" | cut -f6 -d:`
Address=`echo "$Record" | cut -f7 -d:`
Address2=`echo "$Record" | cut -f8 -d:`
Address3=`echo "$Record" | cut -f9 -d:`
}
NameFormat="last,first"
Order=a-z
Range=A-Z
[ ! -f sataddress.dat ] && touch sataddress.dat
main
echo 'addValidation {valid_name "^[A-Z][^:]*$"};addValidation {no_colon "^[^:]*$"}'
Address Book Record Format |
The Address Book data file (sataddress.dat) has the following record format:-
first_name, last_name:last_name, first_name:title:first_name:last_name:telephone:address1:address2:address3
For example:
Fred, Smith:Smith, Fred:Mr:Fred:Smith:987-6545:1 Long Drive:Townsville:Green County Marion, Smith:Smith, Marion:Mrs:Marion:Smith:555-8907:76 High Street:Townsville:Green County Mary, Jones:Jones, Mary:Dr:Mary:Jones:555-1234:556 Maple Road:Oakfield:Green County