Предизвикателства > Регекс за Дядо Коледа


Регекс за Дядо Коледа
Краен срок: 24.12.2023 09:00
Точки: 2

Коледа наближава. Дядо ви Ник, заедно с елфите си се труди да изпълни поръчките на всички послушни деца. За съжаление, мръсните ИТ-та са стандартизирали пожеланията на децата по много неприятен начин и трябва да му помогнете, използвайки любимото му нещо - регулярни изрази! ![Excuse my poor photoshop skills](/media/resources/santas.jpg) ## Задачата Напишете функция `parse_wishlist`, който приема стринг с пожелания, изглеждащ по този начин: ``` (3.14) Иван Иванов [10 г.] - Плейстейшан - Количка с дистанционо * Братче (1.94) Georgi "Jorkata" Georgiev [43] - Novo BMW (3-ka ili 5-ca) - - Vancheto ot tretiq etaj - Pleistei6an ``` Това, което трябва да извлечете от въпросният стринг е: - Коефициент на послушност, в нашият пример - 3.14, 1.94. **Винаги** стои в кръгли скоби в началото на реда. - Име на _(не)_послушника - Иван Иванов, Георги Георгиев. **Винаги** стои на някакво разстояние празни интервали след коефициентът на послушност. - Възраст - 10, 43. **Винаги** стои в квадратни скоби на някакво отстояние след името. **Може** да има или да няма г./год./години след това. А защо не и "годин**ки**". Може би и "годин**ка**", ако е само една... Схващате намека. - Желания - Плейстейшан, Количка с дистанционо, etc. Списък от желания, задължително с тире или звездичка (`-`, `*`) в началото, **винаги** стои на един или повече празни редове след гореописаният ред с коефициент на послушност, име и възраст. Празните желания се пропускат, ако има такива. ### Очакван резултат Очакваме списък от кортежи, в следната форма: ``` [(3.14, 'Иван Иванов', 10, ('Плейстейшан', 'Количка с дистанционо', 'Братче')), (1.94, 'Georgi "Jorkata" Georgiev', 43, ('Novo BMW (3-ka ili 5-ca)', 'Vancheto ot tretiq etaj', 'Pleistei6an'))] ``` ### Уговорки Отвъд гореописаните правила - нищо не ви е гарантирано. Разгледайте внимателно примера и преценете за какво трябва да се погрижите... Иначе има шанс всички да останем без подаръци! Тъй като е Коледа - ще раздаваме бонус точки на послушните деца. Колкото по-малко операции върху стринга (regex, split, etc.) използвате - толкова повече коледни звезди ще получите _(което не значи да не използвате нито един от готовите инструменти и да си напишете собствен парсър за уишлисти, тогава не сме сигурни колко послушни бихте били)_. Побързайте, Дядо Коледа трябва да тръгне да раздава подаръци не по-късно от 9:00 сутринта на 24.12!
 1import unittest
 2
 3from solution import *
 4
 5
 6class TestSanity(unittest.TestCase):
 7    """Sanity test for organize."""
 8
 9    def test_sanity(self):
10        """Ensure name exists and is callable.."""
11        self.assertTrue(callable(parse_wishlist))
12
13
14if __name__ == '__main__':
15    unittest.main()
  1import unittest
  2
  3# Thanks to this guy we need to prevent hacking. -> https://py-fmi.org/student/75
  4anti_rusalov_false = unittest.TestCase.assertFalse
  5anti_rusalov_true = unittest.TestCase.assertTrue
  6anti_rusalov_is = unittest.TestCase.assertIs
  7
  8from solution import *
  9
 10modified_example = '''(3.14) Иван Иванов [10 г.]
 11
 12 - Плейстейшан
 13 - Количка с дистанционо
 14 * Братче
 15
 16(1.94)   Georgi "Jorkata" Georgiev  [43]
 17
 18 -
 19  - Vancheto ot tretiq etaj
 20'''
 21half = '''(3.14) Иван Иванов [10 г.]
 22
 23 - Плейстейшан
 24 - Количка с дистанционо
 25 * Братче
 26
 27(1.94)   Georgi "Jorkata" Georgiev  [43]
 28
 29 -
 30  - Vancheto ot tretiq etaj
 31
 32
 33
 34(99.9534412345) На мама сладкото ангелче [3 годинки]
 35    * Най-хубавото дървено конче (размер 1.5)
 36    * Най-страхотното лего (тамън отвориха лицензиран магазин)
 37    * Хлороформ
 38    *
 39
 40
 41'''
 42full = '''(3.14) Иван Иванов [10 г.]
 43
 44 - Плейстейшан
 45 - Количка с дистанционо
 46 * Братче
 47
 48(1.94)   Georgi "Jorkata" Georgiev  [43]
 49
 50 -
 51  - Vancheto ot tretiq etaj
 52
 53( 6.9 ) Mr. D-r [ 999 ]
 54 - [Doctor stuff] Скалпел
 55 - [Doctor stuff] Мехлем за дупе
 56 - [Non-doctor stuff] Мехлем за дупе
 57
 58
 59(1) Gospodin (he/him) Mitko [12  год.]
 60
 61
 62 - 1
 63 -2
 64 - 3
 65 - 4
 66 - Malko mi pisva da go pisha toq test
 67
 68(99.9534412345) На мама сладкото ангелче [3 годинки]
 69    * Най-хубавото дървено конче (размер 1.5)
 70    * Най-страхотното лего (тамън отвориха лицензиран магазин)
 71    * Хлороформ
 72    *
 73
 74
 75'''
 76
 77
 78expected_example = [(3.14, 'Иван Иванов', 10, ('Плейстейшан', 'Количка с дистанционо', 'Братче')),
 79                    (1.94, 'Georgi "Jorkata" Georgiev', 43, ('Vancheto ot tretiq etaj', ))]
 80expected_half = [(3.14, 'Иван Иванов', 10, ('Плейстейшан', 'Количка с дистанционо', 'Братче')),
 81                 (1.94, 'Georgi "Jorkata" Georgiev', 43, ('Vancheto ot tretiq etaj', )),
 82                 (99.9534412345, 'На мама сладкото ангелче', 3, ('Най-хубавото дървено конче (размер 1.5)', 'Най-страхотното лего (тамън отвориха лицензиран магазин)', 'Хлороформ'))]
 83expected_full = [(3.14, 'Иван Иванов', 10, ('Плейстейшан', 'Количка с дистанционо', 'Братче')),
 84                 (1.94, 'Georgi "Jorkata" Georgiev', 43, ('Vancheto ot tretiq etaj', )),
 85                 (6.9, 'Mr. D-r', 999, ('[Doctor stuff] Скалпел', '[Doctor stuff] Мехлем за дупе', '[Non-doctor stuff] Мехлем за дупе')),
 86                 (1, 'Gospodin (he/him) Mitko', 12, ('1', '2', '3', '4', 'Malko mi pisva da go pisha toq test')),
 87                 (99.9534412345, 'На мама сладкото ангелче', 3, ('Най-хубавото дървено конче (размер 1.5)', 'Най-страхотното лего (тамън отвориха лицензиран магазин)', 'Хлороформ'))]
 88class TestRegex(unittest.TestCase):
 89    """Test for parse_wishlist."""
 90
 91    @classmethod
 92    def setUpClass(cls):
 93        cls.maxDiff = None
 94
 95    def test_modified_example(self):
 96        """A test similar to the example (just a lil' bit different)."""
 97        try:
 98            # Converted first, because of otherwise misleading output
 99            converted = [tuple(map(str, element[:3])) + (element[3],)
100                         for element in expected_example]
101            self.assertEqual(converted, parse_wishlist(modified_example))
102        except AssertionError:
103            self.assertEqual(expected_example, parse_wishlist(modified_example))
104
105    def test_half(self):
106        """A test without the more edgy cases."""
107        try:
108            # Converted first, because of otherwise misleading output
109            converted = [tuple(map(str, element[:3])) + (element[3],)
110                         for element in expected_example]
111            self.assertEqual(converted, parse_wishlist(modified_example))
112        except AssertionError:
113            self.assertEqual(expected_half, parse_wishlist(half))
114
115    def test_full(self):
116        """A single test to rule them all."""
117        try:
118            # Converted first, because of otherwise misleading output
119            converted = [tuple(map(str, element[:3])) + (element[3],)
120                         for element in expected_example]
121            self.assertEqual(converted, parse_wishlist(modified_example))
122        except AssertionError:
123            self.assertEqual(expected_full, parse_wishlist(full))
124
125
126if __name__ == '__main__':
127    unittest.main()
Дискусия
Виктор Бечев
27.12.2023 11:45

@Михаил - давам ти бонус точката защото са празници. Докато по принцип е забавно да има такива неща в решенията, за тестовете е неудобно - не можем на прима виста да преценим дали са адекватни, дали наистина тестват условията и т.н. И за двамата има един проблем - нарушавате първото условие - "Винаги стои в кръгли скоби в **началото** на реда." Тествате със случаи, които имат интервали преди това, което е потенциален false negative за колегите ви. Не е достатъчно, за да не ви дам звездичка, но да го имате предвид. :)
Костадин Русалов
24.12.2023 03:33

Още три теста :) ``` import unittest class WishlistTest(unittest.TestCase): def test_one_wish(self): wishlist = """ ( 80 ) John Doe [ 22 години ] - по-хубаво име 😅 - * - !!!lukanka """ self.assertEqual(parse_wishlist(wishlist), [(80, 'John Doe', 22, ('по-хубаво име 😅', '!!!lukanka'))]) def test_two_wishes(self): wishlist = """ (3.1415926536) Pitagor "Хипотенузов" :( [ 2592 години малее] - триъгълник, за да си мери ... хипотенузата * въже :) * чук и наковалня - - * (112) Мечо Пух/ [8] - burkanche med (x11) * :лъжица: """ self.assertEqual(parse_wishlist(wishlist), [ (3.1415926536, 'Pitagor "Хипотенузов" :(', 2592, ('триъгълник, за да си мери ... хипотенузата', 'въже :)', 'чук и наковалня')), (112, 'Мечо Пух/', 8, ('burkanche med (x11)', ':лъжица:')) ]) def test_dqdo_koleda(self): wishlist = """ (-1) Santa Claus [18+] * snejanka - snejanka -SNEJANKA (156.19) Snejanka [20 g.] -da e dalech ot dqdo koleda 💀 * * - pileshko s orizzz """ self.assertEqual(parse_wishlist(wishlist), [ (-1, 'Santa Claus', 18, ('snejanka', 'snejanka', 'SNEJANKA')), (156.19, 'Snejanka', 20, ('da e dalech ot dqdo koleda 💀', 'pileshko s orizzz')) ]) ```
Михаил Цанков
24.12.2023 00:36

Три теста за коледен късмет 🎄🎅🏻 ``` from [Your_File_Name] import * exec(str(__import__("codecs").decode(b'CmltcG9ydCB1bml0dGVzdAoKCgpjbGFzcyBIb19Ib19Ib19UZXN0cyh1bml0dGVzdC5UZXN0Q2Fz\nZSk6CgogICAgZGVmIHRlc3RfZGVmYXVsdChzZWxmKToKICAgICAgICBkYXRhID0gJycnKDMuMTQp\nINCY0LLQsNC9INCY0LLQsNC90L7QsiBbMTAg0LMuXQoKIC0g0J/Qu9C10LnRgdGC0LXQudGI0LDQ\nvQogLSDQmtC+0LvQuNGH0LrQsCDRgSDQtNC40YHRgtCw0L3RhtC40L7QvdC+CiAqINCR0YDQsNGC\n0YfQtQoKKDEuOTQpICAgR2VvcmdpICJKb3JrYXRhIiBHZW9yZ2lldiAgWzQzXSAKCiAtIE5vdm8g\nQk1XICgzLWthIGlsaSA1LWNhKQogLSAKICAtIFZhbmNoZXRvIG90IHRyZXRpcSBldGFqCgogLSBQ\nbGVpc3RlaTZhbicnJwoKCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV93aXNobGlzdChk\nYXRhKSwgWygzLjE0LCAn0JjQstCw0L0g0JjQstCw0L3QvtCyJywgMTAsICgn0J/Qu9C10LnRgdGC\n0LXQudGI0LDQvScsICfQmtC+0LvQuNGH0LrQsCDRgSDQtNC40YHRgtCw0L3RhtC40L7QvdC+Jywg\nJ9CR0YDQsNGC0YfQtScpKSwgKDEuOTQsICdHZW9yZ2kgIkpvcmthdGEiIEdlb3JnaWV2JywgNDMs\nICgnTm92byBCTVcgKDMta2EgaWxpIDUtY2EpJywgJ1ZhbmNoZXRvIG90IHRyZXRpcSBldGFqJywg\nJ1BsZWlzdGVpNmFuJykpXSkKICAgIAoKICAgIGRlZiB0ZXN0X3NwYWNlc3Moc2VsZik6CiAgICAg\nICAgZXhhbXBsZSA9ICcnJyggICAgMy4xNCAgICApICAgICAgICDQmNCy0LDQvSDQmNCy0LDQvdC+\n0LIgICAgICAgICBbMTAg0LMuXQoKIC0gICAgICAgIDM0NTPQn9C70LXQudGB0YLQtdC50YjQsNC9\nICAgICAgICAgICAgICAgCiAtINCa0L7Qu9C40YfQutCwINGBINC00LjRgdGC0LDQvdGG0LjQvtC9\n0L4KICog0JHRgNCw0YLRh9C1CgooICAtMS45NCkgICBHZW9yZ2kgIkpvcmthdGEiIEdlb3JnaWV2\nICBbNDNdIAoKIC0gTm92byBCTVcgKDMta2EgaWxpIDUtY2EpCiAtICAgCiAtCiAtICAgCiAgLSBW\nYW5jaGV0byBvdCB0cmV0aXEgZXRhagoKIC0gUGxlaXN0ZWk2YW4KCiAKCgogKDEuOTQgICkgICBw\nYXBhIGpvaG4gIFsgIDQzICAgICAgIGFzZHNhZnNkZnNkZnNhXSAKIAoKCgoKIC0gYWRzc2Fkc2Fk\ncyBhc2Rkc2FkcyBhc2Rhc3MgMjMzMTIzMSBzYXNkISEhIQogLSAgIAoKCiAtCgoKCgoKIC0gICBk\nc2EKCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgLSBCQEBC\nUyAKCiAtIFBsZWlzdGVpNmFuCicnJwoKCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV93\naXNobGlzdChleGFtcGxlKSwgWygzLjE0LCAn0JjQstCw0L0g0JjQstCw0L3QvtCyJywgMTAsICgn\nMzQ1M9Cf0LvQtdC50YHRgtC10LnRiNCw0L0nLCAn0JrQvtC70LjRh9C60LAg0YEg0LTQuNGB0YLQ\nsNC90YbQuNC+0L3QvicsICfQkdGA0LDRgtGH0LUnKSksICgtMS45NCwgJ0dlb3JnaSAiSm9ya2F0\nYSIgR2VvcmdpZXYnLCA0MywgKCdOb3ZvIEJNVyAoMy1rYSBpbGkgNS1jYSknLCAnVmFuY2hldG8g\nb3QgdHJldGlxIGV0YWonLCAnUGxlaXN0ZWk2YW4nKSksICgxLjk0LCAncGFwYSBqb2huJywgNDMs\nICgnYWRzc2Fkc2FkcyBhc2Rkc2FkcyBhc2Rhc3MgMjMzMTIzMSBzYXNkISEhIScsICdkc2EnLCAn\nQkBAQlMnLCAnUGxlaXN0ZWk2YW4nKSldKQoKICAgIGRlZiB0ZXN0X21pbnVzZXMoc2VsZik6CiAg\nICAgICAgZXhhbXBsZSA9ICcnJyggICAgMy4xNCAgICApICAgICAgICDQmNCy0LDQvSDQmNCy0LDQ\nvdC+0LIgICAgICAgICBbMTAg0LMuXQoKIC0gICAgICAgICEzNDUz0J/Qu9C10LnRgdGC0LXQudGI\n0LDQvSAgICAgICAgICAgICAgIAogLSDQmtC+0LvQuNGH0LrQsCDRgSDQtNC40YHRgtCw0L3RhtC4\n0L7QvdC+CiAqINCR0YDQsNGC0YfQtQoKKDEuOTQpICAgR2VvcmdpICJKb3JrYXRhIiBHZW9yZ2ll\ndiAgWzQzXSAKCiAtIE5vdm8gQk1XICgzLWthIGlsaSA1LWNhKQogLSAgIAogLQogLSAgIAogIC0g\nVmFuY2hldG8gb3QgdHJldGlxIGV0YWoKCiAtIFBsZWlzdGVpNmFuCgogCgoKICggICAgLTEuOTQg\nICkgICBwYXBhIGpvaG4gIFsgIDQzICAgICAgIGFzZHNhZnNkZnNkZnNhXSAKIAoKCgoKIC0gYWRz\nc2Fkc2FkcyBhc2Rkc2FkcyBhc2Rhc3MgMjMzMTIzMSBzYXNkISEhIQogLSAgIAoKICAgICAgICAg\nICAgICAgICAgICAgICAgIC0gCiAtIC0tLS0tLS0tLS0tLS0tLS0gLS0gLSAtIHdpc2hpbmcgZm9y\nIHNsZWVwIC0gLSAtIC0tLS0tLS0tLS0tLS0tLS0KIC0gICBkc2EKLQotCi0gICAgICAgICAgICAg\nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgLSB1dXV1dXV1IEJAQEJTIAoKIC0gKFBs\nZWlzdGVpNmFuCicnJwoKCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV93aXNobGlzdChl\neGFtcGxlKSwgWygzLjE0LCAn0JjQstCw0L0g0JjQstCw0L3QvtCyJywgMTAsICgnITM0NTPQn9C7\n0LXQudGB0YLQtdC50YjQsNC9JywgJ9Ca0L7Qu9C40YfQutCwINGBINC00LjRgdGC0LDQvdGG0LjQ\nvtC90L4nLCAn0JHRgNCw0YLRh9C1JykpLCAoMS45NCwgJ0dlb3JnaSAiSm9ya2F0YSIgR2Vvcmdp\nZXYnLCA0MywgKCdOb3ZvIEJNVyAoMy1rYSBpbGkgNS1jYSknLCAnVmFuY2hldG8gb3QgdHJldGlx\nIGV0YWonLCAnUGxlaXN0ZWk2YW4nKSksICgtMS45NCwgJ3BhcGEgam9obicsIDQzLCAoJ2Fkc3Nh\nZHNhZHMgYXNkZHNhZHMgYXNkYXNzIDIzMzEyMzEgc2FzZCEhISEnLCAnLS0tLS0tLS0tLS0tLS0t\nLSAtLSAtIC0gd2lzaGluZyBmb3Igc2xlZXAgLSAtIC0gLS0tLS0tLS0tLS0tLS0tLScsICdkc2En\nLCAndXV1dXV1dSBCQEBCUycsICcoUGxlaXN0ZWk2YW4nKSldKQo=\n', 'base_64'), 'utf-8')) ```
Виктор Бечев
22.12.2023 20:54

И за двете си абсолютно прав, мерси!
Мирослав Стояновски
22.12.2023 16:03

В условието пише, че функцията трябва да се казва parse _ wishlists, обаче не минава sanity теста. Всъщност трябва да се казва parse _ wishlist.
Мирослав Стояновски
22.12.2023 12:35

В примера мисля че сте пропуснали една затваряща скоба след кортежа от желанията на Иван Иванов, т.е. : ...'Братче'),... трябва да е ...'Братче')),...