add new exercise
This commit is contained in:
parent
f1c22136a8
commit
afbfecdc55
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"blurb": "Learn about numbers by solving Chandler's currency exchange conundrums.",
|
||||
"icon": "hyperia-forex",
|
||||
"authors": ["Ticktakto", "Yabby1997", "limm-jk", "OMEGA-Y", "wnstj2007", "J08K"],
|
||||
"files": {
|
||||
"solution": ["exchange.py"],
|
||||
"test": ["exchange_test.py"],
|
||||
"exemplar": [".meta/exemplar.py"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"track":"python","exercise":"currency-exchange","id":"f1e3f1d8394941a7b649aba8641e3c4a","url":"https://exercism.org/tracks/python/exercises/currency-exchange","handle":"Nebucatnetzer","is_requester":true,"auto_approve":false}
|
|
@ -0,0 +1,55 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
To run the included *tests*, run the test file using the `pytest` module, replacing `{exercise_name}`:
|
||||
|
||||
```bash
|
||||
$ python3 -m pytest {exercise_name}_test.py
|
||||
```
|
||||
|
||||
Many IDE's and code editors have built-in support for using Pytest to run tests; check them out [here](https://github.com/exercism/python/blob/main/docs/TOOLS.md#editors-and-ides).
|
||||
|
||||
For more information about running tests using `pytest`, checkout our [Python testing guide](https://github.com/exercism/python/blob/main/docs/TESTS.md#pytest).
|
||||
|
||||
### Common pytest options
|
||||
|
||||
- `-v` : enable verbose output.
|
||||
- `-x` : stop running tests on first failure.
|
||||
- `--ff` : run failures from previous test before running other test cases.
|
||||
|
||||
For other options, see `python3 -m pytest -h`.
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit exchange.py` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [Python track's documentation](https://exercism.org/docs/tracks/python)
|
||||
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
Below are some resources for getting help if you run into trouble:
|
||||
|
||||
- [The PSF](https://www.python.org) hosts Python downloads, documentation, and community resources.
|
||||
- [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community.
|
||||
- [#python on Libera.chat](https://www.python.org/community/irc/) this is where the cored developers for the language hang out and get work done.
|
||||
- [Exercism on Gitter](https://gitter.im/exercism/home) join the Python room for Python-related questions or problems.
|
||||
- [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners.
|
||||
- [Python Community Forums](https://discuss.python.org/)
|
||||
- [Pythontutor](http://pythontutor.com/) for stepping through small code snippets visually.
|
||||
|
||||
|
||||
Additionally, [StackOverflow](http://stackoverflow.com/questions/tagged/python) is a good spot to search for your problem/question to see if it has been answered already.
|
||||
If not - you can always [ask](https://stackoverflow.com/help/how-to-ask) or [answer](https://stackoverflow.com/help/how-to-answer) someone else's question.
|
|
@ -0,0 +1,31 @@
|
|||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- [The Python Numbers Tutorial](https://docs.python.org/3/tutorial/introduction.html#numbers) and [Python numeric types](https://docs.python.org/3.9/library/stdtypes.html#numeric-types-int-float-complex) can be a great introduction.
|
||||
|
||||
## 1. Estimating exchangeable value
|
||||
|
||||
- You can use the [division operator](https://docs.python.org/3/tutorial/introduction.html#numbers) to get the value of exchanged currency.
|
||||
|
||||
## 2. Changes after exchanging
|
||||
|
||||
- You can use the [subtraction operator](https://docs.python.org/3/tutorial/introduction.html#numbers) to get the amount of changes.
|
||||
|
||||
## 3. Calculate value of bills
|
||||
|
||||
- You can use the [multiplication operator](https://docs.python.org/3/tutorial/introduction.html#numbers) to get the value of bills.
|
||||
|
||||
## 4. Calculate number of bills
|
||||
|
||||
- You need to divide `budget` into `denomination`.
|
||||
- You need to use type casting to _int_ to get the exact number of bills.
|
||||
- To remove decimal places from a `float`, you can convert it to `int`.
|
||||
|
||||
**Note:** The `//` operator also does floor division. But, if the operand has `float`, the result is still `float`.
|
||||
|
||||
## 5. Calculate exchangeable value
|
||||
|
||||
- You need to calculate `spread` percent of `exchange_rate` using multiplication operator and add it to `exchange_rate` to get the exchanged currency.
|
||||
- The actual rate needs to be computed. Remember to add exchange rate and exchange fee.
|
||||
- You can get exchanged money affected by commission by using divide operation and type casting _int_.
|
|
@ -0,0 +1,188 @@
|
|||
# Currency Exchange
|
||||
|
||||
Welcome to Currency Exchange on Exercism's Python Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
||||
|
||||
## Introduction
|
||||
|
||||
## Numbers
|
||||
|
||||
There are three different kinds of built-in numbers in Python : `ints`, `floats`, and `complex`. However, in this exercise you'll be dealing only with `ints` and `floats`.
|
||||
|
||||
### ints
|
||||
|
||||
`ints` are whole numbers. e.g. `1234`, `-10`, `20201278`.
|
||||
|
||||
Integers in Python have [arbitrary precision][arbitrary-precision] -- the amount of digits is limited only by the available memory of the host system.
|
||||
|
||||
### floats
|
||||
|
||||
`floats` are numbers containing a decimal point. e.g. `0.0`,`3.14`,`-9.01`.
|
||||
|
||||
Floating point numbers are usually implemented in Python using a `double` in C (_15 decimal places of precision_), but will vary in representation based on the host system and other implementation details. This can create some surprises when working with floats, but is "good enough" for most situations.
|
||||
|
||||
You can see more details and discussions in the following resources:
|
||||
|
||||
- [Python numeric type documentation][numeric-type-docs]
|
||||
- [The Python Tutorial][floating point math]
|
||||
- [Documentation for `int()` built in][`int()` built in]
|
||||
- [Documentation for `float()` built in][`float()` built in]
|
||||
- [0.30000000000000004.com][0.30000000000000004.com]
|
||||
|
||||
## Arithmetic
|
||||
|
||||
Python fully supports arithmetic between `ints` and `floats`. It will convert narrower numbers to match their less narrow counterparts when used with the binary arithmetic operators (`+`, `-`, `*`, `/`, `//`, and `%`). When division with `/`, `//` returns the quotient and `%` returns the remainder.
|
||||
|
||||
Python considers `ints` narrower than `floats`. So, using a float in an expression ensures the result will be a float too. However, when doing division, the result will always be a float, even if only integers are used.
|
||||
|
||||
```python
|
||||
# The int is widened to a float here, and a float type is returned.
|
||||
>>> 3 + 4.0
|
||||
7.0
|
||||
>>> 3 * 4.0
|
||||
12.0
|
||||
>>> 3 - 2.0
|
||||
1.0
|
||||
# Division always returns a float.
|
||||
>>> 6 / 2
|
||||
3.0
|
||||
>>> 7 / 4
|
||||
1.75
|
||||
# Calculating remainders.
|
||||
>>> 7 % 4
|
||||
3
|
||||
>>> 2 % 4
|
||||
2
|
||||
>>> 12.75 % 3
|
||||
0.75
|
||||
```
|
||||
|
||||
If an int result is needed, you can use `//` to truncate the result.
|
||||
|
||||
```python
|
||||
>>> 6 // 2
|
||||
3
|
||||
>>> 7 // 4
|
||||
1
|
||||
```
|
||||
|
||||
To convert a float to an integer, you can use `int()`. Also, to convert an integer to a float, you can use `float()`.
|
||||
|
||||
```python
|
||||
>>> int(6 / 2)
|
||||
3
|
||||
>>> float(1 + 2)
|
||||
3.0
|
||||
```
|
||||
|
||||
[arbitrary-precision]: https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic#:~:text=In%20computer%20science%2C%20arbitrary%2Dprecision,memory%20of%20the%20host%20system.
|
||||
[numeric-type-docs]: https://docs.python.org/3/library/stdtypes.html#typesnumeric
|
||||
[`int()` built in]: https://docs.python.org/3/library/functions.html#int
|
||||
[`float()` built in]: https://docs.python.org/3/library/functions.html#float
|
||||
[0.30000000000000004.com]: https://0.30000000000000004.com/
|
||||
[floating point math]: https://docs.python.org/3.9/tutorial/floatingpoint.html
|
||||
|
||||
## Instructions
|
||||
|
||||
Your friend Chandler plans to visit exotic countries all around the world. Sadly, Chandler's math skills aren't good. He's pretty worried about being scammed by currency exchanges during his trip - and he wants you to make a currency calculator for him. Here are his specifications for the app:
|
||||
|
||||
## 1. Estimate value after exchange
|
||||
|
||||
Create the `exchange_money()` function, taking 2 parameters:
|
||||
|
||||
1. `budget` : The amount of money you are planning to exchange.
|
||||
2. `exchange_rate` : Unit value of the foreign currency.
|
||||
|
||||
This function should return the value of the exchanged currency.
|
||||
|
||||
**Note:** If your currency is USD and you want to exchange USD for EUR with an exchange rate of `1.20`, then `1.20 USD == 1 EUR`.
|
||||
|
||||
```python
|
||||
>>> exchange_money(127.5, 1.2)
|
||||
106.25
|
||||
```
|
||||
|
||||
## 2. Calculate currency left after an exchange
|
||||
|
||||
Create the `get_change()` function, taking 2 parameters:
|
||||
|
||||
1. `budget` : Amount of money before exchange.
|
||||
2. `exchanging_value` : Amount of money that is *taken* from the budget to be exchanged.
|
||||
|
||||
This function should return the amount of money that *is left* from the budget.
|
||||
|
||||
```python
|
||||
>>> get_change(127.5, 120)
|
||||
7.5
|
||||
```
|
||||
|
||||
## 3. Calculate value of bills
|
||||
|
||||
Create the `get_value_of_bills()` function, taking 2 parameters:
|
||||
|
||||
1. `denomination` : The value of a single bill.
|
||||
2. `number_of_bills` : Amount of bills you received.
|
||||
|
||||
This function should return the total value of the given *bills*.
|
||||
|
||||
```python
|
||||
>>> get_value_of_bills(5, 128)
|
||||
640
|
||||
```
|
||||
|
||||
## 4. Calculate number of bills
|
||||
|
||||
Create the `get_number_of_bills()` function, taking `budget` and `denomination`.
|
||||
|
||||
This function should return the *number of bills* that you can get using the *budget*.
|
||||
**Note: ** You can only receive _whole bills_, not fractions of bills, so remember to divide accordingly.
|
||||
```python
|
||||
>>> get_number_of_bills(127.5, 5)
|
||||
25
|
||||
```
|
||||
|
||||
## 5. Calculate value after exchange
|
||||
|
||||
Create the `exchangeable_value()` function, taking `budget`, `exchange_rate`, `spread`, and `denomination`.
|
||||
|
||||
Parameter `spread` is the *percentage taken* as an exchange fee.
|
||||
If `1.00 EUR == 1.20 USD` and the *spread* is `10`, the actual exchange will be: `1.00 EUR == 1.32 USD`.
|
||||
|
||||
This function should return the maximum value of the new currency after calculating the *exchange rate* plus the *spread*.
|
||||
Remember that the currency *denomination* is a whole number, and cannot be sub-divided.
|
||||
|
||||
**Note:** Returned value should be `int` type.
|
||||
|
||||
```python
|
||||
>>> exchangeable_value(127.25, 1.20, 10, 20)
|
||||
80
|
||||
>>> exchangeable_value(127.25, 1.20, 10, 5)
|
||||
95
|
||||
```
|
||||
|
||||
## 6. Calculate non-exchangeable value
|
||||
|
||||
Create the `non_exchangeable_value()` function, taking `budget`, `exchange_rate`, `spread`, and `denomination`.
|
||||
|
||||
This function should return the value that is *not* exchangeable due to the *denomination* of the bills.
|
||||
|
||||
**Note:** Returned value should be `int` type.
|
||||
|
||||
```python
|
||||
>>> non_exchangeable_value(127.25, 1.20, 10, 20)
|
||||
16
|
||||
>>> non_exchangeable_value(127.25, 1.20, 10, 5)
|
||||
1
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @Ticktakto
|
||||
- @Yabby1997
|
||||
- @limm-jk
|
||||
- @OMEGA-Y
|
||||
- @wnstj2007
|
||||
- @J08K
|
|
@ -0,0 +1,68 @@
|
|||
def exchange_money(budget, exchange_rate):
|
||||
"""
|
||||
|
||||
:param budget: float - amount of money you are planning to exchange.
|
||||
:param exchange_rate: float - unit value of the foreign currency.
|
||||
:return: float - exchanged value of the foreign currency you can receive.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def get_change(budget, exchanging_value):
|
||||
"""
|
||||
|
||||
:param budget: float - amount of money you own.
|
||||
:param exchanging_value: int - amount of your money you want to exchange now.
|
||||
:return: float - amount left of your starting currency after exchanging.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def get_value_of_bills(denomination, number_of_bills):
|
||||
"""
|
||||
|
||||
:param denomination: int - the value of a bill.
|
||||
:param number_of_bills: int - amount of bills you received.
|
||||
:return: int - total value of bills you now have.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def get_number_of_bills(budget, denomination):
|
||||
"""
|
||||
|
||||
:param budget: float - the amount of money you are planning to exchange.
|
||||
:param denomination: int - the value of a single bill.
|
||||
:return: int - number of bills after exchanging all your money.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def exchangeable_value(budget, exchange_rate, spread, denomination):
|
||||
"""
|
||||
|
||||
:param budget: float - the amount of your money you are planning to exchange.
|
||||
:param exchange_rate: float - the unit value of the foreign currency.
|
||||
:param spread: int - percentage that is taken as an exchange fee.
|
||||
:param denomination: int - the value of a single bill.
|
||||
:return: int - maximum value you can get.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def non_exchangeable_value(budget, exchange_rate, spread, denomination):
|
||||
"""
|
||||
|
||||
:param budget: float - the amount of your money you are planning to exchange.
|
||||
:param exchange_rate: float - the unit value of the foreign currency.
|
||||
:param spread: int - percentage that is taken as an exchange fee.
|
||||
:param denomination: int - the value of a single bill.
|
||||
:return: int non-exchangeable value.
|
||||
"""
|
||||
|
||||
pass
|
|
@ -0,0 +1,77 @@
|
|||
import unittest
|
||||
import pytest
|
||||
from exchange import (
|
||||
exchange_money,
|
||||
get_change,
|
||||
get_value_of_bills,
|
||||
get_number_of_bills,
|
||||
exchangeable_value,
|
||||
non_exchangeable_value)
|
||||
|
||||
|
||||
class CurrencyExchangeTest(unittest.TestCase):
|
||||
|
||||
@pytest.mark.task(taskno=1)
|
||||
def test_exchange_money(self):
|
||||
input_data = [(100000, 0.84), (700000, 10.1)]
|
||||
output_data = [119047, 69306]
|
||||
|
||||
for variant, (input_data, output_data) in enumerate(zip(input_data, output_data), start=1):
|
||||
with self.subTest(f"variation #{variant}", input_data=input_data, output_data=output_data):
|
||||
self.assertEqual(int(exchange_money(input_data[0], input_data[1])), output_data)
|
||||
|
||||
@pytest.mark.task(taskno=2)
|
||||
def test_get_change(self):
|
||||
input_data = [(463000, 5000), (1250, 120), (15000, 1380)]
|
||||
output_data = [458000, 1130, 13620]
|
||||
|
||||
for variant, (input_data, output_data) in enumerate(zip(input_data, output_data), start=1):
|
||||
with self.subTest(f"variation #{variant}", input_data=input_data, output_data=output_data):
|
||||
self.assertEqual(get_change(input_data[0], input_data[1]), output_data)
|
||||
|
||||
@pytest.mark.task(taskno=3)
|
||||
def test_get_value_of_bills(self):
|
||||
input_data = [(10000, 128), (50, 360), (200, 200)]
|
||||
output_data = [1280000, 18000, 40000]
|
||||
|
||||
for variant, (input_data, output_data) in enumerate(zip(input_data, output_data), start=1):
|
||||
with self.subTest(f"variation #{variant}", input_data=input_data, output_data=output_data):
|
||||
self.assertEqual(get_value_of_bills(input_data[0], input_data[1]), output_data)
|
||||
|
||||
@pytest.mark.task(taskno=4)
|
||||
def test_get_number_of_bills(self):
|
||||
input_data = [(163270, 50000), (54361, 1000)]
|
||||
output_data = [3, 54]
|
||||
|
||||
for variant, (input_data, output_data) in enumerate(zip(input_data, output_data), start=1):
|
||||
with self.subTest(f"variation #{variant}", input_data=input_data, output_data=output_data):
|
||||
self.assertEqual(get_number_of_bills(input_data[0], input_data[1]), output_data)
|
||||
|
||||
@pytest.mark.task(taskno=5)
|
||||
def test_exchangeable_value(self):
|
||||
inputs = [
|
||||
(100000, 10.61, 10, 1),
|
||||
(1500, 0.84, 25, 40),
|
||||
(470000, 1050, 30, 10000000000),
|
||||
(470000, 0.00000009, 30, 700),
|
||||
(425.33, 0.0009, 30, 700)]
|
||||
|
||||
output_data = [8568, 1400, 0, 4017094016600, 363300]
|
||||
|
||||
for variant, (inputs, output_data) in enumerate(zip(inputs, output_data), start=1):
|
||||
with self.subTest(f"variation #{variant}", inputs=inputs, output_data=output_data):
|
||||
self.assertEqual(exchangeable_value(inputs[0], inputs[1], inputs[2], inputs[3]), output_data)
|
||||
|
||||
@pytest.mark.task(taskno=6)
|
||||
def test_non_exchangeable_value(self):
|
||||
inputs = [
|
||||
(100000, 10.61, 10, 1),
|
||||
(1500, 0.84, 25, 40),
|
||||
(425.33, 0.0009, 30, 700),
|
||||
(12000, 0.0096, 10, 50)]
|
||||
|
||||
output_data = [0, 28, 229, 13]
|
||||
|
||||
for variant, (inputs, output_data) in enumerate(zip(inputs, output_data), start=1):
|
||||
with self.subTest(f"variation #{variant}", inputs=inputs, output_data=output_data):
|
||||
self.assertEqual(non_exchangeable_value(inputs[0], inputs[1], inputs[2], inputs[3]), output_data)
|
Loading…
Reference in New Issue