Latest posts on Еще одна битва с ветвлениями, долой if'ы! topichttps://python.su/forum/topic/890/2007-07-05T16:31:10+03:00Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-07-05T16:31:10+03:00xonix6435<blockquote><em>j2a</em><br/>По правилам между разрядами запятые не ставятся, между рублями и копейками союза “и” не должно быть.<br/><br/>P.S. В отечественных (российских) фин.бумагах принято “одинадцать тысяч восемьдесят два рубля 72 коп”</blockquote>Возможно, но это легко поправить =)
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-07-05T13:25:28+03:00j2a6433<blockquote><em>xonix</em><br/>Ой, ребята, посмотрел на ваши решения, и понял, что самому надо написать. :-)<br/>…<br/>одинадцать тысяч, восемьдесят два рубля и семьдесят две копейки<br/>одинадцать тысяч, восемьдесят два доллара и семьдесят два цента<br/>девятьсот миллиардов, триста один миллион, восемьсот сорок одна тысяча, сто двадцать три доллара и четыреста пятьдесят два цента</blockquote>По правилам между разрядами запятые не ставятся, между рублями и копейками союза “и” не должно быть.<br/><br/>P.S. В отечественных (российских) фин.бумагах принято “одинадцать тысяч восемьдесят два рубля 72 коп”
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-27T15:10:39+03:00balu6208<blockquote><em>proDiva</em><br/>Парни, как много решений одной задачи! И у всех своя идея, выбирай любую.</blockquote>я сделал и рекурсивный вариант, но итеративный больше понравился, потому он и остался.
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-27T13:32:37+03:00proDiva6200Парни, как много решений одной задачи! И у всех своя идея, выбирай любую. Спасибо всем, что потратили свое время и представили каждый свой вариант функции. Просто супер!
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-27T08:39:08+03:00bialix6190<blockquote><em>pythonwin</em><br/><strong>xonix</strong>, у тебя какой версии питон?<br/><br/><blockquote>File “money.py”, line 69<br/> return n_2 if n_2 < 20 else n_2 % 10</blockquote>Python 2.4.4</blockquote>эта конструкция из 2.5
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-27T07:08:58+03:00pythonwin6189<strong>xonix</strong>, у тебя какой версии питон?<br/><br/><blockquote>File “money.py”, line 69<br/> return n_2 if n_2 < 20 else n_2 % 10</blockquote>Python 2.4.4
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-26T13:31:26+03:00xonix6177<blockquote><em>bialix</em><br/><blockquote><em>xonix</em><br/>Преимущества этого кода в том, что код и данные полностью раздельно, что облегчает расширение по валютам. Как видите, я без труда добавил доллары.</blockquote>даёшь гривню! :-)</blockquote>Дык, пожалуйста!!<br/>Добавьте код<br/><div class="code"><pre>N_HRIVNA = "грив"<br/>UAH = (N_HRIVNA, N_COP)<br/>ENDINGS[N_HRIVNA] = ["ен", "на", "ны", "ны", "ны"] + 30 * ["ен"]<br/>GENDER[N_HRIVNA] = SHE</pre></div>Проверяем:<br/><div class="code"><pre>print write_price(23, 75, UAH) # двадцать три гривны и семьдесят пять копеек<br/>print write_price(123456, currency=UAH) # сто двадцать три тысячи, четыреста пятьдесят шесть гривен<br/>print write_price(2007, 94, UAH) # две тысячи, семь гривен и девяносто четыре копейки</pre></div>
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-26T08:01:42+03:00balu6170Зоопарк сумм прописью ;)
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-26T07:05:50+03:00bialix6168<blockquote><em>xonix</em><br/>Преимущества этого кода в том, что код и данные полностью раздельно, что облегчает расширение по валютам. Как видите, я без труда добавил доллары.</blockquote>даёшь гривню! :-)
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-25T21:54:15+03:00xonix6160Ой, ребята, посмотрел на ваши решения, и понял, что самому надо написать. :-)<br/><div class="code"><pre># coding: cp1251<br/>from __future__ import division<br/><br/>ZERO = "ноль"<br/><br/>L_1_HE = HE = [ZERO, "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять",<br/> "одинадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", <br/> "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"]<br/> <br/>L_1_SHE = SHE = [ZERO, "одна", "две"] + L_1_HE[3:]<br/> <br/>L_10 = [ZERO, "десять", "двадцать", "тридцать", "сорок", "пятьдесят", <br/> "шестьдесят", "семьдесят", "восемьдесят", "девяносто"]<br/> <br/>L_100 = [ZERO, "сто", "двести", "триста", "четыреста", "пятьсот", <br/> "шестьсот", "семьсот", "восемьсот", "девятьсот"]<br/> <br/>N_ROUBLE = "рубл"<br/>N_COP = "копе"<br/>RUR = (N_ROUBLE, N_COP)<br/><br/>N_DOLLAR = "доллар"<br/>N_CENT = "цент"<br/>USD = (N_DOLLAR, N_CENT)<br/><br/>GENDER = {<br/> N_ROUBLE: HE,<br/> N_COP: SHE,<br/> N_DOLLAR: HE,<br/> N_CENT: HE,<br/>}<br/><br/>N_1000 = "тысяч"<br/>N_MILLION = "миллион"<br/>N_BILLION = "миллиард"<br/><br/>ENDINGS = {<br/> N_ROUBLE: ["ей", "ь", "я", "я", "я"] + 30 * ["ей"],<br/> N_COP: ["ек", "йка", "йки", "йки", "йки"] + 30 * ["ек"],<br/> N_DOLLAR: ["ов", "", "а", "а", "а"] + 30 * ["ов"],<br/> N_CENT: ["ов", "", "а", "а", "а"] + 30 * ["ов"],<br/> N_1000: ["", "а", "и", "и", "и"] + 30 * [""],<br/> N_MILLION: ["ов", "", "а", "а", "а"] + 30 * ["ов"],<br/> N_BILLION: ["ов", "", "а", "а", "а"] + 30 * ["ов"],<br/>}<br/><br/>def write_1_to_999(n, gender_digits=HE):<br/> assert n<=999<br/> <br/> if n==0:<br/> return ZERO<br/> <br/> n_100 = n // 100<br/> n_10 = n % 100 // 10 <br/> n_1 = n % 10<br/> <br/> res = []<br/> res.append(L_100[n_100])<br/> <br/> if n_10 == 1:<br/> res.append(gender_digits[10*n_10 + n_1])<br/> else:<br/> res.append(L_10[n_10])<br/> res.append(gender_digits[n_1])<br/> return " ".join([s for s in res if s != ZERO])<br/><br/>def ending_index(n):<br/> n_2 = n % 100<br/> return n_2 if n_2 < 20 else n_2 % 10<br/><br/>def form_group_name(group, n):<br/> return group + ENDINGS[group][ending_index(n)]<br/> <br/>def form_group(group, n, gender_digits=HE):<br/> return ("%s %s" % (write_1_to_999(n, gender_digits), form_group_name(group, n))) if n else ZERO<br/><br/>def write_number(n, gender_digits=HE):<br/> assert type(n) in (int, long)<br/> if n==0:<br/> return ZERO<br/> <br/> n_3 = n % 10**3<br/> n_6 = n % 10**6 // 10**3<br/> n_9 = n % 10**9 // 10**6<br/> n_12 = n % 10**12 // 10**9<br/> <br/> #print n_12, n_9, n_6, n_3<br/> res = []<br/> <br/> res.append(form_group(N_BILLION, n_12))<br/> res.append(form_group(N_MILLION, n_9))<br/> res.append(form_group(N_1000, n_6, SHE))<br/> res.append(write_1_to_999(n_3, gender_digits))<br/> <br/> return ", ".join([s for s in res if s != ZERO])<br/><br/>def write_price(n_rub, n_cop=0, currency=RUR):<br/> rub_id, cop_id = currency<br/> n = int(n_rub)<br/> res = []<br/> res.append("%s %s" % (write_number(n, GENDER[rub_id]), form_group_name(rub_id, n)))<br/> res.append(form_group(cop_id, n_cop, GENDER[cop_id]))<br/> <br/> return " и ".join([s for s in res if s != ZERO])<br/> <br/><br/>if __name__ == "__main__":<br/> print write_price(11082, 72)<br/> print write_price(11082, 72, USD)<br/> print write_price(900301841123, 452, currency=USD)<br/> print write_price(0)<br/> print write_price(103)<br/> print write_price(103, 21)<br/> print write_price(103, 21, USD)<br/> print write_price(100000000, 21, USD)<br/> print write_price(10000000000, 17, USD)<br/> print write_price(10000000017, 29, USD)</pre></div>Вывод<br/><div class="code"><pre>>c:\python25\pythonw -u "rublz_xonix.py"<br/>одинадцать тысяч, восемьдесят два рубля и семьдесят две копейки<br/>одинадцать тысяч, восемьдесят два доллара и семьдесят два цента<br/>девятьсот миллиардов, триста один миллион, восемьсот сорок одна тысяча, сто двадцать три доллара и четыреста пятьдесят два цента<br/>ноль рублей<br/>сто три рубля<br/>сто три рубля и двадцать одна копейка<br/>сто три доллара и двадцать один цент<br/>сто миллионов долларов и двадцать один цент<br/>десять миллиардов долларов и семнадцать центов<br/>десять миллиардов, семнадцать долларов и двадцать девять центов<br/>>Exit code: 0</pre></div>По-моему мой вариант самый понятный =)<br/>Преимущества этого кода в том, что код и данные полностью раздельно, что облегчает расширение по валютам. Как видите, я без труда добавил доллары. Собственно вот что я имел в виду, насчет того, как следует писать на питоне.
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-25T16:34:51+03:00alafin6158<strong>RDX</strong>, тег для python должен быть code:python
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-25T16:30:37+03:00RDX6157плиииин…. форматировние ушло….. Народ что я не так сделал при вставке кода??
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-25T16:28:13+03:00RDX6156Звеняйте не смог удержаться.<br/>Добавлю свою “какашку” в общую кучу ;)))<br/><br/>import os<br/><br/>addition = ‘надцать’<br/>letters = {\<br/>'1':,\<br/>'2':,\<br/>'3':}<br/><br/>zeros = {'3':('тысяча','тысячи','тысяч'), ‘6’:('миллион','миллиона','миллионов'), ‘9’:('миллиард','миллиарда','миллиардов')}<br/><br/>def triada_trans(trd, two=False):<br/> len_ = len(trd)<br/> res = <br/> if len_ != 1:<br/> if trd == ‘1’:<br/> if len_ == 3:<br/> res.append(letters[int(trd)])<br/> tmp_int = int(trd)<br/> t_add = ‘'<br/> if tmp_int == 2:<br/> t_add = ’е'<br/> if tmp_int == 0:<br/> res.append(letters)<br/> else:<br/> res.append(letters+t_add+addition)<br/> else:<br/> res.extend([letters[int(trd)] for x in range(len_)])<br/> if trd == ‘2’ and two == True:<br/> res = ‘две’<br/> else:<br/> if trd == ‘2’ and two == True:<br/> res = [letters[int(trd)]+'е']<br/> else:<br/> res = [letters[int(trd)]]<br/> return res<br/><br/>def descr_zeros(numb):<br/> res = <br/> len_ = len(numb) - 1<br/> keys_ = zeros.keys()<br/> keys_.sort()<br/> for i in range(len_):<br/> tmp_int = int(numb<em>)<br/> if tmp_int > 10 and tmp_int < 19:<br/> res.append(zeros[keys_])<br/> else:<br/> tmp_n = int(numb)<br/> if tmp_n == 1:<br/> res.append(zeros[keys_])<br/> elif tmp_n > 1 and tmp_n < 5:<br/> res.append(zeros[keys_])<br/> else:<br/> res.append(zeros[keys_])<br/> return res<br/><br/>def triada(num_str):<br/> res = <br/> len_ = len(num_str)<br/> keys_ = zeros.keys()<br/> keys_.sort()<br/> sign = int(filter(lambda a:int(a)>=len_, keys_))<br/> a = int(3-(sign-len_))<br/> res.append(num_str)<br/> res.extend([num_str for i in range(a,len_,3)])<br/> return res<br/><br/>def money_to_string(money, curr):<br/> res = ''<br/> two_ = False<br/> thousands = triada(money)<br/> len_ = len(thousands)<br/> tmp_int = int(thousands)<br/> if tmp_int == 1:<br/> curr += ‘ь’<br/> elif tmp_int > 1 and tmp_int < 5:<br/> curr += ‘я’<br/> else:<br/> curr += ‘ей’<br/> name_of_th = descr_zeros(thousands)<br/> for i in range(len_ - 1):<br/> if len_ - 2 == i:<br/> two_ = True<br/> else:<br/> two_ = False<br/> res += reduce(lambda a,b:a+“ ”+b, triada_trans(thousands, two_)) + ‘ ’ + name_of_th + ‘ ’<br/> res += reduce(lambda a,b:a+“ ”+b, triada_trans(thousands))+' ‘+curr<br/> return res<br/> <br/>if __name__ == ’__main__':<br/> print money_to_string('16234', ‘рубл’)<br/> print money_to_string('2765', ‘рубл’)<br/> print money_to_string('52498', ‘рубл’)<br/> print money_to_string('12152734', ‘рубл’)<br/> print<br/>сильно только не пинайте… <br/>писал давно и вот сейчас смотрю на код и непонимаю нафига сделал именно так О_о</em>
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-25T09:08:30+03:00balu6143<blockquote><em>xonix</em><br/>1) Логика программы очень запутана, и гораздо менее понятна, чем в корневом посте.</blockquote>Мне проще так, чем продраться ч-з массу if-ов, для внесения дополнительных изменений. Если можно, подробнее, что в логике не понятно?<br/><br/><blockquote><em>xonix</em><br/>2) В подтверждение<br/>Код: python:<br/><br/>res = res.replace(“один тысяча”, “одна тысяча”)<br/><br/>выглядит как хак, и вероятно показывает несовершенство реализуемого Вами алгоритма.</blockquote>Проще сделать так, чем писать еще массу if-ов. Тем более, что это исключение из правила.<br/><blockquote><em>xonix</em><br/>4) `summ` - вот это лучше не использовать, нужно использовать str, или repr. Конструкция с обратными ковычками сейчас считаются плохим тоном и будут исключены в Py3K.</blockquote>За “``” тот же самый repr. А вот, что “``” будут удалены - не знал. Спасибо, поправлю.<br/><blockquote><em>xonix</em><br/>в одну строку не следует, т.к. делает код менее читаемым, питон то не даром основан на отступах.</blockquote>Дело вкуса. Как по мне, тренарные операторы куда менее читабельные. И записывать с отступами, ИМХО, имеет смысл, если выражений в отступе больше 1-го. Тем более у меня само условие длиннее следствия. У меня вообще много рекурсии, map, lambda, filter, т.е. не самых читабельных, но очень удобных элементов. Жаль, что reduce выбросят, придется свою писать.<br/><br/><br/><blockquote><em>xonix</em><br/>Проcьба не воспринимать как наезд, а просто как дружескую критику :-)</blockquote>И не воспринимаю. Я свой код просто в копилку бросил, а его восприятие дело вкуса.
Общий :: Python для экспертов :: Еще одна битва с ветвлениями, долой if'ы!
2007-06-25T03:30:34+03:00xonix6139<strong>balu</strong>, не удержался и хочу прокомментировать, а точнее покритиковать Ваш код… Думаю, Ваш пример похож на то, как не стоит писать на питоне. По пунктам:<br/><br/>1) Логика программы очень запутана, и гораздо менее понятна, чем в корневом посте.<br/>2) В подтверждение<br/><div class="code"><pre><span class="n">res</span> <span class="o">=</span> <span class="n">res</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"один тысяча"</span><span class="p">,</span> <span class="s">"одна тысяча"</span><span class="p">)</span>
</pre></div>выглядит как хак, и вероятно показывает несовершенство реализуемого Вами алгоритма.<br/>3) именование функций и переменных вызывает недоумение<br/>4) `summ` - вот это лучше не использовать, нужно использовать str, или repr. Конструкция с обратными ковычками сейчас считаются плохим тоном и будут исключены в Py3K.<br/>5) Писать конструкции типа<br/><div class="code"><pre><span class="k">if</span> <span class="n">summ</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">==</span><span class="s">'0'</span> <span class="ow">or</span> <span class="p">(</span><span class="mi">5</span><span class="o"><=</span> <span class="nb">int</span><span class="p">(</span><span class="n">summ</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span><span class="o"><=</span><span class="mi">9</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">summ</span><span class="p">)</span><span class="o">></span> <span class="mi">1</span> <span class="ow">and</span> <span class="mi">10</span><span class="o"><=</span><span class="nb">int</span><span class="p">(</span><span class="n">summ</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:])</span><span class="o"><=</span><span class="mi">19</span><span class="p">):</span><span class="k">return</span> <span class="mi">2</span>
</pre></div>в одну строку не следует, т.к. делает код менее читаемым, питон то не даром основан на отступах.<br/><br/>Проcьба не воспринимать как наезд, а просто как дружескую критику :-)