diff --git a/README.md b/README.md index 7ad7f7f..ecfcc1b 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,6 @@ -# Currency converter +Bret Runestad +currency conversion assignment -## Description +The convert function takes a list of rates, a starting value, and two strings: a 'from' string and a 'two' string. The list of rates must take the form of a list of tuples. Each tuple should take the form ('USD', 'EUR', 0.74), where the first two indexes are 3-letter codes for different currencies, and the 3rd index is the conversion rate from the first code to the second. The 'from' and 'to' strings must be 3-letter codes that correspond to existing pairs within the list of rates, although the order of the pair may be reversed. When run, the convert function will take the starting value, and convert that amount from the 'from' currency to the 'to' currency. It is as fun as it sounds. -Create a set of functions to convert currency from one denomination to another. - -## Objectives - -### Learning Objectives - -After completing this assignment, you should understand: - -* Test-driven development - -### Performance Objectives - -After completing this assignment, you should be able to: - -* Raise exceptions -* Write detailed tests -* Break down programming problems into smaller ones - -## Details - -### Deliverables - -* A Git repo called currency-converter containing at least: - * `README.md` file explaining how to run your project - * a `currency` module - * a `test_currency` set of tests - -### Requirements - -* Passing unit tests -* No PEP8 or Pyflakes warnings or errors -* No functions longer than 7 lines of code -* 100% test coverage - -## Normal Mode - -Use test-driven development to design a function called `convert`. Below is a list of all the things it should do. In order to complete this exercise, follow these directions: - -* For each requirement, write a test first, and then make the test pass, do not pass Go, do not collect $200. -* Every time you finish a requirement, commit your code with a message describing the requirement. -* Go through the requirements one-by-one. Do not skip around. - -### Steps: - -* Create a function called `convert` that takes a list called `rates`, a number called `value`, a string called `from`, and a string called `to`. Make sure than when you call `convert` with `from` and `to` being equal, the return value is the same as `value`. - -* `rates` list should be a list of tuples, with each tuple containing a currency code you can convert from, a currency code you can convert to, and a rate. - - ```py - [("USD", "EUR", 0.74)] - ``` - - This means that each dollar is worth 0.74 euros. - - `value` is the amount of currency, `from` is the current currency code, and `to` is the currency code you wish to convert to. - - Given the above rates, make sure that converting 1 dollar into euros returns the following value: `0.74`. - -* Next, test that you can convert currency with a `value` that is not 1. -* Next, test that converting 1 euro into dollars returns `1.35` (or an approximation). -* Create a new list of rates with two or more tuples. Make sure you can convert both ways with each rate. For example, with these rates: - - ```py - [("USD", "EUR", 0.74), ("EUR", "JPY", 145.949)] - ``` - - Make sure you can convert from USD to EUR, EUR to USD, EUR to JPY, and JPY to EUR. - -## Hard Mode - -In addition to the requirements from **Normal Mode**: - -* Make sure that if you try to make a conversion you do not know about, a `ValueError` is raised with an appropriate message. - -* Test that you can convert between any two rates that you have the ability to, even if you do not have a direct conversion rate for them. For example, with the rates: - - ```py - [("USD", "EUR", 0.74), ("EUR", "JPY", 145.949)] - ``` - - Make sure you can convert from USD to JPY. - - This will probably require [Dijkstra's algorithm](http://rosettacode.org/wiki/Dijkstra%27s_algorithm). - - -## Additional Resources - -* [Currency charts](http://www.xe.com/currencycharts/) if you want accurate values. -* The [pytest](http://pytest.org/latest/) testing framework. -* [An Introduction to Test Driven Development](https://www.codeenigma.com/community/blog/introduction-test-driven-development). -* [Test-Driven Development](https://en.wikibooks.org/wiki/Introduction_to_Software_Engineering/Testing/Test-driven_Development) on Wikibooks. -* [Test-Driven Development by Example](http://www.amazon.com/Test-Driven-Development-By-Example/dp/0321146530), the canonical book on this stuff. +The exception_check program is a small program whose sole purpose is to catch the IndexError that arises when the 'from' and 'to' strings do not match with a corresponding tuple. diff --git a/currency.py b/currency.py new file mode 100644 index 0000000..3e5054a --- /dev/null +++ b/currency.py @@ -0,0 +1,29 @@ +def convert(rates, value, from_string, to_string): + """Takes a list of rates, an amount of currency(value), a from_string, and + a to_string. It cross references the 'from' and 'to' strings to find the + applicable currency exchange rate. It then multiplies the value by that + rate, rounded to 2 decimal places.""" + tuple_list = ( + [x for x in rates if x[0] == from_string and x[1] == to_string]) + if tuple_list: + return round(tuple_list[0][2] * value, 2) + else: + tuple_list2 = ( + [x for x in rates if x[1] == from_string and x[0] == to_string]) + return round((1/tuple_list2[0][2]) * value, 2) + + +def exception_check(rates, value, from_string, to_string): + """Runs the convert program, but provides an error message for + unrecognized 'from' or 'to' strings""" + try: + return convert(rates, value, from_string, to_string) + except IndexError: + print( + "Sorry, at least one of the currency codes is not in my database") + return ("Error message") + + +if __name__ == "__main__": + + rates = [("USD", "EUR", 0.74)] diff --git a/test_currency.py b/test_currency.py new file mode 100644 index 0000000..5fea6d0 --- /dev/null +++ b/test_currency.py @@ -0,0 +1,62 @@ +from currency import* + + +def test_convert_value_check(): + assert convert(rates=[('USD', 'USD', 1)], + value=5, + from_string='USD', + to_string='USD') == 5 + + +def test_convert_dollar_to_euro(): + rates = [('USD', 'EUR', .74), ('USD', 'JPY', 145.949)] + assert convert(rates, + value=1, + from_string='USD', + to_string='EUR') == 0.74 + + +def test_convert_different_values(): + rates = [('USD', 'EUR', .74), ('USD', 'JPY', 145.949)] + assert convert(rates, value=5, + from_string='USD', to_string='EUR') == 3.7 + assert convert(rates, value=.2, + from_string='USD', to_string='EUR') == 0.15 + assert convert(rates, value=0, + from_string='USD', to_string='EUR') == 0 + + +def test_flipped_conversion(): + rates = [('USD', 'EUR', .74), ('USD', 'JPY', 145.949)] + assert convert(rates, value=1, + from_string='EUR', to_string='USD') == 1.35 + + +def test_multiple_conversions(): + rates = [('USD', 'EUR', .74), + ('USD', 'JPY', 145.949), + ('USD', 'CAD', 1.21)] + assert convert(rates, value=500, + from_string='USD', to_string='EUR') == 370 + assert convert(rates, value=500, + from_string='EUR', to_string='USD') == 675.68 + assert convert(rates, value=500, + from_string='USD', to_string='JPY') == 72974.5 + assert convert(rates, value=500, + from_string='JPY', to_string='USD') == 3.43 + assert convert(rates, value=500, + from_string='USD', to_string='CAD') == 605 + + +def test_exception_check(): + rates = [('USD', 'EUR', .74), + ('USD', 'JPY', 145.949), + ('USD', 'CAD', 1.21)] + assert exception_check(rates, value=500, + from_string='USD', to_string='EUR') == 370 + assert exception_check(rates, value=500, + from_string='USD', to_string='FART') == ( + "Error message") + assert exception_check(rates, value=500, + from_string='ABC', to_string='DEF') == ( + "Error message")