Найти - Пользователи
Полная версия: Еще одна битва с ветвлениями, долой if'ы!
Начало » Python для экспертов » Еще одна битва с ветвлениями, долой if'ы!
1 2 3
balu
xonix
1) Логика программы очень запутана, и гораздо менее понятна, чем в корневом посте.
Мне проще так, чем продраться ч-з массу if-ов, для внесения дополнительных изменений. Если можно, подробнее, что в логике не понятно?

xonix
2) В подтверждение
Код: python:

res = res.replace(“один тысяча”, “одна тысяча”)

выглядит как хак, и вероятно показывает несовершенство реализуемого Вами алгоритма.
Проще сделать так, чем писать еще массу if-ов. Тем более, что это исключение из правила.
xonix
4) `summ` - вот это лучше не использовать, нужно использовать str, или repr. Конструкция с обратными ковычками сейчас считаются плохим тоном и будут исключены в Py3K.
За “``” тот же самый repr. А вот, что “``” будут удалены - не знал. Спасибо, поправлю.
xonix
в одну строку не следует, т.к. делает код менее читаемым, питон то не даром основан на отступах.
Дело вкуса. Как по мне, тренарные операторы куда менее читабельные. И записывать с отступами, ИМХО, имеет смысл, если выражений в отступе больше 1-го. Тем более у меня само условие длиннее следствия. У меня вообще много рекурсии, map, lambda, filter, т.е. не самых читабельных, но очень удобных элементов. Жаль, что reduce выбросят, придется свою писать.


xonix
Проcьба не воспринимать как наезд, а просто как дружескую критику :-)
И не воспринимаю. Я свой код просто в копилку бросил, а его восприятие дело вкуса.
RDX
Звеняйте не смог удержаться.
Добавлю свою “какашку” в общую кучу ;)))

import os

addition = ‘надцать’
letters = {\
'1':,\
'2':,\
'3':}

zeros = {'3':('тысяча','тысячи','тысяч'), ‘6’:('миллион','миллиона','миллионов'), ‘9’:('миллиард','миллиарда','миллиардов')}

def triada_trans(trd, two=False):
len_ = len(trd)
res =
if len_ != 1:
if trd == ‘1’:
if len_ == 3:
res.append(letters[int(trd)])
tmp_int = int(trd)
t_add = ‘'
if tmp_int == 2:
t_add = ’е'
if tmp_int == 0:
res.append(letters)
else:
res.append(letters+t_add+addition)
else:
res.extend([letters[int(trd)] for x in range(len_)])
if trd == ‘2’ and two == True:
res = ‘две’
else:
if trd == ‘2’ and two == True:
res = [letters[int(trd)]+'е']
else:
res = [letters[int(trd)]]
return res

def descr_zeros(numb):
res =
len_ = len(numb) - 1
keys_ = zeros.keys()
keys_.sort()
for i in range(len_):
tmp_int = int(numb)
if tmp_int > 10 and tmp_int < 19:
res.append(zeros[keys_])
else:
tmp_n = int(numb)
if tmp_n == 1:
res.append(zeros[keys_])
elif tmp_n > 1 and tmp_n < 5:
res.append(zeros[keys_])
else:
res.append(zeros[keys_])
return res

def triada(num_str):
res =
len_ = len(num_str)
keys_ = zeros.keys()
keys_.sort()
sign = int(filter(lambda a:int(a)>=len_, keys_))
a = int(3-(sign-len_))
res.append(num_str)
res.extend([num_str for i in range(a,len_,3)])
return res

def money_to_string(money, curr):
res = ''
two_ = False
thousands = triada(money)
len_ = len(thousands)
tmp_int = int(thousands)
if tmp_int == 1:
curr += ‘ь’
elif tmp_int > 1 and tmp_int < 5:
curr += ‘я’
else:
curr += ‘ей’
name_of_th = descr_zeros(thousands)
for i in range(len_ - 1):
if len_ - 2 == i:
two_ = True
else:
two_ = False
res += reduce(lambda a,b:a+“ ”+b, triada_trans(thousands, two_)) + ‘ ’ + name_of_th + ‘ ’
res += reduce(lambda a,b:a+“ ”+b, triada_trans(thousands))+' ‘+curr
return res

if __name__ == ’__main__':
print money_to_string('16234', ‘рубл’)
print money_to_string('2765', ‘рубл’)
print money_to_string('52498', ‘рубл’)
print money_to_string('12152734', ‘рубл’)
print
сильно только не пинайте…
писал давно и вот сейчас смотрю на код и непонимаю нафига сделал именно так О_о
RDX
плиииин…. форматировние ушло….. Народ что я не так сделал при вставке кода??
alafin
RDX, тег для python должен быть code:python
xonix
Ой, ребята, посмотрел на ваши решения, и понял, что самому надо написать. :-)
# coding: cp1251
from __future__ import division

ZERO = "ноль"

L_1_HE = HE = [ZERO, "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять",
"одинадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать",
"шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"]

L_1_SHE = SHE = [ZERO, "одна", "две"] + L_1_HE[3:]

L_10 = [ZERO, "десять", "двадцать", "тридцать", "сорок", "пятьдесят",
"шестьдесят", "семьдесят", "восемьдесят", "девяносто"]

L_100 = [ZERO, "сто", "двести", "триста", "четыреста", "пятьсот",
"шестьсот", "семьсот", "восемьсот", "девятьсот"]

N_ROUBLE = "рубл"
N_COP = "копе"
RUR = (N_ROUBLE, N_COP)

N_DOLLAR = "доллар"
N_CENT = "цент"
USD = (N_DOLLAR, N_CENT)

GENDER = {
N_ROUBLE: HE,
N_COP: SHE,
N_DOLLAR: HE,
N_CENT: HE,
}

N_1000 = "тысяч"
N_MILLION = "миллион"
N_BILLION = "миллиард"

ENDINGS = {
N_ROUBLE: ["ей", "ь", "я", "я", "я"] + 30 * ["ей"],
N_COP: ["ек", "йка", "йки", "йки", "йки"] + 30 * ["ек"],
N_DOLLAR: ["ов", "", "а", "а", "а"] + 30 * ["ов"],
N_CENT: ["ов", "", "а", "а", "а"] + 30 * ["ов"],
N_1000: ["", "а", "и", "и", "и"] + 30 * [""],
N_MILLION: ["ов", "", "а", "а", "а"] + 30 * ["ов"],
N_BILLION: ["ов", "", "а", "а", "а"] + 30 * ["ов"],
}

def write_1_to_999(n, gender_digits=HE):
assert n<=999

if n==0:
return ZERO

n_100 = n // 100
n_10 = n % 100 // 10
n_1 = n % 10

res = []
res.append(L_100[n_100])

if n_10 == 1:
res.append(gender_digits[10*n_10 + n_1])
else:
res.append(L_10[n_10])
res.append(gender_digits[n_1])
return " ".join([s for s in res if s != ZERO])

def ending_index(n):
n_2 = n % 100
return n_2 if n_2 < 20 else n_2 % 10

def form_group_name(group, n):
return group + ENDINGS[group][ending_index(n)]

def form_group(group, n, gender_digits=HE):
return ("%s %s" % (write_1_to_999(n, gender_digits), form_group_name(group, n))) if n else ZERO

def write_number(n, gender_digits=HE):
assert type(n) in (int, long)
if n==0:
return ZERO

n_3 = n % 10**3
n_6 = n % 10**6 // 10**3
n_9 = n % 10**9 // 10**6
n_12 = n % 10**12 // 10**9

#print n_12, n_9, n_6, n_3
res = []

res.append(form_group(N_BILLION, n_12))
res.append(form_group(N_MILLION, n_9))
res.append(form_group(N_1000, n_6, SHE))
res.append(write_1_to_999(n_3, gender_digits))

return ", ".join([s for s in res if s != ZERO])

def write_price(n_rub, n_cop=0, currency=RUR):
rub_id, cop_id = currency
n = int(n_rub)
res = []
res.append("%s %s" % (write_number(n, GENDER[rub_id]), form_group_name(rub_id, n)))
res.append(form_group(cop_id, n_cop, GENDER[cop_id]))

return " и ".join([s for s in res if s != ZERO])


if __name__ == "__main__":
print write_price(11082, 72)
print write_price(11082, 72, USD)
print write_price(900301841123, 452, currency=USD)
print write_price(0)
print write_price(103)
print write_price(103, 21)
print write_price(103, 21, USD)
print write_price(100000000, 21, USD)
print write_price(10000000000, 17, USD)
print write_price(10000000017, 29, USD)
Вывод
>c:\python25\pythonw -u "rublz_xonix.py"
одинадцать тысяч, восемьдесят два рубля и семьдесят две копейки
одинадцать тысяч, восемьдесят два доллара и семьдесят два цента
девятьсот миллиардов, триста один миллион, восемьсот сорок одна тысяча, сто двадцать три доллара и четыреста пятьдесят два цента
ноль рублей
сто три рубля
сто три рубля и двадцать одна копейка
сто три доллара и двадцать один цент
сто миллионов долларов и двадцать один цент
десять миллиардов долларов и семнадцать центов
десять миллиардов, семнадцать долларов и двадцать девять центов
>Exit code: 0
По-моему мой вариант самый понятный =)
Преимущества этого кода в том, что код и данные полностью раздельно, что облегчает расширение по валютам. Как видите, я без труда добавил доллары. Собственно вот что я имел в виду, насчет того, как следует писать на питоне.
bialix
xonix
Преимущества этого кода в том, что код и данные полностью раздельно, что облегчает расширение по валютам. Как видите, я без труда добавил доллары.
даёшь гривню! :-)
balu
Зоопарк сумм прописью ;)
xonix
bialix
xonix
Преимущества этого кода в том, что код и данные полностью раздельно, что облегчает расширение по валютам. Как видите, я без труда добавил доллары.
даёшь гривню! :-)
Дык, пожалуйста!!
Добавьте код
N_HRIVNA = "грив"
UAH = (N_HRIVNA, N_COP)
ENDINGS[N_HRIVNA] = ["ен", "на", "ны", "ны", "ны"] + 30 * ["ен"]
GENDER[N_HRIVNA] = SHE
Проверяем:
print write_price(23, 75, UAH) # двадцать три гривны и семьдесят пять копеек
print write_price(123456, currency=UAH) # сто двадцать три тысячи, четыреста пятьдесят шесть гривен
print write_price(2007, 94, UAH) # две тысячи, семь гривен и девяносто четыре копейки
pythonwin
xonix, у тебя какой версии питон?

File “money.py”, line 69
return n_2 if n_2 < 20 else n_2 % 10
Python 2.4.4
bialix
pythonwin
xonix, у тебя какой версии питон?

File “money.py”, line 69
return n_2 if n_2 < 20 else n_2 % 10
Python 2.4.4
эта конструкция из 2.5
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB