Уведомления

Группа в Telegram: @pythonsu

#1 Март 8, 2019 00:29:59

kedavr
Зарегистрирован: 2019-03-08
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Скрипт: конвертация числа из цыфрового формата в текстовый

Вспомнив детство и как занимался обучением программированию на паскале решил немного вспомнить это дело. Выбрав для себя python начал что то писать. воть:

 # данный скрипт предназначен для конвертирования числа в строку
# пример: 3 456  = три тысячи четыреста пятдесят шесть
# нужно представить число в виде списка с нулями вместо пустых символов
# т.е. если это "сто" тогда сохраняем так: 000100
#импорт функции удаления лишних пробелов между словами
from textoper import space_del
numbs = { 1:'один', 2:'два', 3:'три', 4:'четыре', 5:'пять',
		  6:'шесть', 7:'семь', 8:'восемь', 9:'девять', 0:'' }
		  
numbs1 = { 1:'одна', 2:'две', 3:'три', 4:'четыре', 5:'пять',
		   6:'шесть', 7:'семь', 8:'восемь', 9:'девять', 0:''  }
		  
tens1 = { 10:'десять', 11:'одинадцать', 12:'двенадцать', 
		  13:'тринадцать', 14:'четырнадцать', 15:'пятнадцать',
		  16:'шестнадцать', 17:'семнадцать', 18:'восемнадцать',
			  19:'девятнадцать' }
		  
tens = { 2:'двадцать', 3:'тридцать', 4:'сорок', 5:'пятьдесят',
		 6:'шестьдесят', 7:'семьдесят', 8:'восемьдесят',
	     9: 'девяносто', 0:''	}
		 
hundreds = { 1:'сто', 2:'двесте', 3:'триста', 4:'четыреста',
			 5:'пятсот', 6:'шестьсот', 7:'семьсот', 8:'восемьсот',
			 9:'девятьсот', 0:'' }
# функция для преобразования сотни в текстовый формат
def con(unit,explist):
	if unit[1] == '1':
		return hundreds[int(unit[0])] + " " + tens1[int(unit[1]+unit[2])]
	else:
		return (hundreds[int(unit[0])] + " " + tens[int(unit[1])] + " " 
				+ explist[int(unit[2])])
# коррективные функции для вывода 	
def thous_ending(numb):
	if numb == 1:
		return 'тысяча'
	elif numb != 1 and numb > 4 or numb == 0 :
		return 'тысяч'
	elif numb != 1 and numb < 5 :
		return 'тысячи'	
		
def mill_ending(numb):
	if numb == 1:
		return 'миллион'
	elif numb != 1 and numb > 4 or numb == 0:
		return 'миллионов'
	elif numb != 1 and numb < 5 :
		return 'миллиона'
		
def bill_ending(numb):
	if numb == 1:
		return 'миллиард'
	elif numb != 1 and numb > 4 or numb == 0:
		return 'миллиардов'
	elif numb != 1 and numb < 5 :
		return 'миллиарда'
def converter(x):
	
	num = '000000000000'
	num =list(num)
	x = list(x)
	# переносим введенное число в заготовку
	i = -1
	for k in x:
		num[i]= x[i]
		i -= 1
	
	# разделяем число на тысячи, миллионы и т.д.	
	bill  = num[0:3]
	mill  = num[3:6]
	thous = num[6:9]
	hund  = num[9:12]
	# обьединение и дополнительная корректировка	
	billions = con(bill,numbs)
	if int(bill[0]+bill[1]+bill[2]) > 0 and bill[1] != '1' :
		billions += " " + bill_ending(int(bill[2]))
	elif int(bill[0]+bill[1]+bill[2]) > 0 and bill[1] == '1' :
		billions +=' миллиардов'
	
	millions = con(mill,numbs) 
	if int(mill[0]+mill[1]+mill[2]) > 0 and mill[1] != '1' :
		millions += " " + mill_ending(int(mill[2]))
	elif int(mill[0]+mill[1]+mill[2]) > 0 and mill[1] == '1' :
		millions +=' миллионов'
	
	thousands = con(thous,numbs1)
	if int(thous[0]+thous[1]+thous[2]) > 0 and thous[1] != '1':
		thousands += " " + thous_ending(int(thous[2]))
	if int(thous[0]+thous[1]+thous[2]) > 0 and thous[1] == '1':
		thousands +=' тысяч'
	
	hundreds = con(hund,numbs)
	
	full_numb = (billions + " " + millions + " " + thousands + " " 
				 + hundreds)
	return space_del(full_numb)
	

прошу вас оценить скрипт, и может подкинуть мне задачек подобного плана

Офлайн

#2 Март 8, 2019 09:02:55

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Скрипт: конвертация числа из цыфрового формата в текстовый

Ошибки проектирования:
1) Почему функция, которая преобразует числа в текст, принимает на вход строку?
2) Принцип единичной ответственности грубо изнасилован. Смешаны логика преобразования и отображение. Почему ваша функция converter оперирует строковыми литералами “миллиардов”, “миллионов” …? У вас же выше есть специальные функции для этого.
3) Задача не решена в общем виде. Если задание изменится и понадобятся триллионы, в скольких местах вашей программы вы будете вносить изменения? А должно быть одно место, в которое вы должны добавить единственную сущность.
4) Программа не обладает важным параметром, во многом определяющем качество кода - она лишена гибкости. Попробуйте сделать её многоязычной (чтобы поддерживался ещё, например, французский язык) и вы поймете, что хардкодить ‘миллион’, “миллиарда” и пр. - плохая идея.

Ошибки питона:
1) строки не надо преобразовывать в списки
2) # переносим введенное число в заготовку - есть функция форматирования.
3) Конкатенация строк? Плохо.

Алгоритм:
1) Вы какой-то сам себе злобный Буратино, вы функцию работы с числами делаете специально строковой, а потом мучаетесь преобразованием строк в числа

 int(thous[0] + thous[1] + thous[2])
зачем это? Работайте с числами как с числами, а не как со строками
2)
 	if int(mill[0]+mill[1]+mill[2]) > 0 and mill[1] != '1' :
		millions += " " + mill_ending(int(mill[2]))
	elif int(mill[0]+mill[1]+mill[2]) > 0 and mill[1] == '1' :
		millions +=' миллионов'
Забористо! Ну, во первых, даже не придираясь к логике происходящего, вы не видите, что у вас две последующие строки повторяют друг друга? А если придираться, то почему ту не сделать else?

Дальше мне надоело мозг напрягать в праздник.
Держите маленькую подсказку
 rn = ["единиц", "десятков", "сотен", "тысяч"] + ["..."] * 10
i = 3423445345354
c = 0
while i > 1:
     rem = i % 10
     i = (i - rem) // 10
     c += 1
     print(f"{rem} {rn[c]}")



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version