trackler 2.2.1.52 → 2.2.1.53

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/leap/canonical-data.json +2 -2
  4. data/tracks/cfml/tasks/FormatConfig.cfc +6 -4
  5. data/tracks/cfml/tasks/GenerateReadme.cfc +197 -0
  6. data/tracks/cfml/tasks/ScaffoldExercise.cfc +6 -0
  7. data/tracks/csharp/config.json +1 -1
  8. data/tracks/delphi/exercises/leap/uLeapTests.pas +1 -1
  9. data/tracks/fsharp/exercises/clock/Clock.fs +1 -1
  10. data/tracks/fsharp/exercises/clock/ClockTest.fs +239 -61
  11. data/tracks/fsharp/exercises/clock/Example.fs +3 -3
  12. data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +29 -26
  13. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProductTest.fs +30 -15
  14. data/tracks/fsharp/exercises/leap/LeapTest.fs +2 -2
  15. data/tracks/fsharp/exercises/rectangles/Example.fs +1 -1
  16. data/tracks/fsharp/exercises/rectangles/Rectangles.fs +1 -1
  17. data/tracks/fsharp/exercises/rectangles/RectanglesTest.fs +66 -43
  18. data/tracks/fsharp/generators/Generators.fs +85 -1
  19. data/tracks/java/scripts/canonical_data_check.sh +8 -0
  20. data/tracks/kotlin/.gitignore +1 -0
  21. data/tracks/kotlin/exercises/acronym/.meta/version +1 -0
  22. data/tracks/kotlin/exercises/acronym/src/test/kotlin/AcronymTest.kt +9 -10
  23. data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -1
  24. data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +20 -20
  25. data/tracks/kotlin/exercises/allergies/.meta/version +1 -0
  26. data/tracks/kotlin/exercises/allergies/src/test/kotlin/AllergiesTest.kt +19 -72
  27. data/tracks/kotlin/exercises/anagram/.meta/src/reference/kotlin/Anagram.kt +7 -4
  28. data/tracks/kotlin/exercises/anagram/.meta/version +1 -0
  29. data/tracks/kotlin/exercises/anagram/src/test/kotlin/AnagramTest.kt +76 -29
  30. data/tracks/kotlin/exercises/atbash-cipher/.meta/version +1 -0
  31. data/tracks/kotlin/exercises/atbash-cipher/src/test/kotlin/AtbashTest.kt +6 -3
  32. data/tracks/kotlin/exercises/beer-song/.meta/version +1 -0
  33. data/tracks/kotlin/exercises/beer-song/src/test/kotlin/BeerSongTest.kt +21 -46
  34. data/tracks/kotlin/exercises/binary-search/.meta/version +1 -0
  35. data/tracks/kotlin/exercises/binary-search/src/test/kotlin/BinarySearchTest.kt +30 -19
  36. data/tracks/kotlin/exercises/bob/.meta/src/reference/kotlin/Bob.kt +8 -7
  37. data/tracks/kotlin/exercises/bob/.meta/version +1 -0
  38. data/tracks/kotlin/exercises/bob/src/test/kotlin/BobTest.kt +57 -15
  39. data/tracks/kotlin/exercises/bracket-push/.meta/version +1 -0
  40. data/tracks/kotlin/exercises/bracket-push/src/test/kotlin/BracketPushTest.kt +3 -1
  41. data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -1
  42. data/tracks/kotlin/exercises/difference-of-squares/.meta/version +1 -0
  43. data/tracks/kotlin/exercises/difference-of-squares/src/test/kotlin/SquaresTest.kt +10 -23
  44. data/tracks/kotlin/exercises/etl/.meta/src/reference/kotlin/ETL.kt +7 -1
  45. data/tracks/kotlin/exercises/etl/.meta/version +1 -0
  46. data/tracks/kotlin/exercises/etl/src/test/kotlin/ETLTest.kt +10 -10
  47. data/tracks/kotlin/exercises/flatten-array/.meta/version +1 -0
  48. data/tracks/kotlin/exercises/flatten-array/src/test/kotlin/FlattenerTest.kt +8 -16
  49. data/tracks/kotlin/exercises/gigasecond/.meta/version +1 -0
  50. data/tracks/kotlin/exercises/gigasecond/src/test/kotlin/GigasecondTest.kt +1 -1
  51. data/tracks/kotlin/exercises/hamming/.meta/src/reference/kotlin/Hamming.kt +1 -1
  52. data/tracks/kotlin/exercises/hamming/.meta/version +1 -1
  53. data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +4 -4
  54. data/tracks/kotlin/exercises/hello-world/.meta/version +1 -0
  55. data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +1 -1
  56. data/tracks/kotlin/exercises/isogram/.meta/version +1 -0
  57. data/tracks/kotlin/exercises/isogram/src/test/kotlin/IsogramTest.kt +5 -8
  58. data/tracks/kotlin/exercises/largest-series-product/.meta/src/reference/kotlin/Series.kt +2 -3
  59. data/tracks/kotlin/exercises/largest-series-product/.meta/version +1 -0
  60. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesTest.kt +97 -0
  61. data/tracks/kotlin/exercises/leap/.meta/version +1 -0
  62. data/tracks/kotlin/exercises/leap/src/test/kotlin/LeapTest.kt +8 -26
  63. data/tracks/kotlin/exercises/list-ops/.meta/version +1 -1
  64. data/tracks/kotlin/exercises/luhn/.meta/version +1 -0
  65. data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +0 -3
  66. data/tracks/kotlin/exercises/nth-prime/.meta/version +1 -0
  67. data/tracks/kotlin/exercises/nth-prime/src/test/kotlin/PrimeTest.kt +0 -2
  68. data/tracks/kotlin/exercises/nucleotide-count/.meta/src/reference/kotlin/{DNA.kt → Dna.kt} +3 -8
  69. data/tracks/kotlin/exercises/nucleotide-count/.meta/version +1 -0
  70. data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/DnaTest.kt +48 -0
  71. data/tracks/kotlin/exercises/pangram/.meta/src/reference/kotlin/{Pangrams.kt → Pangram.kt} +1 -1
  72. data/tracks/kotlin/exercises/pangram/.meta/version +1 -1
  73. data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +15 -9
  74. data/tracks/kotlin/exercises/pascals-triangle/.meta/version +1 -0
  75. data/tracks/kotlin/exercises/pascals-triangle/src/test/kotlin/PascalsTriangleTest.kt +32 -14
  76. data/tracks/kotlin/exercises/perfect-numbers/.meta/src/reference/kotlin/NaturalNumber.kt +1 -1
  77. data/tracks/kotlin/exercises/perfect-numbers/.meta/version +1 -0
  78. data/tracks/kotlin/exercises/perfect-numbers/src/test/kotlin/{PerfectNumbersTest.kt → NaturalNumberTest.kt} +25 -7
  79. data/tracks/kotlin/exercises/phone-number/.meta/src/reference/kotlin/PhoneNumber.kt +15 -7
  80. data/tracks/kotlin/exercises/phone-number/.meta/version +1 -0
  81. data/tracks/kotlin/exercises/phone-number/src/test/kotlin/PhoneNumberTest.kt +46 -29
  82. data/tracks/kotlin/exercises/pig-latin/.meta/src/reference/kotlin/PigLatin.kt +2 -2
  83. data/tracks/kotlin/exercises/pig-latin/.meta/version +1 -0
  84. data/tracks/kotlin/exercises/pig-latin/src/test/kotlin/PigLatinTest.kt +21 -10
  85. data/tracks/kotlin/exercises/raindrops/.meta/version +1 -0
  86. data/tracks/kotlin/exercises/raindrops/src/test/kotlin/RaindropsTest.kt +19 -26
  87. data/tracks/kotlin/exercises/react/.meta/version +1 -0
  88. data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +11 -4
  89. data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -1
  90. data/tracks/kotlin/exercises/roman-numerals/.meta/version +1 -0
  91. data/tracks/kotlin/exercises/roman-numerals/src/test/kotlin/RomanNumeralTest.kt +1 -2
  92. data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -1
  93. data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +7 -7
  94. data/tracks/kotlin/exercises/scrabble-score/.meta/src/reference/kotlin/{Scrabble.kt → ScrabbleScore.kt} +1 -1
  95. data/tracks/kotlin/exercises/scrabble-score/.meta/version +1 -0
  96. data/tracks/kotlin/exercises/scrabble-score/src/test/kotlin/ScrabbleScoreTest.kt +9 -7
  97. data/tracks/kotlin/exercises/sieve/.meta/version +1 -0
  98. data/tracks/kotlin/exercises/sieve/src/test/kotlin/SieveTest.kt +8 -0
  99. data/tracks/kotlin/exercises/space-age/.meta/version +1 -0
  100. data/tracks/kotlin/exercises/space-age/src/test/kotlin/SpaceAgeTest.kt +1 -16
  101. data/tracks/kotlin/exercises/sum-of-multiples/.meta/version +1 -0
  102. data/tracks/kotlin/exercises/sum-of-multiples/src/test/kotlin/SumOfMultiplesTest.kt +7 -7
  103. data/tracks/kotlin/exercises/triangle/.meta/version +1 -0
  104. data/tracks/kotlin/exercises/two-fer/.meta/version +1 -0
  105. data/tracks/kotlin/exercises/two-fer/src/test/kotlin/TwoferTest.kt +0 -1
  106. data/tracks/kotlin/exercises/word-count/.meta/src/reference/kotlin/WordCount.kt +6 -2
  107. data/tracks/kotlin/exercises/word-count/.meta/version +1 -0
  108. data/tracks/kotlin/exercises/word-count/src/test/kotlin/WordCountTest.kt +31 -9
  109. data/tracks/kotlin/scripts/canonical_data_check.sh +8 -0
  110. data/tracks/perl6/exercises/leap/leap.t +2 -2
  111. data/tracks/php/config.json +16 -0
  112. data/tracks/php/exercises/crypto-square/crypto-square_test.php +50 -0
  113. data/tracks/php/exercises/crypto-square/example.php +32 -0
  114. data/tracks/php/exercises/meetup/README.md +21 -0
  115. data/tracks/php/exercises/meetup/example.php +19 -0
  116. data/tracks/php/exercises/meetup/meetup_test.php +577 -0
  117. data/tracks/python/README.md +7 -5
  118. data/tracks/python/config.json +36 -27
  119. data/tracks/python/docs/TESTS.md +36 -12
  120. data/tracks/python/exercises/complex-numbers/complex_numbers_test.py +1 -1
  121. data/tracks/python/exercises/diffie-hellman/.meta/hints.md +16 -0
  122. data/tracks/python/exercises/diffie-hellman/README.md +15 -2
  123. data/tracks/python/exercises/error-handling/README.md +23 -0
  124. data/tracks/python/exercises/error-handling/error_handling.py +14 -0
  125. data/tracks/python/exercises/error-handling/error_handling_test.py +66 -0
  126. data/tracks/python/exercises/error-handling/example.py +21 -0
  127. data/tracks/python/exercises/forth/forth_test.py +1 -1
  128. data/tracks/python/exercises/isogram/isogram_test.py +5 -3
  129. data/tracks/python/exercises/leap/leap_test.py +2 -2
  130. data/tracks/python/exercises/rotational-cipher/rotational_cipher_test.py +4 -4
  131. data/tracks/python/exercises/simple-cipher/.meta/hints.md +16 -0
  132. data/tracks/python/exercises/simple-cipher/README.md +17 -0
  133. data/tracks/python/exercises/sum-of-multiples/sum_of_multiples_test.py +4 -1
  134. data/tracks/python/exercises/twelve-days/example.py +3 -3
  135. data/tracks/python/exercises/twelve-days/twelve_days.py +2 -2
  136. metadata +53 -9
  137. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesInvalidInputTest.kt +0 -30
  138. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesValidInputTest.kt +0 -34
  139. data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/NucleotideTest.kt +0 -87
@@ -19,10 +19,12 @@ A list of missing exercise can be found here: http://exercism.io/languages/pytho
19
19
 
20
20
  ### Conventions
21
21
 
22
- - We use minimalistic stub files for all exercises (#272).
22
+ - We use minimalistic stub files for all exercises ([#272](https://github.com/exercism/python/issues/272)).
23
23
  - We use `unittest` (Python Standard Library) and no 3rd-party-framework.
24
- - We use the parameter order `self.assertEqual(actual, expected)` (#440).
25
- - We use context managers (`with self.assertRaises(\<exception type\>):`) for testing for exceptions (#477).
24
+ - We use the parameter order `self.assertEqual(actual, expected)` ([#440](https://github.com/exercism/python/issues/440)).
25
+ - We use context managers (`with self.assertRaises(\<exception type\>):`) for testing for exceptions ([#477](https://github.com/exercism/python/issues/477)).
26
+ - We use `assertIs(actual, True)` and `assertIs(actual, False)` rather than `assertTrue(actual)` or `assertFalse(actual)` ([#419](https://github.com/exercism/python/pull/419)).
27
+ - We use a comment string in the test file to reference the version of the exercise's `canonical-data.json` that tests were adapted from (wording can be found in: [#784](https://github.com/exercism/python/issues/784)).
26
28
 
27
29
 
28
30
  ### Testing
@@ -56,12 +58,12 @@ It will automatically check the code style, the problem configuration, and run t
56
58
 
57
59
  ## Pull Requests
58
60
 
59
- We :heart: pull requests!
61
+ We :heart: pull requests!
60
62
  We even :sparkling_heart: them if they contain well written commit messages!
61
63
 
62
64
  Please write the first line of your commit message in the following style:
63
65
 
64
- ```exercise-name: Change some things```
66
+ ```exercise-name: Change some things```
65
67
 
66
68
  Please try to follow the [The seven rules of a great Git commit message](https://chris.beams.io/posts/git-commit/#seven-rules) like to capitalize the subject line and use the imperative mood. If there are more details to add, put those into the body of the commit message.
67
69
 
@@ -9,9 +9,9 @@
9
9
  "unlocked_by": null,
10
10
  "difficulty": 1,
11
11
  "topics": [
12
- "control-flow (if-else statements)",
13
- "optional values",
14
- "text formatting"
12
+ "conditionals",
13
+ "optional_values",
14
+ "text_formatting"
15
15
  ]
16
16
  },
17
17
  {
@@ -21,7 +21,7 @@
21
21
  "unlocked_by": null,
22
22
  "difficulty": 1,
23
23
  "topics": [
24
- "control-flow (if-else statements)",
24
+ "conditionals",
25
25
  "booleans",
26
26
  "logic"
27
27
  ]
@@ -46,8 +46,8 @@
46
46
  "unlocked_by": null,
47
47
  "difficulty": 1,
48
48
  "topics": [
49
- "control-flow (loops)",
50
- "control-flow (if-else statements)",
49
+ "loops",
50
+ "conditionals",
51
51
  "strings",
52
52
  "algorithms",
53
53
  "filtering",
@@ -61,8 +61,8 @@
61
61
  "unlocked_by": null,
62
62
  "difficulty": 1,
63
63
  "topics": [
64
- "control-flow (if-else statements)",
65
- "control-flow (loops)",
64
+ "conditionals",
65
+ "loops",
66
66
  "maps",
67
67
  "strings",
68
68
  "logic",
@@ -76,8 +76,8 @@
76
76
  "unlocked_by": null,
77
77
  "difficulty": 1,
78
78
  "topics": [
79
- "control-flow (if-else statements)",
80
- "control-flow (loops)",
79
+ "conditionals",
80
+ "loops",
81
81
  "sequences",
82
82
  "sets",
83
83
  "strings",
@@ -96,8 +96,8 @@
96
96
  "strings",
97
97
  "algorithms",
98
98
  "logic",
99
- "pattern recognition",
100
- "text formatting"
99
+ "pattern_recognition",
100
+ "text_formatting"
101
101
  ]
102
102
  },
103
103
  {
@@ -158,7 +158,7 @@
158
158
  "topics": [
159
159
  "strings",
160
160
  "logic",
161
- "control-flow (loops)"
161
+ "loops"
162
162
  ]
163
163
  },
164
164
  {
@@ -479,8 +479,7 @@
479
479
  "topics": [
480
480
  "lists",
481
481
  "searching",
482
- "loops",
483
- "iteration"
482
+ "loops"
484
483
  ]
485
484
  },
486
485
  {
@@ -672,7 +671,7 @@
672
671
  "topics": [
673
672
  "lists",
674
673
  "parsing",
675
- "transformation",
674
+ "transforming",
676
675
  "loops",
677
676
  "games"
678
677
  ]
@@ -908,7 +907,7 @@
908
907
  "time",
909
908
  "mathematics",
910
909
  "logic",
911
- "text formatting"
910
+ "text_formatting"
912
911
  ]
913
912
  },
914
913
  {
@@ -919,7 +918,7 @@
919
918
  "difficulty": 4,
920
919
  "topics": [
921
920
  "files",
922
- "text formatting",
921
+ "text_formatting",
923
922
  "searching"
924
923
  ]
925
924
  },
@@ -967,7 +966,7 @@
967
966
  "difficulty": 3,
968
967
  "topics": [
969
968
  "strings",
970
- "pattern matching"
969
+ "pattern_matching"
971
970
  ]
972
971
  },
973
972
  {
@@ -978,7 +977,7 @@
978
977
  "difficulty": 3,
979
978
  "topics": [
980
979
  "strings",
981
- "pattern matching"
980
+ "pattern_matching"
982
981
  ]
983
982
  },
984
983
  {
@@ -988,9 +987,9 @@
988
987
  "unlocked_by": null,
989
988
  "difficulty": 4,
990
989
  "topics": [
991
- "Control-flow (loops)",
992
- "Arrays",
993
- "Algorithms"
990
+ "loops",
991
+ "arrays",
992
+ "algorithms"
994
993
  ]
995
994
  },
996
995
  {
@@ -1000,9 +999,9 @@
1000
999
  "unlocked_by": null,
1001
1000
  "difficulty": 1,
1002
1001
  "topics": [
1003
- "control-flow (if-else statements)",
1004
- "optional values",
1005
- "text formatting"
1002
+ "conditionals",
1003
+ "optional_values",
1004
+ "text_formatting"
1006
1005
  ]
1007
1006
  },
1008
1007
  {
@@ -1012,7 +1011,7 @@
1012
1011
  "unlocked_by": null,
1013
1012
  "difficulty": 1,
1014
1013
  "topics": [
1015
- "control-flow (loops)"
1014
+ "loops"
1016
1015
  ]
1017
1016
  },
1018
1017
  {
@@ -1089,6 +1088,16 @@
1089
1088
  "trees"
1090
1089
  ]
1091
1090
  },
1091
+ {
1092
+ "uuid": "3a2a947a-01b3-1e80-e32b-de1756fd88365adf12e",
1093
+ "slug": "error-handling",
1094
+ "core": false,
1095
+ "unlocked_by": null,
1096
+ "difficulty": 3,
1097
+ "topics": [
1098
+ "exception_handling"
1099
+ ]
1100
+ },
1092
1101
  {
1093
1102
  "uuid": "e7351e8e-d3ff-4621-b818-cd55cf05bffd",
1094
1103
  "slug": "accumulate",
@@ -4,14 +4,38 @@ We recommend you install [pytest](http://pytest.org/latest/) and
4
4
  [pytest-cache](http://pythonhosted.org/pytest-cache/). `pytest` is a testing
5
5
  tool that will give you more flexibility over running your unit tests.
6
6
 
7
+ If you want to install `pytest` for Python 2, then use `pip`.
8
+
7
9
  ```bash
8
10
  pip install pytest pytest-cache
9
11
  ```
12
+ If you instead want the version of `pytest` for Python 3, then use `pip3`.
13
+
14
+ ```bash
15
+ pip3 install pytest pytest-cache
16
+ ```
10
17
 
11
18
  If you get a `command not found` response from your system, you can find a
12
19
  tutorial on how to install `pip`
13
20
  [here](https://pip.pypa.io/en/stable/installing/).
14
21
 
22
+ **Note:** Whichever version of `pytest` you install last will be the default one used whenever `pytest` is executed, regardless of whether you have installed both versions.
23
+
24
+ If you want to check what the default version of `pytest` being used is, run the following:
25
+
26
+ ```bash
27
+ pytest --version
28
+ ```
29
+
30
+ If you have either version of `pytest` installed and you want to specifically run one of the versions, you can run that version by using `python` with the `-m` flag.
31
+
32
+ For example, you could run the Python 3 version of pytest like so:
33
+
34
+ ```bash
35
+ $ python3 -m pytest --version
36
+ This is pytest version 3.2.3, imported from /usr/local/lib/python3.5/dist-packages/pytest.py
37
+ ```
38
+
15
39
  If you choose not to install `pytest`, you can still run tests individually and
16
40
  skip the rest of this tutorial:
17
41
 
@@ -29,7 +53,7 @@ an example here), place yourself in the directory where that exercise has been
29
53
  fetched and run:
30
54
 
31
55
  ```bash
32
- py.test bob_test.py
56
+ pytest bob_test.py
33
57
  ```
34
58
 
35
59
  **Note:** To run the tests you need to pass the name of the testsuite file to
@@ -56,7 +80,7 @@ The above will run all the tests, whether they fail or not. If you'd rather stop
56
80
  the process and exit on the first failure, run:
57
81
 
58
82
  ```bash
59
- py.test -x bob_test.py
83
+ pytest -x bob_test.py
60
84
  ```
61
85
 
62
86
  ### Failed Tests First
@@ -64,14 +88,14 @@ py.test -x bob_test.py
64
88
  `pytest-cache` remembers which tests failed, and can run those tests first.
65
89
 
66
90
  ```bash
67
- py.test --ff bob_test.py
91
+ pytest --ff bob_test.py
68
92
  ```
69
93
 
70
94
  ### Running All Tests for All Exercises
71
95
 
72
96
  ```bash
73
97
  cd exercism/python/
74
- py.test
98
+ pytest
75
99
  ```
76
100
 
77
101
  ## Recommended Workflow
@@ -80,7 +104,7 @@ We recommend you run this command while working on exercises.
80
104
 
81
105
  ```bash
82
106
  cd exercism/python/bob
83
- py.test -x --ff bob_test.py
107
+ pytest -x --ff bob_test.py
84
108
  ```
85
109
 
86
110
  ## PDB
@@ -89,28 +113,28 @@ Will drop you into the python debugger when a test fails. To learn how to use
89
113
  pdb, check out the
90
114
  [documentation](https://docs.python.org/3/library/pdb.html#debugger-commands).
91
115
 
92
- You may also be interested in watching [Clayton Parker's "So you think you can
93
- pdb?" PyCon 2015 talk](https://www.youtube.com/watch?v=P0pIW5tJrRM)
94
-
95
116
  ```bash
96
- py.test --pdb bob_test.py
117
+ pytest --pdb bob_test.py
97
118
  ```
98
119
 
120
+ You may also be interested in watching [Clayton Parker's "So you think you can
121
+ pdb?" PyCon 2015 talk](https://www.youtube.com/watch?v=P0pIW5tJrRM).
122
+
99
123
  ## PEP8
100
124
 
101
125
  PEP8 is the [Style Guide for Python
102
126
  Code](https://www.python.org/dev/peps/pep-0008/). If you would like to test for
103
127
  compliance to the style guide, install
104
- [pytest-pep8](https://pypi.python.org/pypi/pytest-pep8)
128
+ [pytest-pep8](https://pypi.python.org/pypi/pytest-pep8).
105
129
 
106
130
  ```bash
107
131
  pip install pytest-pep8
108
132
  ```
109
133
 
110
- and add the pep8 flag to your command
134
+ Then, just add the `--pep8` flag to your command
111
135
 
112
136
  ```bash
113
- py.test --pep8 bob_test.py
137
+ pytest --pep8 bob_test.py
114
138
  ```
115
139
 
116
140
  Read the [pytest documentation](http://pytest.org/latest/contents.html#toc) and
@@ -55,7 +55,7 @@ class ComplexNumbersTest(unittest.TestCase):
55
55
  self.assertEqual(first_input.sub(second_input).real, 2)
56
56
  self.assertEqual(first_input.sub(second_input).imaginary, 0)
57
57
 
58
- def test_substract_numbers_with_real_and_imaginary_part(self):
58
+ def test_subtract_numbers_with_real_and_imaginary_part(self):
59
59
  first_input = ComplexNumber(1, 2)
60
60
  second_input = ComplexNumber(-2, -2)
61
61
  self.assertEqual(first_input.sub(second_input).real, 3)
@@ -0,0 +1,16 @@
1
+ ## Should I use random or secrets?
2
+
3
+ Python, as of version 3.6, includes two different random modules.
4
+
5
+ The module called `random` is pseudo-random, meaning it does not generate
6
+ true randomness, but follows an algorithm that simulates randomness.
7
+ Since random numbers are generated through a known algorithm, they are not truly random.
8
+
9
+ The `random` module is not correctly suited for cryptography and should not be used,
10
+ precisely because it is pseudo-random.
11
+
12
+ For this reason, in version 3.6, Python introduced the `secrets` module, which generates
13
+ cryptographically strong random numbers that provide the greater security required for cryptography.
14
+
15
+ Since this is only an exercise, `random` is fine to use, but note that **it would be
16
+ very insecure if actually used for cryptography.**
@@ -37,9 +37,22 @@ Bob calculates
37
37
  The calculations produce the same result! Alice and Bob now share
38
38
  secret s.
39
39
 
40
- ## Notes
40
+ ## Should I use random or secrets?
41
41
 
42
- Python, as of version 3.6, includes two different random modules. The module called `random` is pseudo-random, meaning it does not generate true randomness, but follows and algorithm that simulates randomness. Since random numbers are generated through a known algorithm, they are not truly random. The `random` module is not correctly suited for cryptography and should not be used, because it is pseudo-random. In version 3.6, Python introduced the `secrets` module, which generates cryptographically strong random numbers that provide the greater security required for cryptography. Since this is only an exercise, `random` is fine to use, but note that it would be very insecure if actually used for cryptography.
42
+ Python, as of version 3.6, includes two different random modules.
43
+
44
+ The module called `random` is pseudo-random, meaning it does not generate
45
+ true randomness, but follows an algorithm that simulates randomness.
46
+ Since random numbers are generated through a known algorithm, they are not truly random.
47
+
48
+ The `random` module is not correctly suited for cryptography and should not be used,
49
+ precisely because it is pseudo-random.
50
+
51
+ For this reason, in version 3.6, Python introduced the `secrets` module, which generates
52
+ cryptographically strong random numbers that provide the greater security required for cryptography.
53
+
54
+ Since this is only an exercise, `random` is fine to use, but note that **it would be
55
+ very insecure if actually used for cryptography.**
43
56
 
44
57
  ### Submitting Exercises
45
58
 
@@ -0,0 +1,23 @@
1
+ # Error Handling
2
+
3
+ Implement various kinds of error handling and resource management.
4
+
5
+ An important point of programming is how to handle errors and close
6
+ resources even if errors occur.
7
+
8
+ This exercise requires you to handle various errors. Because error handling
9
+ is rather programming language specific you'll have to refer to the tests
10
+ for your track to see what's exactly required.
11
+
12
+ ### Submitting Exercises
13
+
14
+ Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
15
+
16
+ For example, if you're submitting `bob.py` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/python/bob/bob.py`.
17
+
18
+
19
+ For more detailed information about running tests, code style and linting,
20
+ please see the [help page](http://exercism.io/languages/python).
21
+
22
+ ## Submitting Incomplete Solutions
23
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,14 @@
1
+ def handle_error_by_throwing_exception():
2
+ pass
3
+
4
+
5
+ def handle_error_by_returning_none(input_data):
6
+ pass
7
+
8
+
9
+ def handle_error_by_returning_tuple(input_data):
10
+ pass
11
+
12
+
13
+ def filelike_objects_are_closed_on_exception(filelike_object):
14
+ pass
@@ -0,0 +1,66 @@
1
+ import unittest
2
+
3
+ import error_handling as er
4
+
5
+
6
+ class FileLike(object):
7
+ def __init__(self):
8
+ self.is_open = False
9
+ self.was_open = False
10
+ self.did_something = False
11
+
12
+ def open(self):
13
+ self.was_open = False
14
+ self.is_open = True
15
+
16
+ def close(self):
17
+ self.is_open = False
18
+ self.was_open = True
19
+
20
+ def __enter__(self):
21
+ self.open()
22
+ return self
23
+
24
+ def __exit__(self, *args):
25
+ self.close()
26
+
27
+ def do_something(self):
28
+ self.did_something = True
29
+ raise Exception()
30
+
31
+
32
+ class ErrorHandlingTest(unittest.TestCase):
33
+ def test_throw_exception(self):
34
+ with self.assertRaises(Exception):
35
+ er.handle_error_by_throwing_exception()
36
+
37
+ def test_return_none(self):
38
+ self.assertEqual(er.handle_error_by_returning_none('1'), 1,
39
+ 'Result of valid input should not be None')
40
+ self.assertIsNone(er.handle_error_by_returning_none('a'),
41
+ 'Result of invalid input should be None')
42
+
43
+ def test_return_tuple(self):
44
+ successful_result, result = er.handle_error_by_returning_tuple('1')
45
+ self.assertIs(successful_result, True,
46
+ 'Valid input should be successful')
47
+ self.assertEqual(result, 1, 'Result of valid input should not be None')
48
+
49
+ failure_result, result = er.handle_error_by_returning_tuple('a')
50
+ self.assertIs(failure_result, False,
51
+ 'Invalid input should not be successful')
52
+
53
+ def test_filelike_objects_are_closed_on_exception(self):
54
+ filelike_object = FileLike()
55
+ with self.assertRaises(Exception):
56
+ er.filelike_objects_are_closed_on_exception(filelike_object)
57
+ self.assertIs(filelike_object.is_open, False,
58
+ 'filelike_object should be closed')
59
+ self.assertIs(filelike_object.was_open, True,
60
+ 'filelike_object should have been opened')
61
+ self.assertIs(filelike_object.did_something, True,
62
+ 'filelike_object should call do_something()')
63
+
64
+
65
+ if __name__ == '__main__':
66
+ unittest.main()