Решение на Телефонна любов от Николай Натов

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

Към профила на Николай Натов

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 36 успешни тест(а)
  • 1 неуспешни тест(а)

Код

from math import floor
BUTTONS = {
2: "ABC",
3: "DEF",
4: "GHI",
5: "JKL",
6: "MNO",
7: "PQRS",
8: "TUV",
9: "WXYZ",
0: " ",
};
ANGLE_INCREMENT = 30
def nums_to_text(nums):
text_result = ""
current_index = 0
while current_index < len(nums):

Не съм убеден, че е лесно да приложиш точно в този код, но обикновено при нужда от елемента и индекса му, се използва enumerate:

for index, num in enumerate(nums):
    <do some stuff with index and num>

Просто си спестяваш ръчното инкрементиране на индекса и взимането на елемент с този индекс от колекцията.

# Ignore anything that is not contained in the BUTTONS dictionary
if BUTTONS.get(nums[current_index]) is None:
current_index += 1
continue
repeat_count = 1
# Loop until we find a number different from the current one
next_index = current_index + 1
while next_index < len(nums) and nums[current_index] == nums[next_index]:
repeat_count += 1
next_index += 1
# We've found a different number or reached the end so add the letter to the result
button_string = BUTTONS[nums[current_index]]
text_result += button_string[(repeat_count - 1) % len(button_string)]
current_index += repeat_count
return text_result;
def text_to_nums(text):
numbers_result = []
for letter in text:
letter = letter.upper()
repeat_count = 0
current_number = -1
for button_number, button_string in BUTTONS.items():
letter_index = button_string.find(letter)
if letter_index != -1:
current_number = button_number
repeat_count = letter_index + 1
break
# If the previously inserted number is the same as the current one, that means we need to insert -1
if len(numbers_result) > 0 and numbers_result[-1] == current_number:
numbers_result.append(-1)
numbers_result += [current_number] * repeat_count
return numbers_result;
def normalize_angle(angle):
return angle - floor(angle / 360) * 360
def round_angle(angle):
prev_multiple = floor((angle + 30) / 30) * 30 - 30
next_multiple = floor((angle + 30) / 30) * 30
if angle == (prev_multiple + next_multiple) / 2:
return floor(angle / 30) * 30
return round(angle / 30) * 30
def nums_to_angle(nums):
angle = 0
for number in nums:
if number == -1:
continue
elif number == 0:
angle += 300
else:
angle += number * ANGLE_INCREMENT
return normalize_angle(angle)
def angles_to_nums(angles):
numbers = []
for angle in angles:
final_angle = normalize_angle(round_angle(angle))
if final_angle == 330 or final_angle == 0:
continue
elif final_angle == 300:
numbers.append(0)
else:
numbers.append(int(final_angle / ANGLE_INCREMENT))
return numbers
def is_phone_tastic(word):
return nums_to_angle(text_to_nums(word)) % len(word) == 0

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

..........E..........................
======================================================================
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

----------------------------------------------------------------------
Ran 37 tests in 0.341s

FAILED (errors=1)

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

Николай обнови решението на 30.10.2022 11:49 (преди над 1 година)

+from math import floor
+
+BUTTONS = {
+ 2: "ABC",
+ 3: "DEF",
+ 4: "GHI",
+ 5: "JKL",
+ 6: "MNO",
+ 7: "PQRS",
+ 8: "TUV",
+ 9: "WXYZ",
+ 0: " ",
+};
+
+ANGLE_INCREMENT = 30
+
+def nums_to_text(nums):
+
+ text_result = ""
+ current_index = 0
+
+ while current_index < len(nums):

Не съм убеден, че е лесно да приложиш точно в този код, но обикновено при нужда от елемента и индекса му, се използва enumerate:

for index, num in enumerate(nums):
    <do some stuff with index and num>

Просто си спестяваш ръчното инкрементиране на индекса и взимането на елемент с този индекс от колекцията.

+
+ # Ignore anything that is not contained in the BUTTONS dictionary
+ if BUTTONS.get(nums[current_index]) == None:
+ current_index += 1
+ continue
+
+ repeat_count = 1
+
+ # Loop until we find a number different from the current one
+ next_index = current_index + 1
+ while next_index < len(nums) and nums[current_index] == nums[next_index]:
+ repeat_count += 1
+ next_index += 1
+
+ # We've found a different number or reached the end so add the letter to the result
+ button_string = BUTTONS[nums[current_index]]
+ text_result += button_string[(repeat_count - 1) % len(button_string)]
+
+ current_index += repeat_count
+
+ return text_result;
+
+def text_to_nums(text):
+
+ numbers_result = []
+
+ for letter in text:
+ letter = letter.upper()
+
+ repeat_count = 0
+ current_number = -1
+
+ for button_number, button_string in BUTTONS.items():
+ letter_index = button_string.find(letter)
+
+ if letter_index != -1:
+ current_number = button_number
+ repeat_count = letter_index + 1
+ break
+
+ # If the previously inserted number is the same as the current one, that means we need to insert -1
+ if len(numbers_result) > 0 and numbers_result[-1] == current_number:
+ numbers_result.append(-1)
+
+ numbers_result += [current_number] * repeat_count
+
+ return numbers_result;
+
+def normalize_angle(angle):
+ return angle - floor(angle / 360) * 360
+
+def round_angle(angle):
+ prev_multiple = floor((angle + 30) / 30) * 30 - 30
+ next_multiple = floor((angle + 30) / 30) * 30
+
+ if angle == (prev_multiple + next_multiple) / 2:
+ return floor(angle / 30) * 30
+
+ return round(angle / 30) * 30
+
+def nums_to_angle(nums):
+ angle = 0
+
+ for number in nums:
+ if number == -1:
+ continue
+ elif number == 0:
+ angle += 300
+ else:
+ angle += number * ANGLE_INCREMENT
+
+ return normalize_angle(angle)
+
+def angles_to_nums(angles):
+ numbers = []
+
+ for angle in angles:
+ final_angle = normalize_angle(round_angle(angle))
+
+ if final_angle == 330 or final_angle == 0:
+ continue
+ elif final_angle == 300:
+ numbers.append(0)
+ else:
+ numbers.append(int(final_angle / ANGLE_INCREMENT))
+
+ return numbers
+
+def is_phone_tastic(word):
+ return nums_to_angle(text_to_nums(word)) % len(word) == 0

Добро решение.

Бих обърнал внимание на празните редове. В момента имаш по един празен ред м/у всяка функция, което е напълно вярно. Имаш, обаче, доста празни редове вътре в самите функции, което прави трудно разграничаването на начало/край на дадена функция. Ако в тялото на функциите си нямаш никакви празни редове, или поне не толкова много, ще можеш с един погледн да се ориентираш в кода си.

ПП: Това, че си слагал нови редове във функциите си, не е в разрез с нито едно общоприето правило, така че е напълно валидно. Просто споделям субективно мнение, така че можеш спокойно да го игнорираш. ако не си съгласен.

При мен явно е точно обратното, защото нямам ли празни редове в тялото на функциите ми е доста трудно да проследя кода особено, ако нямам { } определящи scope-a :D. Съгласен съм обаче, че на някои места могат да се премахнат новите редове.

Николай обнови решението на 30.10.2022 15:08 (преди над 1 година)

from math import floor
BUTTONS = {
2: "ABC",
3: "DEF",
4: "GHI",
5: "JKL",
6: "MNO",
7: "PQRS",
8: "TUV",
9: "WXYZ",
0: " ",
};
ANGLE_INCREMENT = 30
def nums_to_text(nums):
-
text_result = ""
current_index = 0
while current_index < len(nums):
-
# Ignore anything that is not contained in the BUTTONS dictionary
- if BUTTONS.get(nums[current_index]) == None:
+ if BUTTONS.get(nums[current_index]) is None:
current_index += 1
continue
repeat_count = 1
# Loop until we find a number different from the current one
next_index = current_index + 1
while next_index < len(nums) and nums[current_index] == nums[next_index]:
repeat_count += 1
next_index += 1
# We've found a different number or reached the end so add the letter to the result
button_string = BUTTONS[nums[current_index]]
text_result += button_string[(repeat_count - 1) % len(button_string)]
-
current_index += repeat_count
return text_result;
def text_to_nums(text):
-
numbers_result = []
for letter in text:
letter = letter.upper()
-
repeat_count = 0
current_number = -1
for button_number, button_string in BUTTONS.items():
letter_index = button_string.find(letter)
if letter_index != -1:
current_number = button_number
repeat_count = letter_index + 1
break
# If the previously inserted number is the same as the current one, that means we need to insert -1
if len(numbers_result) > 0 and numbers_result[-1] == current_number:
numbers_result.append(-1)
numbers_result += [current_number] * repeat_count
return numbers_result;
def normalize_angle(angle):
return angle - floor(angle / 360) * 360
def round_angle(angle):
prev_multiple = floor((angle + 30) / 30) * 30 - 30
next_multiple = floor((angle + 30) / 30) * 30
if angle == (prev_multiple + next_multiple) / 2:
return floor(angle / 30) * 30
return round(angle / 30) * 30
def nums_to_angle(nums):
angle = 0
for number in nums:
if number == -1:
continue
elif number == 0:
angle += 300
else:
angle += number * ANGLE_INCREMENT
return normalize_angle(angle)
def angles_to_nums(angles):
numbers = []
for angle in angles:
final_angle = normalize_angle(round_angle(angle))
if final_angle == 330 or final_angle == 0:
continue
elif final_angle == 300:
numbers.append(0)
else:
numbers.append(int(final_angle / ANGLE_INCREMENT))
return numbers
def is_phone_tastic(word):
- return nums_to_angle(text_to_nums(word)) % len(word) == 0
+ return nums_to_angle(text_to_nums(word)) % len(word) == 0