Найти - Пользователи
Полная версия: вывод числа прописью и наоборот, вывод слова числом
Начало » Python для новичков » вывод числа прописью и наоборот, вывод слова числом
1
shiroi
Здравствуйте, есть программа которая выводит число прописью до 999999 (и то не точно на единицу в конце (выводит 142322 как стосорокдветысячитристадвадцатьтри)), как ее можно переделать, чтобы она считала до 99.999.999 и если вводятся число прописью, то переделывала его в число?
py.user.next
В 2013 году писал такую программу, правда на C дело было
[guest@localhost ~]$ ntow
Usage: ntow gender [ word0 word1 word2 ]
Try `ntow --help' for more information.
[guest@localhost ~]$
[guest@localhost ~]$ ntow --help
Usage: ntow gender [ word0 word1 word2 ]

Converts numbers to cardinal numbers, including units.
Range of numbers is [0; 10 ^ 36 - 1].

gender -- a letter m | f | n
(masculine, feminine and neuter)
word0 -- a unit for zero
word1 -- a unit for one
word2 -- a unit for two

Words may be empty.

--help -- display this help and exit
--version -- output version information and exit

[guest@localhost ~]$

[guest@localhost ~]$ echo 1 | ntow m ежей ёжик ёжика
один ёжик
[guest@localhost ~]$ echo 2 | ntow m ежей ёжик ёжика
два ёжика
[guest@localhost ~]$ echo 3 | ntow m ежей ёжик ёжика
три ёжика
[guest@localhost ~]$ echo 111222333444555666777888999 | ntow m ежей ёжик ёжика
сто одиннадцать септиллионов двести двадцать два секстиллиона триста тридцать три квинтиллиона четыреста сорок четыре квадриллиона пятьсот пятьдесят пять триллионов шестьсот шестьдесят шесть миллиардов семьсот семьдесят семь миллионов восемьсот восемьдесят восемь тысяч девятьсот девяносто девять ежей
[guest@localhost ~]$


Вот оттуда кусок, отвечающий за тройки цифр

triple.c
#include <string.h>
#include <assert.h>
#include "triple.h"

static const char *hundreds[] = {
"сто", "двести", "триста",
"четыреста", "пятьсот", "шестьсот",
"семьсот", "восемьсот", "девятьсот"
};

static const char *teens[] = {
"одиннадцать", "двенадцать", "тринадцать",
"четырнадцать", "пятнадцать", "шестнадцать",
"семнадцать", "восемнадцать", "девятнадцать"
};

static const char *tens[] = {
"десять", "двадцать", "тридцать",
"сорок", "пятьдесят", "шестьдесят",
"семьдесят", "восемьдесят", "девяносто"
};

static const char *ten[] = {
"три",
"четыре", "пять", "шесть",
"семь", "восемь", "девять"
};

static const char *one_two[][2] = {
{ "один", "два" },
{ "одна", "две" },
{ "одно", "два" }
};

static const char *zero = "ноль";

/* get_triple: запиывает в dst словесный эквивалент
трёхзначного числа num с учётом рода g */
char *get_triple(char *dst, int num, enum gender g)
{
int d1, d2, d3;
const char *w1, *w2;

assert(num / 1000 == 0 && "the number should be in range 0-999");
if (num == 0)
return strcpy(dst, zero);
switch(g) {
case G_M:
w1 = one_two[0][0];
w2 = one_two[0][1];
break;
case G_F:
w1 = one_two[1][0];
w2 = one_two[1][1];
break;
case G_N:
w1 = one_two[2][0];
w2 = one_two[2][1];
break;
default:
assert(0 && "wrong gender");
}
assert(1 <= num && num <= 999);
d1 = num % 10;
d2 = num / 10 % 10;
d3 = num / 100 % 10;
*dst = '\0';
assert(*dst == '\0' && "the string should be prepared for strcat()");
if (d3 > 0)
strcat(dst, hundreds[d3 - 1]);
if (d2 > 0) {
if (*dst)
strcat(dst, " ");
if (d2 == 1 && d1 > 0) {
strcat(dst, teens[d1 - 1]);
return dst;
} else
strcat(dst, tens[d2 - 1]);
}
if (d1 > 0) {
if (*dst)
strcat(dst, " ");
switch (d1) {
case 1:
strcat(dst, w1);
break;
case 2:
strcat(dst, w2);
break;
default:
strcat(dst, ten[d1 - 3]);
break;
}
}
assert(*dst);
return dst;
}
shiroi
py.user.next
разобрался только с неточностью на конце, с миллионами так и не выходит, ладно это пол беды, подскажи как лучше сделать вывод слова числом?(например одинмиллиондвестепятьдесятчетыретысячистосорокодин как 1254141)
JOHN_16
в свое время я спокойно загуглил решения для перевода числа в строку, обратное думаю менее востребовано и может вполне не иметь готовых общедоступных решений
py.user.next
shiroi
подскажи как лучше сделать вывод слова числом?(например одинмиллиондвестепятьдесятчетыретысячистосорокодин как 1254141)
Для фразы:
один миллион двести пятьдесят четыре тысячи сто сорок один

Надо сначала разделить всё по словам на группы. Может же быть “один миллион сто” - то есть не быть тысяч.

То есть получить
один миллион | двести пятьдесят четыре тысячи | сто сорок один

Потом это надо почистить от нецифровых слов
один | двести пятьдесят четыре | сто сорок один

А потом каждую часть передавать в функцию преобразования тройки из слов в цифры.

В итоге у тебя получится
1 | 254 | 141

Потом соединяешь.


P.S.
А для фразы:
один миллион сто

После разложения будет
один миллион | | сто

После очистки
один | | сто

После преобразования в цифры
1 | 000 | 100
Rodegast
Эти числа уже много раз обсуждали: http://python.su/forum/topic/890/
shiroi
py.user.next
это конечно дико и глупо, но можно ли использовать при переводе слова в число использовать обычный перебор? т.е вводишь число словом, и он в цикле переводит все числа от 1 до 99.999.999 и если находит совпадение то выводит?

может кто подсказать, хотел сделать как написал выше, то есть через перебирание чисел в цикле, но если беру и подставляю число из цикла в вызов функции, то мне выдает “Type ‘int’ doesn't have expected attribute ‘__len_’ ”
 if str(a):
    for i in range(1, 1000000000):
        result = convert_int(i)
        while a != result:
            number[i] += 1
    print(number)
    exit()

и сразу ругается на строчку в коде
 def convert_int(string): #преобразование
       integer = int(string)  на эту строчку
py.user.next
shiroi
это конечно дико и глупо, но можно ли использовать при переводе слова в число использовать обычный перебор?
Можно, но это неверный алгоритм, за такое двойку поставят. Почему? Потому что он вредительский, из-за него будет программа виснуть всё время. Алгоритмическая сложность O(n^2) - одна из самых плохих сложностей. И это ты увидишь на экране, когда тебе в эту функцию подадут миллион таких строчных чисел. Оно просто повиснет и всё.

Как сделать, я тебе сказал: это нужно сделать поэтапно - то есть ты должен подготовить данные, потом подготовить подготовленные данные, потом подготовить подготовленные подготовленные данные и так много раз, а потом уже у тебя получатся удобные данные, которые можно обрабатывать. Так всё программирование устроено. Ты от какой-то неопределённой хрени всё сужаешь-сужаешь-сужаешь и в итоге приходишь к простым данным, которые легко обрабатывать. Это называется борьба со сложностью.

Понимаешь, чтобы скушать пирог, надо разрезать его на кусочки, а ты пытаешься его сначала весь в рот запихнуть, потом режешь на две части и их пытаешься съесть по очереди, потом режешь их на две части и у тебя получается четыре части и они тоже не подходят, потому что слишком большие, и из-за этого всего ты думаешь, что разрезать пирог было неправильным ходом изначально, что нужно было всё-таки его целиком запихивать. Это ты просто не знаешь, как это делается.

То есть вот это число, которое у тебя введено словами, его надо сначала подготовить, его не надо обрабатывать сразу. И в этом твоя проблема - ты не понимаешь этого принципа. У тебя всё равно ничего не получится, поэтому делай это так, как это делают все. Никто не сидит, допустим, и браузер сходу не пишет, потому что это очень сложная система. Его разделяют-разделяют-разделяют и только потом там что-то начинают писать и соединять потихоньку в единую систему типа такого ветвистого трубопровода.

tags: decomposition
shiroi
py.user.next
хорошо, а как разбить строку на группы если нет разделителя?
py.user.next
shiroi
как разбить строку на группы если нет разделителя?
Разделителями являются нециферные слова вроде миллион, тысяча. Если при просмотре слева направо слова миллион нет, то там пустая секция получается. Если слова тысяча нет, то там тоже пустая секция. Если в конце там слов не остаётся, то там тоже пустая пустая секция будет.
Типа фраза “один миллион”: тысяч нет, слово один уже в миллионы попало, получается три секции “один | | ”. Дальше ты это передаёшь функции преобразования, которая сама это всё разбивает по разделителю и передаёт по кускам функции преобразования тройки цифр, которая уже на цифры даёт цифры, а на пустоты даёт тройные нули. А чтобы на цифры дать цифры, нужно уже конкретно набор цифр передать в функцию, которая только цифры может получать, не пустоты.

На псевдокоде это так выглядит
text = "один миллион"
segmented = break_to_segments(text) # -> "один миллион | | "
parts = split_to_parts(segmented) # -> ("один", "", "")
translated_parts = translate_parts(parts) # -> ("1", "000", "000")
out = concatenate_parts(translated_parts) # -> "1.000.000"
Каждую функцию потом отдельно делаешь, эти функции друг про друга не знают. Просто им что-то подаётся на вход и они должны это обработать и выдать результат на выход, больше они ничего не знают про эти данные. В этом и заключается структурное программирование - когда у тебя программа разделена на независимые части и простые три конструкции переходов между этими частями. Независимые части - это подпрограммы (в питоне - функции), а конструкции переходов - это последовательность, ветвление, цикл.
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