Решение на Телефонна любов от Виктор Боев

Обратно към всички решения

Към профила на Виктор Боев

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 30 успешни тест(а)
  • 7 неуспешни тест(а)

Код

def calculate_letter(prev_num, counter):
match(prev_num):
case 0:
return ' '
case 2:
return chr(ord('A') + counter)
case 3:
return chr(ord('D') + counter)
case 4:
return chr(ord('G') + counter)
case 5:
return chr(ord('J') + counter)
case 6:
return chr(ord('M') + counter)
case 7:
return chr(ord('P') + counter)
case 8:
return chr(ord('T') + counter)
case 9:
return chr(ord('W') + counter)
return ""
def nums_to_text(nums):
text = ""
prev_num = -2
counter = 0
for number in nums:
if number == 1:
continue
if number < -1 or number > 9:
print("Error")
return "Invalid parameters"
if prev_num == number:
counter += 1
else:
if prev_num in (7, 9):
counter %= 4
else:
counter %= 3
text += calculate_letter(prev_num, counter)
counter = 0
prev_num = number
text += calculate_letter(prev_num, counter)
return text
def text_to_nums(text):
text = text.upper()
# first letters in sections 2-9
compare_values = ord('A'), ord('D'), ord('G'), ord('J'), ord('M'), ord('P'), ord('T'), ord('W')
nums_list = []
number = 2
prev_num = -2
for letter in text:
if letter == ' ':
nums_list.append(0)
else:
for value in compare_values:
if number in (7, 9):
length = 4
else:
length = 3
counter = ord(letter) - value
if (counter < length):
if prev_num == number:
nums_list.append(-1)
while counter >= 0:
nums_list.append(number)
counter -= 1
prev_num = number
number = 2
break
number += 1
return nums_list
def nums_to_angle(nums):
nums = nums * 30
return sum(nums) % 360
def angles_to_nums(angles):
nums_list = []
for angle in angles:
angle %= 360
num = int(angle / 30)
if angle % 30 > 15:
num += 1
if num > 0 and num < 12:
nums_list.append(num)
return nums_list
def is_phone_tastic(word):
return nums_to_angle(text_to_nums(word)) % len(word) == 0

Лог от изпълнението

..F....F..E..F....F......FF..........
======================================================================
ERROR: test_empty_input (test.TestIsPhonetastic)
Test with empty input.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
ZeroDivisionError: integer division or modulo by zero

======================================================================
FAIL: test_ignoring_over_330 (test.TestAnglesToNums)
Test that angles rounded over 330 are ignored.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: Lists differ: [11] != []

First list contains 1 additional elements.
First extra element 0:
11

- [11]
+ []

======================================================================
FAIL: test_random_mixed_case (test.TestAnglesToNums)
Test with a random mixed input.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: Lists differ: [5, 1, 2, 4, 9, 11, 11, 1, 8, 10, 9] != [5, 1, 2, 4, 9, 1, 8, 0, 9]

First differing element 5:
11
1

First list contains 2 additional elements.
First extra element 9:
10

- [5, 1, 2, 4, 9, 11, 11, 1, 8, 10, 9]
?                 -   -------   -

+ [5, 1, 2, 4, 9, 1, 8, 0, 9]

======================================================================
FAIL: test_correct_mapping (test.TestNumsToAngles)
Test correct mapping for all numbers.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 0 != 300

======================================================================
FAIL: test_random_mixed_case (test.TestNumsToAngles)
Test with a random mixed input.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 90 != 150

======================================================================
FAIL: test_overflow_input (test.TestNumsToText)
Test with oveflowing number of presses.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: '\\' != 'x'
- \
+ x


======================================================================
FAIL: test_random_mixed_case (test.TestNumsToText)
Test for a random mixed case.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 'fmi rulzzf' != 'fmi rulzzz'
- fmi rulzzf
?          ^
+ fmi rulzzz
?          ^


----------------------------------------------------------------------
Ran 37 tests in 0.327s

FAILED (failures=6, errors=1)

История (2 версии и 10 коментара)

Виктор обнови решението на 01.11.2022 08:39 (преди над 1 година)

+def helper_nums_to_text(prev_num, counter) :

Името на функцията може да е по-добро. "helper" частта показва, че функцията се използва в nums_to_text. Но ако не прочета тази функция, а само мина през кода на nums_to_text, няма да имам никаква идея когато видя извикването по-долу:

result += helper_nums_to_text(prev_num, counter)

Какво прави функцията? Създава мапинг между число и буква (символ). Превежда число към символ. Определя какъв символ отговаря на числото спрямо това, колко пъти е въведено то. Все можеш да измилиш нещо, което да не кара читателя да търси имплементацията, когато види извикването, защото не знае какво точно прави функцията.

+ result = ""

result е информативно дотолкова, доколкото ти дава информация, че това ще е нещото, което ще върнеш накрая. Това обаче става ясно и от return-а. Име от сорта на char(acter) би било по-описателно.

Това е прост код, очевидно е, не е проблем, но за в бъдеще го имай предвид.

+ match(prev_num) :
+ case 0:
+ result += ' '

result += <нещо> в твоят случай на практика е същото като result = <нещо>. Във функцията няма итерация, така че result винаги ще е 1 символ. На практика би трябвало да можеш да махнеш и result = "" и пак да работи... Почти, ще трябва да сложиш един case за единицата, която би била result = "".

Определено не-критична забележка, но създава малко грешното впечатление, че result може да бъде нещо различно от празен низ или 1 буква (вкл. интервал).

+ case 2:
+ result += chr(ord('A') + counter)
+ case 3:
+ result += chr(ord('D') + counter)
+ case 4:
+ result += chr(ord('G') + counter)
+ case 5:
+ result += chr(ord('J') + counter)
+ case 6:
+ result += chr(ord('M') + counter)
+ case 7:
+ result += chr(ord('P') + counter)
+ case 8:
+ result += chr(ord('T') + counter)
+ case 9:
+ result += chr(ord('W') + counter)
+ return result
+
+def nums_to_text(nums) :
+ result = ""
+ prev_num = -2
+ counter = 0
+ for number in nums :
+ if number == 1 :
+ continue
+ if number < -1 or number > 9 :
+ print("Error")
+ return "Invalid parameters"
+ if prev_num is number :

Числа се сравняват с ==, не с is. Case in point:

x = 5
>>> y = 5
>>> x == y
True
>>> x is y
True

# Обаче!

>>> a = 3**20
>>> b = 3**20
>>> a == b
True
>>> a is b
False

В случая няма да имаш проблеми... Но само в случая, и разчита на оптимизация в Python. :)

+ counter += 1
+ else :
+ if prev_num in (7, 9) :
+ counter %= 4
+ else :
+ counter %= 3
+ result += helper_nums_to_text(prev_num, counter)
+ counter = 0
+ prev_num = number
+ result += helper_nums_to_text(prev_num, counter)
+ return result
+
+def text_to_nums(text) :
+ text = text.upper()
+ list_chars = ord('A'), ord('D'), ord('G') , ord('J') , ord('M') , ord('P') , ord('T') , ord('W')
+ result = []
+ number = 2
+ prev_num = -2
+ for letter in text :
+ if letter == ' ' :
+ result.append(0)
+ else:
+ for l in list_chars :
+ if number in (7, 9) :
+ length = 4
+ else :
+ length = 3
+ counter = ord(letter) - l
+ if (counter < length) :
+ if prev_num is number :
+ result.append(-1)
+ while counter >= 0 :
+ result.append(number)
+ counter -= 1
+ prev_num = number
+ number = 2
+ break
+ number += 1
+ return result
+
+def nums_to_angle(nums) :
+ sum = 0
+ for number in nums :
+ sum += number * 30
+ return sum % 360
+
+def angles_to_nums(angles) :
+ result = []
+ for angle in angles :
+ angle = angle % 360
+ num = int(angle / 30)
+ if angle % 30 > 15 :
+ num += 1
+ if num > 0 and num < 12:
+ result.append(num)
+ return result
+
+def is_phone_tastic(word) :
+ if nums_to_angle(text_to_nums(word)) % len(word) == 0:
+ return True
+ else:
+ return False

Ах, не очаквах толкова забележки :D. Благодаря за труда да ми върнеш обратна връзка! Без нея някои от грешките със сигурност щях да ги повтарям и нямаше да ми правят впечатление. За в бъдеще ще следя за тях.

Виктор обнови решението на 02.11.2022 09:37 (преди над 1 година)

-def helper_nums_to_text(prev_num, counter) :
- result = ""
- match(prev_num) :
+def calculate_letter(prev_num, counter):
+ match(prev_num):
case 0:
- result += ' '
+ return ' '
case 2:
- result += chr(ord('A') + counter)
+ return chr(ord('A') + counter)
case 3:
- result += chr(ord('D') + counter)
+ return chr(ord('D') + counter)
case 4:
- result += chr(ord('G') + counter)
+ return chr(ord('G') + counter)
case 5:
- result += chr(ord('J') + counter)
+ return chr(ord('J') + counter)
case 6:
- result += chr(ord('M') + counter)
+ return chr(ord('M') + counter)
case 7:
- result += chr(ord('P') + counter)
+ return chr(ord('P') + counter)
case 8:
- result += chr(ord('T') + counter)
+ return chr(ord('T') + counter)
case 9:
- result += chr(ord('W') + counter)
- return result
+ return chr(ord('W') + counter)
+ return ""
-def nums_to_text(nums) :
- result = ""
+def nums_to_text(nums):
+ text = ""
prev_num = -2
counter = 0
- for number in nums :
- if number == 1 :
+ for number in nums:
+ if number == 1:
continue
- if number < -1 or number > 9 :
+ if number < -1 or number > 9:
print("Error")
return "Invalid parameters"
- if prev_num is number :
+ if prev_num == number:
counter += 1
- else :
- if prev_num in (7, 9) :
+ else:
+ if prev_num in (7, 9):
counter %= 4
- else :
+ else:
counter %= 3
- result += helper_nums_to_text(prev_num, counter)
+ text += calculate_letter(prev_num, counter)
counter = 0
prev_num = number
- result += helper_nums_to_text(prev_num, counter)
- return result
+ text += calculate_letter(prev_num, counter)
+ return text
-def text_to_nums(text) :
+def text_to_nums(text):
text = text.upper()
- list_chars = ord('A'), ord('D'), ord('G') , ord('J') , ord('M') , ord('P') , ord('T') , ord('W')
- result = []
+
+ # first letters in sections 2-9
+ compare_values = ord('A'), ord('D'), ord('G'), ord('J'), ord('M'), ord('P'), ord('T'), ord('W')
+
+ nums_list = []
number = 2
prev_num = -2
- for letter in text :
- if letter == ' ' :
- result.append(0)
+ for letter in text:
+ if letter == ' ':
+ nums_list.append(0)
else:
- for l in list_chars :
- if number in (7, 9) :
+ for value in compare_values:
+ if number in (7, 9):
length = 4
- else :
+ else:
length = 3
- counter = ord(letter) - l
- if (counter < length) :
- if prev_num is number :
- result.append(-1)
- while counter >= 0 :
- result.append(number)
+ counter = ord(letter) - value
+ if (counter < length):
+ if prev_num == number:
+ nums_list.append(-1)
+ while counter >= 0:
+ nums_list.append(number)
counter -= 1
prev_num = number
number = 2
break
number += 1
- return result
+ return nums_list
-def nums_to_angle(nums) :
- sum = 0
- for number in nums :
- sum += number * 30
- return sum % 360
+def nums_to_angle(nums):
+ nums = nums * 30
+ return sum(nums) % 360
-def angles_to_nums(angles) :
- result = []
- for angle in angles :
- angle = angle % 360
+def angles_to_nums(angles):
+ nums_list = []
+ for angle in angles:
+ angle %= 360
num = int(angle / 30)
- if angle % 30 > 15 :
+ if angle % 30 > 15:
num += 1
if num > 0 and num < 12:
- result.append(num)
- return result
+ nums_list.append(num)
+ return nums_list
-def is_phone_tastic(word) :
- if nums_to_angle(text_to_nums(word)) % len(word) == 0:
+def is_phone_tastic(word):
- return True
+ return nums_to_angle(text_to_nums(word)) % len(word) == 0
- else:
- return False