From b1e27e7699b63ca2c9c846b632de96eb7bc2f812 Mon Sep 17 00:00:00 2001 From: Cacahuete Date: Mon, 21 Dec 2020 23:14:20 +0100 Subject: [PATCH] parse_ranges: first attempt with Bonus1. --- parse_ranges/parse_ranges.py | 19 ++++++++++++++ parse_ranges/test_parse_ranges.py | 42 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 parse_ranges/parse_ranges.py create mode 100644 parse_ranges/test_parse_ranges.py diff --git a/parse_ranges/parse_ranges.py b/parse_ranges/parse_ranges.py new file mode 100644 index 0000000..402cffa --- /dev/null +++ b/parse_ranges/parse_ranges.py @@ -0,0 +1,19 @@ +def parse_ranges_v1(range_string): + """This version causes a memory error for huge ranges...""" + ranges = [tuple(map(int, r.split("-"))) for r in range_string.split(",")] + result = [] + for start, stop in ranges: + result = [*result, *list(range(start, stop + 1))] + for number in result: + yield number + + +def parse_ranges_v2(range_string): + """This version seems more memory efficient.""" + ranges = [tuple(map(int, r.split("-"))) for r in range_string.split(",")] + for start, stop in ranges: + for number in range(start, stop + 1): + yield number + + +parse_ranges = parse_ranges_v2 diff --git a/parse_ranges/test_parse_ranges.py b/parse_ranges/test_parse_ranges.py new file mode 100644 index 0000000..c5bac3c --- /dev/null +++ b/parse_ranges/test_parse_ranges.py @@ -0,0 +1,42 @@ +import unittest + +from parse_ranges import parse_ranges + + +class ParseRangesTests(unittest.TestCase): + + """Tests for parse_ranges.""" + + def test_three_ranges(self): + self.assertEqual(list(parse_ranges("1-2,4-4,8-10")), [1, 2, 4, 8, 9, 10]) + + def test_with_spaces(self): + self.assertEqual( + list(parse_ranges("0-0, 4-8, 20-21, 43-45")), + [0, 4, 5, 6, 7, 8, 20, 21, 43, 44, 45], + ) + + def test_return_iterator(self): + numbers = parse_ranges("0-0, 4-8, 20-21, 43-45") + self.assertEqual(next(numbers), 0) + self.assertEqual(list(numbers), [4, 5, 6, 7, 8, 20, 21, 43, 44, 45]) + self.assertEqual(list(numbers), []) + numbers = parse_ranges("100-1000000000000") + self.assertEqual(next(numbers), 100) + + @unittest.expectedFailure + def test_with_individual_numbers(self): + self.assertEqual( + list(parse_ranges("0,4-8,20,43-45")), [0, 4, 5, 6, 7, 8, 20, 43, 44, 45] + ) + + @unittest.expectedFailure + def test_ignore_arrows(self): + self.assertEqual( + list(parse_ranges("0, 4-8, 20->exit, 43-45")), + [0, 4, 5, 6, 7, 8, 20, 43, 44, 45], + ) + + +if __name__ == "__main__": + unittest.main(verbosity=2)