Домашни > Pitches love the D > Решения > Решението на Костадин Русалов

Резултати
10 точки от тестове
0 точки от учител

10 точки общо

36 успешни теста
1 неуспешни теста
Код

1(調 := ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')), (音程 := ('unison', 'minor 2nd', 'major 2nd', 'minor 3rd', 'major 3rd', 'perfect 4th', 'diminished 5th', 'perfect 5th', 'minor 6th', 'major 6th', 'minor 7th', 'major 7th')), ( := isinstance), (Tone := type('Tone', (), {'__init__': lambda _, t: setattr(_, 'i', 調.index(t)), '__str__': lambda _: 調[_.i], '__add__': lambda _, o: Chord(_, o) if (o, Tone) else ti(_.i + o.i) if (o, Interval) else NotImplemented, '__radd__': lambda _, o: o + _ if (o, Chord) else exec('raise TypeError(\'Invalid operation\')'), '__sub__': lambda _, o: Interval(_.i - o.i) if (o, Tone) else ti(_.i - o.i) if (o, Interval) else NotImplemented, '__rsub__': lambda _, o: exec('raise TypeError(\'Invalid operation\')')})), (ti := lambda i: Tone(調[i % len(調)])), (Interval := type('Interval', (), {'__init__': lambda _, i, d=1: (setattr(_, 'i', i % len(音程)), setattr(_, 'd', d))[1], '__str__': lambda _: 音程[_.i], '__add__': lambda _, o: Interval(_.i + o.i) if (o, Interval) else NotImplemented, '__neg__': lambda _: Interval(_.i, -_.d), 'f': lambda _: _.i * _.d})), (Ci := type('Ci', (), {'__init__': lambda _, s, t: (setattr(_, 'i', 0), setattr(_, 't', list(map(lambda x: ti(x[0] + s), filter(lambda x: x[1], enumerate(t[s:] + t[:s]))))))[0], '__next__': lambda _: exec('raise StopIteration') if _.i == len(_.t) else _.t[(_.i, setattr(_, 'i', _.i + 1))[0]]})), (Chord := type('Chord', (), {'__init__': lambda _, b, *t: exec('raise TypeError(\'Cannot have a chord made of only 1 unique tone\')') if len({b.i} | set(t_.i for t_ in t)) < 2 else (setattr(_, 'b', b.i), setattr(_, 't', [i in {b.i} | set(t_.i for t_ in t) for i in range(len(調))]))[0], '__iter__': lambda _: Ci(_.b, _.t), '__str__': lambda _: '-'.join(str(t) for t in _), 'is_minor': lambda _: _.t[(_.b + 3) % len(調)], 'is_major': lambda _: _.t[(_.b + 4) % len(調)], 'is_power_chord': lambda _: not _.is_minor() and not _.is_major(), '__add__': lambda _, o: (c := _.__copy__(), c.t.__setitem__(o.i, True))[0] if (o, Tone) else (c := _.__copy__(), setattr(c, 't', list(map(any, zip(c.t, o.t)))), c)[2] if (o, Chord) else NotImplemented, '__sub__': lambda _, o:  exec(f'raise TypeError(\'Cannot remove tone {o} from chord {_}\')') if not _.t[o.i] else (b := ti(_.b) if o.i != _.b else (i := iter(_), next(i), next(i))[2], tx := _.t.copy(), tx.__setitem__(o.i, False), Chord(b, *list(map(lambda x: ti(x[0]), filter(lambda x: x[1], enumerate(tx))))))[-1], '__copy__': lambda _: (c := Chord(Tone('A'), Tone('A#')), setattr(c, 'b', _.b) or setattr(c, 't', _.t))[0], 'transposed': lambda _, i: (c := _.__copy__(), setattr(c, 'b', c.b + i.f()) or setattr(c, 't', c.t[-i.f():] + c.t[:-i.f()]))[0]}))

...........F.........................
======================================================================
FAIL: test_interval_negative (test.TestBasicIntervalFunctionality.test_interval_negative)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 51, in test_interval_negative
self.assertEqual(str(minor_2nd), "minor 2nd")
AssertionError: 'major 7th' != 'minor 2nd'
- major 7th
+ minor 2nd

----------------------------------------------------------------------
Ran 37 tests in 0.003s

FAILED (failures=1)

Дискусия
Виктор Бечев
07.11.2024 01:03

А, да, знаех си, че имаше схема с code обектите - и преди съм го ползвал. :smile: ``` type(lambda: 0)(type((lambda: 0).__code__)(1, 0, 0, 1, 1, 67, b'|\0\202\1', (), (), ('x',), '', '', '', 1, b'', b''), {})(TypeError("String, baby!")) ``` Обяснението на горното е супер добро, утре мога да ви го преразкажа. Има и по-лесен вариант, но той не е толкова забавен... ``` (lambda: (_ for _ in ()).throw(TypeError('String, baby!')))() dir((_ for _ in ())) # [..., 'gi_frame', 'gi_running', 'gi_suspended', 'gi_yieldfrom', 'send', 'throw'] ``` Защо генератор експрешъните имат метод `throw`? Fuck if I know. :smile: П.П. Тъй де, то си пише в документацията, ама защо това е публично...?
Виктор Бечев
07.11.2024 00:36

Отвратен съм, Жорка. Евалата.
Георги Кунчев
06.11.2024 21:29

Малко фийдбек, че ми стана интересно. Да, ясно е, че да `raise`-неш изключение без `exec` е доста трудно начинание, но пък и едноредови решени с `exec` си е компромис. Реших да видя дали мога да се справя с проблема. За `StopIteration` има лесен вариант. Не знам за какво ти е, но очевидно не те интересува текста, така че... `next(iter([]))`. За `TypeError` не знам трик. Може би Виктор ще излезе с някакъв екзорсизъм, но това, което аз се сетих, е, че някъде във вградените библиотеки може да има `raise TypeError(value)`, за което да се закача. Т.е. `TypeError`, който сляпо връща подадена стойност, без да я украсява. Свалих сорс кода на Питон, потърсих и [бинго](https://github.com/python/cpython/blob/a1c57bcfd2bcbc55ff858407e09c1d8d8cee44e6/Lib/plistlib.py#L859). Вярвам, че това можеш да пренапишеш в един ред. Днес работи, утре не, но едва ли утре някой ще ти рънва тестовете пак, така че си струва единия час, който загубих да го търся и сглобя: ``` import plistlib class Dummy: def __init__(self, text): self._text = text def __str__(self): return self._text a = plistlib._BinaryPlistWriter(None, None, None) a._getrefnum = lambda *_: None a._object_offsets = {None: None} a._fp = type('', (), {'tell': lambda: None}) a._write_object(Dummy("Raising a TypeError with custom message without the raise keyword")) ```
Георги Кунчев
06.11.2024 20:45

Решението е качено след крайния срок, от мен. Точките се запазват, защото колегата Русалов вече завърши курса. Тук е, за да покаже защо (не) мразим решенията му.
История
Това решение има само една версия.