T-Th 9:05 |
CS 1110: Introduction to Computing Using Python Fall 2014 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Main
About: Announcements Staff Consultants Times & Places Calendar Materials: Texts Python Command Shell Terminology VideoNote Handouts: Lectures Assignments Labs Assessment: Grading Exams Resources: CMS Piazza AEWs FAQ Python API Python Tutor Style Guide Academic Integrity |
Assignment 1:
|
Code | Name | 1 USD = | Code | Name | 1 USD = | |
---|---|---|---|---|---|---|
AED | United Arab Emirates dirham | 3.672930 | LKR | Sri Lankan rupee | 130.2050 | |
AFN | Afghan afghani | 55.59990 | LRD | Liberian dollar | 92.49990 | |
ALL | Albanian lek | 107.8000 | LSL | Lesotho loti | 10.69920 | |
AMD | Armenian dram | 409.6600 | LTL | Lithuanian litas | 2.665680 | |
ANG | Netherlands Antillean guilder | 1.790000 | LYD | Libyan dinar | 1.226980 | |
AOA | Angolan kwanza | 97.51100 | MAD | Moroccan dirham | 8.540400 | |
ARS | Argentine peso | 8.415000 | MDL | Moldovan leu | 14.12480 | |
AUD | Australian dollar | 1.066270 | MGA | Malagasy ariary | 2544.980 | |
AWG | Aruban florin | 1.790000 | MKD | Macedonian denar | 47.43480 | |
AZN | Azerbaijani manat | 0.784300 | MMK | Myanmar kyat | 973.9940 | |
BAM | Bosnia and Herzegovina convertible mark | 1.509960 | MNT | Mongolian tugrik | 1824.480 | |
BBD | Barbados dollar | 2.000000 | MOP | Macanese pataca | 7.982600 | |
BDT | Bangladeshi taka | 77.47670 | MRO | Mauritanian ouguiya | 290.4980 | |
BGN | Bulgarian lev | 1.510120 | MUR | Mauritian rupee | 31.64990 | |
BHD | Bahraini dinar | 0.377099 | MVR | Maldivian rufiyaa | 15.38000 | |
BIF | Burundian franc | 1534.990 | MWK | Malawian kwacha | 394.4310 | |
BMD | Bermudian dollar | 1.000000 | MXN | Mexican peso | 13.03400 | |
BND | Brunei dollar | 1.253990 | MYR | Malaysian ringgit | 3.182500 | |
BOB | Boliviano | 6.909640 | MZN | Mozambican metical | 30.39990 | |
BRL | Brazilian real | 2.240400 | NAD | Namibian dollar | 10.69920 | |
BSD | Bahamian dollar | 1.000000 | NGN | Nigerian naira | 162.3500 | |
BTN | Bhutanese ngultrum | 60.20000 | NIO | Nicaraguan córdoba | 26.18500 | |
BWP | Botswana pula | 8.928600 | NOK | Norwegian krone | 6.283200 | |
BYR | Belarusian ruble | 10499.79 | NPR | Nepalese rupee | 97.86750 | |
BZD | Belize dollar | 2.032360 | NZD | New Zealand dollar | 1.200700 | |
CAD | Canadian dollar | 1.088150 | OMR | Omani rial | 0.385100 | |
CDF | Congolese franc | 921.8460 | PAB | Panamanian balboa | 1.000000 | |
CHF | Swiss franc | 0.931450 | PEN | Peruvian nuevo sol | 2.856990 | |
CLP | Chilean peso | 586.3400 | PGK | Papua New Guinean kina | 2.475250 | |
CNY | Chinese yuan | 6.140700 | PHP | Philippine peso | 43.65000 | |
COP | Colombian peso | 1935.000 | PKR | Pakistani rupee | 102.0770 | |
CRC | Costa Rican colon | 541.9000 | PLN | Polish zloty | 3.225600 | |
CUC | Cuban convertible peso | 1.000000 | PYG | Paraguayan guaraní | 4282.110 | |
CUP | Cuban peso | 26.50000 | QAR | Qatari riyal | 3.641500 | |
CVE | Cape Verde escudo | 84.79700 | RON | Romanian new leu | 3.398600 | |
CZK | Czech koruna | 21.31940 | RSD | Serbian dinar | 91.93550 | |
DJF | Djiboutian franc | 181.1980 | RUB | Russian ruble | 36.88680 | |
DKK | Danish krone | 5.748800 | RWF | Rwandan franc | 687.9760 | |
DOP | Dominican peso | 43.46270 | SAR | Saudi riyal | 3.750350 | |
DZD | Algerian dinar | 80.53000 | SBD | Solomon Islands dollar | 7.348780 | |
EGP | Egyptian pound | 7.152500 | SCR | Seychelles rupee | 13.00250 | |
ERN | Eritrean nakfa | 10.47000 | SDG | Sudanese pound | 5.692500 | |
ETB | Ethiopian birr | 19.89750 | SEK | Swedish krona | 7.099000 | |
EUR | Euro | 0.772030 | SGD | Singapore dollar | 1.253990 | |
FJD | Fiji dollar | 1.866370 | SHP | Saint Helena pound | 0.612407 | |
FKP | Falkland Islands pound | 0.612407 | SLL | Sierra Leonean leone | 4385.000 | |
GBP | Pound sterling | 0.612407 | SOS | Somali shilling | 1198.980 | |
GEL | Georgian lari | 1.742020 | SRD | Surinamese dollar | 3.250000 | |
GHS | Ghanaian cedi | 3.732490 | STD | Sãmo Tomé and Príncipe dobra | 18950.16 | |
GIP | Gibraltar pound | 0.612407 | SYP | Syrian pound | 154.1000 | |
GMD | Gambian dalasi | 39.59370 | SZL | Swazi lilangeni | 10.69920 | |
GNF | Guinean franc | 7020.990 | THB | Thai baht | 31.98500 | |
GTQ | Guatemalan quetzal | 7.724500 | TJS | Tajikistani somoni | 4.971690 | |
GYD | Guyanese dollar | 205.6990 | TMT | Turkmenistani manat | 2.850000 | |
HKD | Hong Kong dollar | 7.750100 | TND | Tunisian dinar | 1.760500 | |
HNL | Honduran lempira | 21.12590 | TOP | Tongan pa'anga | 1.850140 | |
HRK | Croatian kuna | 5.888800 | TRY | Turkish lira | 2.159000 | |
HTG | Haitian gourde | 45.45240 | TTD | Trinidad and Tobago dollar | 6.328290 | |
HUF | Hungarian forint | 242.5430 | TWD | New Taiwan dollar | 29.91000 | |
IDR | Indonesian rupiah | 11744.20 | TZS | Tanzanian shilling | 1660.470 | |
ILS | Israeli new shekel | 3.602290 | UAH | Ukrainian hryvnia | 12.82700 | |
INR | Indian rupee | 60.20800 | UGX | Ugandan shilling | 2606.950 | |
IQD | Iraqi dinar | 1162.990 | USD | United States dollar | 1.000000 | |
IRR | Iranian rial | 26638.25 | UYU | Uruguayan peso | 24.10990 | |
ISK | Icelandic króna | 117.1500 | UZS | Uzbekistan som | 2351.830 | |
JMD | Jamaican dollar | 112.4980 | VEF | Venezuelan bolívar | 6.292500 | |
JOD | Jordanian dinar | 0.708750 | VND | Vietnamese dong | 21172.98 | |
JPY | Japanese yen | 105.0850 | VUV | Vanuatu vatu | 94.57730 | |
KES | Kenyan shilling | 88.65000 | WST | Samoan tala | 2.303090 | |
KGS | Kyrgyzstani som | 53.54950 | XAF | CFA franc BEAC | 506.4180 | |
KHR | Cambodian riel | 4064.880 | XAG | Silver (one troy ounce) | 0.052043 | |
KMF | Comoro franc | 379.8140 | XAU | Gold (one troy ounce) | 0.000788 | |
KPW | North Korean won | 132.4220 | XBT | BitCoin | 0.002080 | |
KRW | South Korean won | 1024.700 | XCD | East Caribbean dollar | 2.700000 | |
KWD | Kuwaiti dinar | 0.285640 | XPD | Palladium (one troy ounce) | 0.001124 | |
KYD | Cayman Islands dollar | 0.835187 | XPT | Platinum (one troy ounce) | 0.000709 | |
KZT | Kazakhstani tenge | 182.0150 | YER | Yemeni rial | 214.9050 | |
LAK | Lao kip | 8037.290 | ZAR | South African rand | 10.69920 | |
LBP | Lebanese pound | 1512.490 | ZMW | Zambian kwacha | 6.050000 | |
LKR | Sri Lankan rupee | 130.2050 | ZWD | Zimbabwe dollar | 361.9000 |
Note however, that you should not use this table in any of the functions
that you write in a1.py
. The table above is for testing your
functions; not for writing them. There is no reason for you to waste your
time hard-coding in all of the currencies listed in this table into your
program, since the web service you will contact already knows them all anyway.
One of the most important outcomes of this assignment is that you understand the importance of testing. This assignment will follow an iterative development cycle. That means you will write a few functions, then fully test them before you write any more. This process makes it easier to find bugs; you know that any bugs must have been part of the work you did since the last test.
In this section we help you get started with this process. We also provide an overview of the rest of the assignment.
To do this assignment, Python must be set up properly. If you have not already done this, follow the installation instructions to set it up on your computer. Alternatively, you can just work in the ACCEL lab.
You should also create a folder on your hard drive that is dedicated to this assignment and this assignment only. Every time that you work on a new assignment, we want you to make a new folder, to keep things organized and avoid problems with naming collisions. Make sure that the command shell and Komodo Edit are both open in the current folder before you start.
a1
In your newly created directory, you should create the module a1
(with file name a1.py
). This will be the main module for this assignment.
Following the
style guidelines, the first
three lines of this file should be single-line comments with (1) the module name, (2) the
name and netid of the authors, and (3) the date the file was last editted. Immediately
after this, add the following docstring:
"""Module for currency exchange This module provides several string parsing functions to implement a simple currency exchange routine using an online currency service. The primary function in this module is exchange."""
This docstring is the module specification. We recommend that you cut-and-paste the docstring into a1. For now, we want to expose you to specifications, not have you write them on your own.
a1test
Iterative development hinges on proper unit testing, which was covered in
lecture
and lab. In the same folder
as a1.py
, create the module a1test
(with file name a1test.py
). This will be the unit test for the
a1
module.
As with a1.py
, the first three lines of this file should be single-line
comments with (1) the module name, (2) your name and netid, and (3) the date the file
was last editted. Immediately after this, add the following Python code:
"""Unit test for module a1
When run as a script, this module invokes several procedures that
test the various functions in the module a1."""
import cornelltest
import a1
If you don't have the cornelltest module, you can get it
here.
As in lab 3, the module
cornelltest
provides access to the functions assert_equals
and assert_true
. The second import statement allows the unit test to
access all of the functions in a1
.
Add four procedure stubs to this assignment: testA
, testB
,
testC
, testD
. Remember that a procedure stub should have the
keyword pass
(indented) after the header, but nothing else. We will add
our test cases to these procedures later.
Finally at the end of a1test
, add the following script code:
See the lecture slides on how application code works.if __name__ == '__main__': testA() testB() testC() testD() print "Module a1 passed all tests"
The script code will call your four test procedures, which are (currently) empty. If everything is working, then the module print out the message
"Module a1 passed all tests"
Try this out.
The rest of the assignment is broken into four parts (listed as Parts A, B, C, and D). In each part, do the following:
We will give you the header to write. We will also give you a detailed docstring specification for the function. You should copy-and-paste the specification into the function body, indented.
Yes, this means you are writing tests before writing the function bodies. We talked about this in lecture.
Unless otherwise instructed, each test case should be a call to an assert function in cornelltest. Furthermore, your tests should be representative. Refer back to the instructions for lab 3 if you do not understand what we mean by this.
Make sure that the function satisify the specifications exactly. If the specification says to return something, you need a return statement. Make sure that the value returned is of the correct type.
If errors are found, fix them and re-test. Keep doing this until no more errors are found.
The descriptions that we provide in each part below represent the level of completeness and precision we are looking for in your docstring comments. In fact, it is best to copy-and-paste these descriptions to create the first draft of your docstring comments. If you do not cut and paste, please adhere to the conventions we use, such as using a single line, followed by a blank line and a more descriptive paragraph, or by using "Returns: ..." for fruitful-functions. Using a consistent set of good conventions in this class will help us all.
If you want to see if your specifications are written correctly, start an interactive Python shell and type
This should list all the functions with their specifications.>>> import a1 >>> help(a1)
A large part of this assignment is breaking a JSON into its component parts. A JSON string is a sequence of key-value pairs separated by commas. The key is a description of what the value means (like from or rate), since a JSON typically stores more than one value. For example, the substring
'"rate": 0.75443'
is a key-value pair with key 'rate' and value 0.75443.
The most important thing to do with a JSON is to extract out the substrings for the values. For example, consider the following JSON:
'{"to": "EUR", "rate": 0.77203, "from": "USD", "v": 1.93007500000000}'
Each value immediately follows a space. The end of the value is indicated by a comma or, if it is the value for 'v', by the curly brace at the end. This is the motivation for the two functions below.
def after_space(s):
"""Returns: The substring of s after the first space.
Precondition: s is a string with at least one space in it."""
def before_comma_or_end(s):
"""Returns: Substring of s up to but not including, the first comma.
If the string does not contain a comma, then the function returns
all but the last element in the string. THIS FUNCTION SHOULD NOT
HAVE ANY IF STATEMENTS.
Example: If s is 'a,b,c', this function returns 'a'.
Example: If s is 'abc}', it returns 'abc' (there is no comma).
Precondition: s is a nonempty string"""
You should implement these functions according to their specification, specification, as described in the Instructions for the Remainder of the Assignment. In other words,
The implementation of after_space(s) is relatively simple, and should be only a few lines. The implementation of before_comma_or_end(s) seems to be a little more complicated, particularly because you have to deal with the case in which there are no commas in the string. Those of you with programming experience might be tempted to use an if-statement. This is not necessary, and is not allowed.
Fortunately, Python gives us a very simple way to deal with this problem. The method find(a) returns -1 when the substring a is not found. Also note that s[:-1] leaves out the last character of the string. If you combine those two facts together, before_comma_or_end(s) should be just as simple as after_space(s).
To test the functions, you should make use of assert_equals in the module cornelltest to compare the result of each function with the string that you expect to get back. Our solution has four test cases for after_space and five test cases for before_comma_or_end. To give you an idea of what we are looking for after_space, consider the following questions:
The test cases for before_comma_or_end are very similar, except that they use commas instead of spaces.
Finally, do not forget to add a specification to testA(). Just because it is used for testing does not mean that it should not be properly specified.
As we said in Part A, a JSON string is a sequence of key-value pairs. Our next step is to take a complete JSON string and extract a single-key value pair. For example, given the response JSON string
'{"to": "EUR", "rate": 0.77203, "from": "USD", "v": 1.93007500000000}'
we want to extract the substring for key-value pair with key 'v'
'"v": 1.88608072500000'
Note that the keys are always contained inside double quotes. If the value is a string, it is also contained inside double quotes. However, if the value is a number (like the example above), it is not.
The functions below are designed to help you with these key-value pairs.
While working on each of the functions below, remember to write the test cases in
a1test.py
before implementing the body. All test cases in this section
go in the procedure testB(), which you should remember to specify. You
should thoroughly test each function before implementing the next one.
def get_keyword_index(json,key):
"""Returns: The index of the given key inside the JSON string
(including the quote character). It returns -1 if key is not there.
A key is considered to be any substring inside of double quotes. For
example, in the string
'A "B" C'
'B' is a key because it is inside double quote characters, while 'A'
and 'C' are not. However, arguments passed to the parameter key are
provided without any double quotes.
Example: get_keyword_index('A "key" B','key') evaluates to 2.
Example: get_keyword_index('A key B "key" C','key') evaluates to 8,
because it only chooses the instance of 'key' with quotes around it.
Example: get_keyword_index('A x B "key" C','x') evaluates to -1,
because there is no instance of '"x"' in the string 'A x B "key" C'.
Example: get_keyword_index('A "x" B','"x"') violates the precondition,
because the keyword argument is put in double quotes.
Precondition: key is a string that does not contain double quotes,
while json is a string."""
Once you have this function completed, you should move on to the following functions.
def has_error(json):
"""Returns: True if json is an invalid response, and False otherwise.
Given a JSON response to a currency query, this returns the boolean
value that tells whether the query is invalid. There are two ways for
the query to be invalid. The first way is if the JSON response has
a warning message in it. Those strings have the form
'{"to": <code>, "rate": <value>, "warning": <message>, "from": <code>}'
For example, you enter an invalid number of dollars, you will get the
message
'{"to": "EUR", "rate": 0.75, "warning": "invalid quantity, ignored.", "from": "USD"}'
The second way a JSON can be an invalid response is if it has an error
message in it, like
'{"err": <description>}'
For example, if you pass a query with invalid currency code, you will
get the message
'{"err": "failed to parse response from xe.com."}'
Be warned that both the warning and error messages can change; they are
not restricted to the examples above. If there is neither an error
message nor a warning, this function returns False.
Precondition: json is the response to a currency query."""
def get_value(json,key):
"""Returns: The JSON value (as a string) associated with the given key.
The value is substring after the keyword but before the first comma
(or the curly brace at the end). If the value is in double quotes, those
double quotes should be included as part of the substring.
Example: get_value('{"to": "EUR", "rate": 0.75443, "from": "USD", "v": 1.88}','to')
evaluates to '"EUR"'
Example: get_value('{"to": "EUR", "rate": 0.75443, "from": "USD", "v": 1.88}','v')
evaluates to '1.88' (still a string)
Precondition: key is a string that does not contain double quotes.
json is a JSON response string to a valid currency query, while key
is a valid keyword in json."""
As always, write your unit tests before implementing the two functions. Look carefully at the specifications. You only need to test valid JSON queries. To get some JSON responses for testing, enter a query URL into the web service and copy the result into a test case.
You should not need a conditional statement to implement these functions; simply find
the position of the appropriate keyword and extract the value in quotes immediately
after it. Your implementation must make use of the
find() or
index() string methods, plus the helper functions after_space(s)
and before_comma_or_end(s)
.
Now it is time to interact with the web service. In this part, you will implement a single function. The test cases for this function should go in procedure testC() in a1test.py. Do not forget to specify testC() properly.
def currency_response(currency_from, currency_to, amount_from):
"""Returns: a JSON string that is a response to a currency query.
A currency query converts amount_from money in currency
currency_from to the currency currency_to. The response
should be a string of the form
'{"to": <new>, "rate": <exchange>, "from": <old>, "v": <amount>}'
The values for "from" and "to" are the name for the original and
new currencies, respectively. The value for "rate" is the exchange
rate, while "v" is the value in the new currency.
If the query is invalid, the JSON will have a keyword "err"
instead.
Precondition: currency_from and currency_to are of type string,
while amount_from is a float."""
While this function sounds complicated, it is not as bad as you think it is.
You need to use the
urlopen
function from the module urllib2
. This function takes
a string that represents a URL and returns an instance of the class addinfourl
that represents the web page for that url. This object has the following methods:
Method | Specification |
---|---|
geturl() | Returns: The URL address of this web page as a string. |
read() | Returns: The contents of this web page as a string. |
Using one or both of these methods (you might not need them both) is enough to implement the function above.
You need to ensure that the function returns exactly the right JSON string for the value given. The best way to test this is to use a web browser to manually get the right JSON answer. For example, one test case can be constructed by seeing the result of going to the URL
http://cs1110.cs.cornell.edu/2014fa/a1/calculator.php?from=USD&to=EUR&q=2.5
Copy the value from this web page into a test case in testC()
.
Then check that the function returns the same JSON string. Remember to be thorough
with your choice of test cases; one is not enough.
Important: Fetching a web page takes time, especially if too many people are trying to do so simultaneously. You should give each call to this function at least 5-10 seconds to complete before restarting any tests.
We are now ready for the final part of the assignment. Implement the following specifications, again using our test-case-before-function-body approach. The test cases should go in procedure testD() in a1test, which you should properly specify. You may wish to use assert_true() instead of assert_equals() in some of your test cases. As with lab 3, there is also a case in which you will want to use assert_floats_equal().
def iscurrency(currency):
"""Returns: True if currency is a valid (3 letter code for a) currency.
It returns False otherwise.
Precondition: currency is a string."""
In implementing iscurrency()
, you should not use the
table of currencies. That would make a very large
function with a lot of if-statements. You are not allowed if-statements
in this lab. Instead, you must use the functions currency_response
and has_error
as helper functions.
def exchange(currency_from, currency_to, amount_from):
"""Returns: amount of currency received in the given exchange.
In this exchange, the user is changing amount_from money in
currency currency_from to the currency currency_to. The value
returned represents the amount in currency currency_to.
The value returned has type float.
Precondition: currency_from and currency_to are of type string,
and are both valid three-letter currency codes. The value
amount_from is a float"""
In the case of iscurrency()
, you will find the
exchange table useful in determining correct
answers for your test cases. While it is not okay to use the table in the
body of iscurrency()
itself, it is okay to use the table to
to decide on some test cases.
You may also use the table to craft some test cases for the function
exchange
. However, you might find it easier to use a currency
query URL to look up the correct answer, and then paste the answer into your
test case.
A bigger issue with testing exchange
is that problem that we
saw in class: real numbers cannot be represented exactly. This
creates problems when you try to test equality between floats.
To solve this problem, cornelltest provides a function called
assert_floats_equal(), which you encountered in
lab.
You should use this function to test exchange() instead of
assert_equals().
Finally, bear in mind that, like currency_response
, these functions
connect to the web service, and so are not instantaneous. In our solution,
with complete test procedures for everything, it can take up to 5 seconds to
run the unit test on campus. This will be a bit slower if you are working
closer to the deadline.
Once you have everything working you should go back and make sure that your program meets the class coding conventions, including the following:
One of the things that you may have the biggest difficulty with is breaking up long lines. First, you may not be aware when your lines are too long. There is an easy way to test. In Komodo Edit choose Edit > Preferences > Editor > Smart Edition. Select the checkbox that says Draw the edge line column.
As for breaking up long lines, there are two solutions. First, Python allows you to "hit Return" within any expression inside of parentheses. So if you are adding together several expressions together, like
a = 'Hello ' + name + ', it is good to meet you'
you can break it up over several lines, using parentheses, as follows:
a = ('Hello ' + name + ', it is good to meet you')
Another solution is to use the backslash symbol \. Remember that this is the escape character for making special characters in strings. It also has a special effect outside of a string. If you type this symbol, immediately followed by a return, then Python will know to continue to the next line. So you can rewrite the addition above as
a = 'Hello ' + name + \ ', it is good to meet you'
You can even use the backslash symbol inside of a string.
a = 'Hello ' + name + ', it is\ good to meet you'
However, if you do the last trick, be very careful about how spaces are handled; you might accidentally introduce extra spaces on the second line.
Upload the files a1.py
and a1test.py
to CMS by
the due date: Friday, September 19th at 11:59 pm.
Do not submit any files with the extension/suffix .pyc
. It will
help to set the preferences in your operating system so that extensions always appear.
Check the CMS daily until you get feedback from a grader. Make sure your CMS notifications for CS 1110 are set so that you are sent an email when one of your grades is changed. To find the feedback, click on the Assignment 1 link in CMS. On the page you are brought to, click on the red word "show" in the line "Grading Comments & Requests (show)." You can contact your grader if you have questions about their feedback; you can see their netid in the place you can see their feedback.
Within 24 hours, do RRRRR: Read the feedback, Revise your program accordingly, Resubmit, and Request a Regrade using the CMS. If you do not request a regrade, we have no simple way of knowing that you have resubmitted.
This whole process, starting from first submission on Friday, September 19th, continues until you submit a solution that demonstrates complete mastery; in some cases this may require multiple additional resubmits by you. You need to complete this process within one week. You need to have submitted a final, correct version by Friday, September 26th, which means you will probably want to have re-submitted at least once before then.
In addition to turning in the assignment, we ask that you complete the new survey posted in CMS. These assignments are still rather new(ish), and we would like some understanding of how long you spent on the assignment, your impression of the difficulty, and what could be done to improve it.
Please try to complete the survey within a day of turning in this assignment. Remember that participation in surveys compromise 1% of your final grade. We also ask that you be honest in your answers.
This section is not part of the assignment. It is optional. Furthermore, do not make the changes in this section to the file that you submit for grading. It will be sent back to you to fix.
So far you have worked with a simulated currency exchange service. But with a few changes you can use the real thing. In the web service instructions we told you to use the URL prefix
http://cs1110.cs.cornell.edu/2014fa/a1/calculator.php?If you change that prefix to
http://rate-exchange.appspot.com/currency?you will use Rate-Exchange currency calculator instead. Try that out on converting dollars to Euros (pick small values for now).
Run the exchange function four or five times. See the value being different from our currency table? That is one of the reasons we did not use the service; it is too hard to test against. In fact, even professional software engineers would do what we did: write a program against an unchanging exchange service before deploying it against the real thing.
If you end up using Rate-Exchange a lot, we ask that you buy the developer a coffee. Getting the currency exchange rates is not free, and the developer is hitting his quota with the increased load from this class.