diff --git a/python/armstrong-numbers/.exercism/config.json b/python/armstrong-numbers/.exercism/config.json
new file mode 100644
index 0000000..2febbd2
--- /dev/null
+++ b/python/armstrong-numbers/.exercism/config.json
@@ -0,0 +1,27 @@
+{
+ "authors": [
+ "pheanex"
+ ],
+ "contributors": [
+ "BethanyG",
+ "cmccandless",
+ "Dog",
+ "K4cePhoenix",
+ "sukovanej",
+ "tqa236"
+ ],
+ "files": {
+ "solution": [
+ "armstrong_numbers.py"
+ ],
+ "test": [
+ "armstrong_numbers_test.py"
+ ],
+ "example": [
+ ".meta/example.py"
+ ]
+ },
+ "blurb": "Determine if a number is an Armstrong number.",
+ "source": "Wikipedia",
+ "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
+}
diff --git a/python/armstrong-numbers/.exercism/metadata.json b/python/armstrong-numbers/.exercism/metadata.json
new file mode 100644
index 0000000..d2febfc
--- /dev/null
+++ b/python/armstrong-numbers/.exercism/metadata.json
@@ -0,0 +1 @@
+{"track":"python","exercise":"armstrong-numbers","id":"2a80ef9a5a4d4cd3ab33146185340837","url":"https://exercism.org/tracks/python/exercises/armstrong-numbers","handle":"DanielSiepmann","is_requester":true,"auto_approve":false}
\ No newline at end of file
diff --git a/python/armstrong-numbers/HELP.md b/python/armstrong-numbers/HELP.md
new file mode 100644
index 0000000..a28a778
--- /dev/null
+++ b/python/armstrong-numbers/HELP.md
@@ -0,0 +1,130 @@
+# Help
+
+## Running the tests
+
+We use [pytest][pytest: Getting Started Guide] as our website test runner.
+You will need to install `pytest` on your development machine if you want to run tests for the Python track locally.
+You should also install the following `pytest` plugins:
+
+- [pytest-cache][pytest-cache]
+- [pytest-subtests][pytest-subtests]
+
+Extended information can be found in our website [Python testing guide][Python track tests page].
+
+
+### Running Tests
+
+To run the included tests, navigate to the folder where the exercise is stored using `cd` in your terminal (_replace `{exercise-folder-location}` below with your path_).
+Test files usually end in `_test.py`, and are the same tests that run on the website when a solution is uploaded.
+
+Linux/MacOS
+```bash
+$ cd {path/to/exercise-folder-location}
+```
+
+Windows
+```powershell
+PS C:\Users\foobar> cd {path\to\exercise-folder-location}
+```
+
+
+
+Next, run the `pytest` command in your terminal, replacing `{exercise_test.py}` with the name of the test file:
+
+Linux/MacOS
+```bash
+$ python3 -m pytest -o markers=task {exercise_test.py}
+==================== 7 passed in 0.08s ====================
+```
+
+Windows
+```powershell
+PS C:\Users\foobar> py -m pytest -o markers=task {exercise_test.py}
+==================== 7 passed in 0.08s ====================
+```
+
+
+### Common options
+- `-o` : override default `pytest.ini` (_you can use this to avoid marker warnings_)
+- `-v` : enable verbose output.
+- `-x` : stop running tests on first failure.
+- `--ff` : run failures from previous test before running other test cases.
+
+For additional options, use `python3 -m pytest -h` or `py -m pytest -h`.
+
+
+### Fixing warnings
+
+If you do not use `pytest -o markers=task` when invoking `pytest`, you might receive a `PytestUnknownMarkWarning` for tests that use our new syntax:
+
+```bash
+PytestUnknownMarkWarning: Unknown pytest.mark.task - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
+```
+
+To avoid typing `pytest -o markers=task` for every test you run, you can use a `pytest.ini` configuration file.
+We have made one that can be downloaded from the top level of the Python track directory: [pytest.ini][pytest.ini].
+
+You can also create your own `pytest.ini` file with the following content:
+
+```ini
+[pytest]
+markers =
+ task: A concept exercise task.
+```
+
+Placing the `pytest.ini` file in the _root_ or _working_ directory for your Python track exercises will register the marks and stop the warnings.
+More information on pytest marks can be found in the `pytest` documentation on [marking test functions][pytest: marking test functions with attributes] and the `pytest` documentation on [working with custom markers][pytest: working with custom markers].
+
+Information on customizing pytest configurations can be found in the `pytest` documentation on [configuration file formats][pytest: configuration file formats].
+
+
+### Extending your IDE or Code Editor
+
+Many IDEs and code editors have built-in support for using `pytest` and other code quality tools.
+Some community-sourced options can be found on our [Python track tools page][Python track tools page].
+
+[Pytest: Getting Started Guide]: https://docs.pytest.org/en/latest/getting-started.html
+[Python track tools page]: https://exercism.org/docs/tracks/python/tools
+[Python track tests page]: https://exercism.org/docs/tracks/python/tests
+[pytest-cache]:http://pythonhosted.org/pytest-cache/
+[pytest-subtests]:https://github.com/pytest-dev/pytest-subtests
+[pytest.ini]: https://github.com/exercism/python/blob/main/pytest.ini
+[pytest: configuration file formats]: https://docs.pytest.org/en/6.2.x/customize.html#configuration-file-formats
+[pytest: marking test functions with attributes]: https://docs.pytest.org/en/6.2.x/mark.html#raising-errors-on-unknown-marks
+[pytest: working with custom markers]: https://docs.pytest.org/en/6.2.x/example/markers.html#working-with-custom-markers
+
+## Submitting your solution
+
+You can submit your solution using the `exercism submit armstrong_numbers.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)
+- The [Python track's programming category on the forum](https://forum.exercism.org/c/programming/python)
+- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
+- 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.
+- [The Exercism Community on Discord](https://exercism.org/r/discord)
+- [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community.
+- [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners.
+- [#python on Libera.chat](https://www.python.org/community/irc/) this is where the core developers for the language hang out and get work done.
+- [Python Community Forums](https://discuss.python.org/)
+- [Free Code Camp Community Forums](https://forum.freecodecamp.org/)
+- [CodeNewbie Community Help Tag](https://community.codenewbie.org/t/help)
+- [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.
\ No newline at end of file
diff --git a/python/armstrong-numbers/README.md b/python/armstrong-numbers/README.md
new file mode 100644
index 0000000..fe5f76b
--- /dev/null
+++ b/python/armstrong-numbers/README.md
@@ -0,0 +1,38 @@
+# Armstrong Numbers
+
+Welcome to Armstrong Numbers on Exercism's Python Track.
+If you need help running the tests or submitting your code, check out `HELP.md`.
+
+## Instructions
+
+An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits.
+
+For example:
+
+- 9 is an Armstrong number, because `9 = 9^1 = 9`
+- 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1`
+- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
+- 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`
+
+Write some code to determine whether a number is an Armstrong number.
+
+[armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number
+
+## Source
+
+### Created by
+
+- @pheanex
+
+### Contributed to by
+
+- @BethanyG
+- @cmccandless
+- @Dog
+- @K4cePhoenix
+- @sukovanej
+- @tqa236
+
+### Based on
+
+Wikipedia - https://en.wikipedia.org/wiki/Narcissistic_number
\ No newline at end of file
diff --git a/python/armstrong-numbers/armstrong_numbers.py b/python/armstrong-numbers/armstrong_numbers.py
new file mode 100644
index 0000000..b8829fa
--- /dev/null
+++ b/python/armstrong-numbers/armstrong_numbers.py
@@ -0,0 +1,2 @@
+def is_armstrong_number(number):
+ pass
diff --git a/python/armstrong-numbers/armstrong_numbers_test.py b/python/armstrong-numbers/armstrong_numbers_test.py
new file mode 100644
index 0000000..4024766
--- /dev/null
+++ b/python/armstrong-numbers/armstrong_numbers_test.py
@@ -0,0 +1,38 @@
+# These tests are auto-generated with test data from:
+# https://github.com/exercism/problem-specifications/tree/main/exercises/armstrong-numbers/canonical-data.json
+# File last updated on 2023-07-20
+
+import unittest
+
+from armstrong_numbers import (
+ is_armstrong_number,
+)
+
+
+class ArmstrongNumbersTest(unittest.TestCase):
+ def test_zero_is_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(0), True)
+
+ def test_single_digit_numbers_are_armstrong_numbers(self):
+ self.assertIs(is_armstrong_number(5), True)
+
+ def test_there_are_no_two_digit_armstrong_numbers(self):
+ self.assertIs(is_armstrong_number(10), False)
+
+ def test_three_digit_number_that_is_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(153), True)
+
+ def test_three_digit_number_that_is_not_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(100), False)
+
+ def test_four_digit_number_that_is_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(9474), True)
+
+ def test_four_digit_number_that_is_not_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(9475), False)
+
+ def test_seven_digit_number_that_is_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(9926315), True)
+
+ def test_seven_digit_number_that_is_not_an_armstrong_number(self):
+ self.assertIs(is_armstrong_number(9926314), False)
diff --git a/python/collatz-conjecture/.exercism/config.json b/python/collatz-conjecture/.exercism/config.json
new file mode 100644
index 0000000..e5eda73
--- /dev/null
+++ b/python/collatz-conjecture/.exercism/config.json
@@ -0,0 +1,31 @@
+{
+ "authors": [
+ "zwaltman"
+ ],
+ "contributors": [
+ "BethanyG",
+ "cmccandless",
+ "Dog",
+ "ikhadykin",
+ "K4cePhoenix",
+ "N-Parsons",
+ "smt923",
+ "Stigjb",
+ "thomasjpfan",
+ "tqa236"
+ ],
+ "files": {
+ "solution": [
+ "collatz_conjecture.py"
+ ],
+ "test": [
+ "collatz_conjecture_test.py"
+ ],
+ "example": [
+ ".meta/example.py"
+ ]
+ },
+ "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.",
+ "source": "An unsolved problem in mathematics named after mathematician Lothar Collatz",
+ "source_url": "https://en.wikipedia.org/wiki/3x_%2B_1_problem"
+}
diff --git a/python/collatz-conjecture/.exercism/metadata.json b/python/collatz-conjecture/.exercism/metadata.json
new file mode 100644
index 0000000..f023976
--- /dev/null
+++ b/python/collatz-conjecture/.exercism/metadata.json
@@ -0,0 +1 @@
+{"track":"python","exercise":"collatz-conjecture","id":"8dd5b1da6ffe48fd84ebb215294b5945","url":"https://exercism.org/tracks/python/exercises/collatz-conjecture","handle":"DanielSiepmann","is_requester":true,"auto_approve":false}
\ No newline at end of file
diff --git a/python/collatz-conjecture/HELP.md b/python/collatz-conjecture/HELP.md
new file mode 100644
index 0000000..6b9b083
--- /dev/null
+++ b/python/collatz-conjecture/HELP.md
@@ -0,0 +1,130 @@
+# Help
+
+## Running the tests
+
+We use [pytest][pytest: Getting Started Guide] as our website test runner.
+You will need to install `pytest` on your development machine if you want to run tests for the Python track locally.
+You should also install the following `pytest` plugins:
+
+- [pytest-cache][pytest-cache]
+- [pytest-subtests][pytest-subtests]
+
+Extended information can be found in our website [Python testing guide][Python track tests page].
+
+
+### Running Tests
+
+To run the included tests, navigate to the folder where the exercise is stored using `cd` in your terminal (_replace `{exercise-folder-location}` below with your path_).
+Test files usually end in `_test.py`, and are the same tests that run on the website when a solution is uploaded.
+
+Linux/MacOS
+```bash
+$ cd {path/to/exercise-folder-location}
+```
+
+Windows
+```powershell
+PS C:\Users\foobar> cd {path\to\exercise-folder-location}
+```
+
+
+
+Next, run the `pytest` command in your terminal, replacing `{exercise_test.py}` with the name of the test file:
+
+Linux/MacOS
+```bash
+$ python3 -m pytest -o markers=task {exercise_test.py}
+==================== 7 passed in 0.08s ====================
+```
+
+Windows
+```powershell
+PS C:\Users\foobar> py -m pytest -o markers=task {exercise_test.py}
+==================== 7 passed in 0.08s ====================
+```
+
+
+### Common options
+- `-o` : override default `pytest.ini` (_you can use this to avoid marker warnings_)
+- `-v` : enable verbose output.
+- `-x` : stop running tests on first failure.
+- `--ff` : run failures from previous test before running other test cases.
+
+For additional options, use `python3 -m pytest -h` or `py -m pytest -h`.
+
+
+### Fixing warnings
+
+If you do not use `pytest -o markers=task` when invoking `pytest`, you might receive a `PytestUnknownMarkWarning` for tests that use our new syntax:
+
+```bash
+PytestUnknownMarkWarning: Unknown pytest.mark.task - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
+```
+
+To avoid typing `pytest -o markers=task` for every test you run, you can use a `pytest.ini` configuration file.
+We have made one that can be downloaded from the top level of the Python track directory: [pytest.ini][pytest.ini].
+
+You can also create your own `pytest.ini` file with the following content:
+
+```ini
+[pytest]
+markers =
+ task: A concept exercise task.
+```
+
+Placing the `pytest.ini` file in the _root_ or _working_ directory for your Python track exercises will register the marks and stop the warnings.
+More information on pytest marks can be found in the `pytest` documentation on [marking test functions][pytest: marking test functions with attributes] and the `pytest` documentation on [working with custom markers][pytest: working with custom markers].
+
+Information on customizing pytest configurations can be found in the `pytest` documentation on [configuration file formats][pytest: configuration file formats].
+
+
+### Extending your IDE or Code Editor
+
+Many IDEs and code editors have built-in support for using `pytest` and other code quality tools.
+Some community-sourced options can be found on our [Python track tools page][Python track tools page].
+
+[Pytest: Getting Started Guide]: https://docs.pytest.org/en/latest/getting-started.html
+[Python track tools page]: https://exercism.org/docs/tracks/python/tools
+[Python track tests page]: https://exercism.org/docs/tracks/python/tests
+[pytest-cache]:http://pythonhosted.org/pytest-cache/
+[pytest-subtests]:https://github.com/pytest-dev/pytest-subtests
+[pytest.ini]: https://github.com/exercism/python/blob/main/pytest.ini
+[pytest: configuration file formats]: https://docs.pytest.org/en/6.2.x/customize.html#configuration-file-formats
+[pytest: marking test functions with attributes]: https://docs.pytest.org/en/6.2.x/mark.html#raising-errors-on-unknown-marks
+[pytest: working with custom markers]: https://docs.pytest.org/en/6.2.x/example/markers.html#working-with-custom-markers
+
+## Submitting your solution
+
+You can submit your solution using the `exercism submit collatz_conjecture.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)
+- The [Python track's programming category on the forum](https://forum.exercism.org/c/programming/python)
+- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
+- 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.
+- [The Exercism Community on Discord](https://exercism.org/r/discord)
+- [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community.
+- [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners.
+- [#python on Libera.chat](https://www.python.org/community/irc/) this is where the core developers for the language hang out and get work done.
+- [Python Community Forums](https://discuss.python.org/)
+- [Free Code Camp Community Forums](https://forum.freecodecamp.org/)
+- [CodeNewbie Community Help Tag](https://community.codenewbie.org/t/help)
+- [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.
\ No newline at end of file
diff --git a/python/collatz-conjecture/README.md b/python/collatz-conjecture/README.md
new file mode 100644
index 0000000..a56e02b
--- /dev/null
+++ b/python/collatz-conjecture/README.md
@@ -0,0 +1,70 @@
+# Collatz Conjecture
+
+Welcome to Collatz Conjecture on Exercism's Python Track.
+If you need help running the tests or submitting your code, check out `HELP.md`.
+
+## Instructions
+
+The Collatz Conjecture or 3x+1 problem can be summarized as follows:
+
+Take any positive integer n.
+If n is even, divide n by 2 to get n / 2.
+If n is odd, multiply n by 3 and add 1 to get 3n + 1.
+Repeat the process indefinitely.
+The conjecture states that no matter which number you start with, you will always reach 1 eventually.
+
+Given a number n, return the number of steps required to reach 1.
+
+## Examples
+
+Starting with n = 12, the steps would be as follows:
+
+0. 12
+1. 6
+2. 3
+3. 10
+4. 5
+5. 16
+6. 8
+7. 4
+8. 2
+9. 1
+
+Resulting in 9 steps.
+So for input n = 12, the return value would be 9.
+
+## Exception messages
+
+Sometimes it is necessary to [raise an exception](https://docs.python.org/3/tutorial/errors.html#raising-exceptions). When you do this, you should always include a **meaningful error message** to indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. For situations where you know that the error source will be a certain type, you can choose to raise one of the [built in error types](https://docs.python.org/3/library/exceptions.html#base-classes), but should still include a meaningful message.
+
+The Collatz Conjecture is only concerned with **strictly positive integers**, so this exercise expects you to use the [raise statement](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement) and "throw" a `ValueError` in your solution if the given value is zero or a negative integer. The tests will only pass if you both `raise` the `exception` and include a message with it.
+
+To raise a `ValueError` with a message, write the message as an argument to the `exception` type:
+
+```python
+# example when argument is zero or a negative integer
+raise ValueError("Only positive integers are allowed")
+```
+
+## Source
+
+### Created by
+
+- @zwaltman
+
+### Contributed to by
+
+- @BethanyG
+- @cmccandless
+- @Dog
+- @ikhadykin
+- @K4cePhoenix
+- @N-Parsons
+- @smt923
+- @Stigjb
+- @thomasjpfan
+- @tqa236
+
+### Based on
+
+An unsolved problem in mathematics named after mathematician Lothar Collatz - https://en.wikipedia.org/wiki/3x_%2B_1_problem
\ No newline at end of file
diff --git a/python/collatz-conjecture/collatz_conjecture.py b/python/collatz-conjecture/collatz_conjecture.py
new file mode 100644
index 0000000..1740424
--- /dev/null
+++ b/python/collatz-conjecture/collatz_conjecture.py
@@ -0,0 +1,2 @@
+def steps(number):
+ pass
diff --git a/python/collatz-conjecture/collatz_conjecture_test.py b/python/collatz-conjecture/collatz_conjecture_test.py
new file mode 100644
index 0000000..306e3db
--- /dev/null
+++ b/python/collatz-conjecture/collatz_conjecture_test.py
@@ -0,0 +1,35 @@
+# These tests are auto-generated with test data from:
+# https://github.com/exercism/problem-specifications/tree/main/exercises/collatz-conjecture/canonical-data.json
+# File last updated on 2023-07-20
+
+import unittest
+
+from collatz_conjecture import (
+ steps,
+)
+
+
+class CollatzConjectureTest(unittest.TestCase):
+ def test_zero_steps_for_one(self):
+ self.assertEqual(steps(1), 0)
+
+ def test_divide_if_even(self):
+ self.assertEqual(steps(16), 4)
+
+ def test_even_and_odd_steps(self):
+ self.assertEqual(steps(12), 9)
+
+ def test_large_number_of_even_and_odd_steps(self):
+ self.assertEqual(steps(1000000), 152)
+
+ def test_zero_is_an_error(self):
+ with self.assertRaises(ValueError) as err:
+ steps(0)
+ self.assertEqual(type(err.exception), ValueError)
+ self.assertEqual(err.exception.args[0], "Only positive integers are allowed")
+
+ def test_negative_value_is_an_error(self):
+ with self.assertRaises(ValueError) as err:
+ steps(-15)
+ self.assertEqual(type(err.exception), ValueError)
+ self.assertEqual(err.exception.args[0], "Only positive integers are allowed")
diff --git a/python/grains/.exercism/config.json b/python/grains/.exercism/config.json
new file mode 100644
index 0000000..4e59df7
--- /dev/null
+++ b/python/grains/.exercism/config.json
@@ -0,0 +1,34 @@
+{
+ "authors": [],
+ "contributors": [
+ "behrtam",
+ "BethanyG",
+ "cmccandless",
+ "denislooby",
+ "Dog",
+ "kytrinyx",
+ "lowks",
+ "MojitoMonday",
+ "N-Parsons",
+ "pheanex",
+ "sdublish",
+ "sjakobi",
+ "smalley",
+ "tqa236",
+ "yawpitch"
+ ],
+ "files": {
+ "solution": [
+ "grains.py"
+ ],
+ "test": [
+ "grains_test.py"
+ ],
+ "example": [
+ ".meta/example.py"
+ ]
+ },
+ "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.",
+ "source": "The CodeRanch Cattle Drive, Assignment 6",
+ "source_url": "https://coderanch.com/wiki/718824/Grains"
+}
diff --git a/python/grains/.exercism/metadata.json b/python/grains/.exercism/metadata.json
new file mode 100644
index 0000000..52523d8
--- /dev/null
+++ b/python/grains/.exercism/metadata.json
@@ -0,0 +1 @@
+{"track":"python","exercise":"grains","id":"11361381ca01412ab4218ec24ada6139","url":"https://exercism.org/tracks/python/exercises/grains","handle":"DanielSiepmann","is_requester":true,"auto_approve":false}
\ No newline at end of file
diff --git a/python/grains/HELP.md b/python/grains/HELP.md
new file mode 100644
index 0000000..1be6a85
--- /dev/null
+++ b/python/grains/HELP.md
@@ -0,0 +1,130 @@
+# Help
+
+## Running the tests
+
+We use [pytest][pytest: Getting Started Guide] as our website test runner.
+You will need to install `pytest` on your development machine if you want to run tests for the Python track locally.
+You should also install the following `pytest` plugins:
+
+- [pytest-cache][pytest-cache]
+- [pytest-subtests][pytest-subtests]
+
+Extended information can be found in our website [Python testing guide][Python track tests page].
+
+
+### Running Tests
+
+To run the included tests, navigate to the folder where the exercise is stored using `cd` in your terminal (_replace `{exercise-folder-location}` below with your path_).
+Test files usually end in `_test.py`, and are the same tests that run on the website when a solution is uploaded.
+
+Linux/MacOS
+```bash
+$ cd {path/to/exercise-folder-location}
+```
+
+Windows
+```powershell
+PS C:\Users\foobar> cd {path\to\exercise-folder-location}
+```
+
+
+
+Next, run the `pytest` command in your terminal, replacing `{exercise_test.py}` with the name of the test file:
+
+Linux/MacOS
+```bash
+$ python3 -m pytest -o markers=task {exercise_test.py}
+==================== 7 passed in 0.08s ====================
+```
+
+Windows
+```powershell
+PS C:\Users\foobar> py -m pytest -o markers=task {exercise_test.py}
+==================== 7 passed in 0.08s ====================
+```
+
+
+### Common options
+- `-o` : override default `pytest.ini` (_you can use this to avoid marker warnings_)
+- `-v` : enable verbose output.
+- `-x` : stop running tests on first failure.
+- `--ff` : run failures from previous test before running other test cases.
+
+For additional options, use `python3 -m pytest -h` or `py -m pytest -h`.
+
+
+### Fixing warnings
+
+If you do not use `pytest -o markers=task` when invoking `pytest`, you might receive a `PytestUnknownMarkWarning` for tests that use our new syntax:
+
+```bash
+PytestUnknownMarkWarning: Unknown pytest.mark.task - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
+```
+
+To avoid typing `pytest -o markers=task` for every test you run, you can use a `pytest.ini` configuration file.
+We have made one that can be downloaded from the top level of the Python track directory: [pytest.ini][pytest.ini].
+
+You can also create your own `pytest.ini` file with the following content:
+
+```ini
+[pytest]
+markers =
+ task: A concept exercise task.
+```
+
+Placing the `pytest.ini` file in the _root_ or _working_ directory for your Python track exercises will register the marks and stop the warnings.
+More information on pytest marks can be found in the `pytest` documentation on [marking test functions][pytest: marking test functions with attributes] and the `pytest` documentation on [working with custom markers][pytest: working with custom markers].
+
+Information on customizing pytest configurations can be found in the `pytest` documentation on [configuration file formats][pytest: configuration file formats].
+
+
+### Extending your IDE or Code Editor
+
+Many IDEs and code editors have built-in support for using `pytest` and other code quality tools.
+Some community-sourced options can be found on our [Python track tools page][Python track tools page].
+
+[Pytest: Getting Started Guide]: https://docs.pytest.org/en/latest/getting-started.html
+[Python track tools page]: https://exercism.org/docs/tracks/python/tools
+[Python track tests page]: https://exercism.org/docs/tracks/python/tests
+[pytest-cache]:http://pythonhosted.org/pytest-cache/
+[pytest-subtests]:https://github.com/pytest-dev/pytest-subtests
+[pytest.ini]: https://github.com/exercism/python/blob/main/pytest.ini
+[pytest: configuration file formats]: https://docs.pytest.org/en/6.2.x/customize.html#configuration-file-formats
+[pytest: marking test functions with attributes]: https://docs.pytest.org/en/6.2.x/mark.html#raising-errors-on-unknown-marks
+[pytest: working with custom markers]: https://docs.pytest.org/en/6.2.x/example/markers.html#working-with-custom-markers
+
+## Submitting your solution
+
+You can submit your solution using the `exercism submit grains.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)
+- The [Python track's programming category on the forum](https://forum.exercism.org/c/programming/python)
+- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
+- 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.
+- [The Exercism Community on Discord](https://exercism.org/r/discord)
+- [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community.
+- [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners.
+- [#python on Libera.chat](https://www.python.org/community/irc/) this is where the core developers for the language hang out and get work done.
+- [Python Community Forums](https://discuss.python.org/)
+- [Free Code Camp Community Forums](https://forum.freecodecamp.org/)
+- [CodeNewbie Community Help Tag](https://community.codenewbie.org/t/help)
+- [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.
\ No newline at end of file
diff --git a/python/grains/README.md b/python/grains/README.md
new file mode 100644
index 0000000..9f30d0a
--- /dev/null
+++ b/python/grains/README.md
@@ -0,0 +1,57 @@
+# Grains
+
+Welcome to Grains on Exercism's Python Track.
+If you need help running the tests or submitting your code, check out `HELP.md`.
+
+## Instructions
+
+Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.
+
+There once was a wise servant who saved the life of a prince.
+The king promised to pay whatever the servant could dream up.
+Knowing that the king loved chess, the servant told the king he would like to have grains of wheat.
+One grain on the first square of a chess board, with the number of grains doubling on each successive square.
+
+There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on).
+
+Write code that shows:
+
+- how many grains were on a given square, and
+- the total number of grains on the chessboard
+
+## Exception messages
+
+Sometimes it is necessary to [raise an exception](https://docs.python.org/3/tutorial/errors.html#raising-exceptions). When you do this, you should always include a **meaningful error message** to indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. For situations where you know that the error source will be a certain type, you can choose to raise one of the [built in error types](https://docs.python.org/3/library/exceptions.html#base-classes), but should still include a meaningful message.
+
+This particular exercise requires that you use the [raise statement](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement) to "throw" a `ValueError` when the square input is out of range. The tests will only pass if you both `raise` the `exception` and include a message with it.
+
+To raise a `ValueError` with a message, write the message as an argument to the `exception` type:
+
+```python
+# when the square value is not in the acceptable range
+raise ValueError("square must be between 1 and 64")
+```
+
+## Source
+
+### Contributed to by
+
+- @behrtam
+- @BethanyG
+- @cmccandless
+- @denislooby
+- @Dog
+- @kytrinyx
+- @lowks
+- @MojitoMonday
+- @N-Parsons
+- @pheanex
+- @sdublish
+- @sjakobi
+- @smalley
+- @tqa236
+- @yawpitch
+
+### Based on
+
+The CodeRanch Cattle Drive, Assignment 6 - https://coderanch.com/wiki/718824/Grains
\ No newline at end of file
diff --git a/python/grains/grains.py b/python/grains/grains.py
new file mode 100644
index 0000000..16854a7
--- /dev/null
+++ b/python/grains/grains.py
@@ -0,0 +1,6 @@
+def square(number):
+ pass
+
+
+def total():
+ pass
diff --git a/python/grains/grains_test.py b/python/grains/grains_test.py
new file mode 100644
index 0000000..177f91f
--- /dev/null
+++ b/python/grains/grains_test.py
@@ -0,0 +1,54 @@
+# These tests are auto-generated with test data from:
+# https://github.com/exercism/problem-specifications/tree/main/exercises/grains/canonical-data.json
+# File last updated on 2023-09-27
+
+import unittest
+
+from grains import (
+ square,
+ total,
+)
+
+
+class GrainsTest(unittest.TestCase):
+ def test_grains_on_square_1(self):
+ self.assertEqual(square(1), 1)
+
+ def test_grains_on_square_2(self):
+ self.assertEqual(square(2), 2)
+
+ def test_grains_on_square_3(self):
+ self.assertEqual(square(3), 4)
+
+ def test_grains_on_square_4(self):
+ self.assertEqual(square(4), 8)
+
+ def test_grains_on_square_16(self):
+ self.assertEqual(square(16), 32768)
+
+ def test_grains_on_square_32(self):
+ self.assertEqual(square(32), 2147483648)
+
+ def test_grains_on_square_64(self):
+ self.assertEqual(square(64), 9223372036854775808)
+
+ def test_square_0_is_invalid(self):
+ with self.assertRaises(ValueError) as err:
+ square(0)
+ self.assertEqual(type(err.exception), ValueError)
+ self.assertEqual(err.exception.args[0], "square must be between 1 and 64")
+
+ def test_negative_square_is_invalid(self):
+ with self.assertRaises(ValueError) as err:
+ square(-1)
+ self.assertEqual(type(err.exception), ValueError)
+ self.assertEqual(err.exception.args[0], "square must be between 1 and 64")
+
+ def test_square_greater_than_64_is_invalid(self):
+ with self.assertRaises(ValueError) as err:
+ square(65)
+ self.assertEqual(type(err.exception), ValueError)
+ self.assertEqual(err.exception.args[0], "square must be between 1 and 64")
+
+ def test_returns_the_total_number_of_grains_on_the_board(self):
+ self.assertEqual(total(), 18446744073709551615)