Поставил перед собой простую задачу: Сделать кредитный калькулятор, ты ему сумму кредита, период и процентную ставку, а он тебе график погашения и сумму переплаты.
Задача была разбита на 3 части
1. Получение входных данных для обработки и принятия решения
2. Вычисление платежей и процентных ставок
3. Вывод данных
---------------------------------------------------------------------
Внимание: В процессе написания скрипта я столкнулся с проблемой объявления глобальных переменных. В 3.1 появились такие директивы как global и nonlocal здесь я понял как использовать эти директивы
---------------------------------------------------------------------
Поскольку для меня сейчас интересна работа с регулярными выражениями, я не искал простых путей получения параметров командной строки, а воспользовался мощью RegExp. Возможно это и не корректно с точки зрения культуры языка, но считаю практику весьма полезной. И так получение входных параметров из командной строки.
# Строковая переменная в которой описываем все команды для скрипта Help = ''' в командной строке использоваться следующие ключи: -s исходная сумма кредита без учёта процентов -r процентная ставка по кредиту -p срок кредита если в конце слова будет стоять "y" то знаем что это год и необходимо рассчитать количество месяцев -dfc если указан данный ключ то рассчитываем по дифференциальному алгоритму иначе по аннуитентному /? Вызов данной справки ''' ''' Процедура получения входных параметров Используя регулярные выражения ''' def GetEnterData(): # nonlocal директива определяющая что использовать необходимо # переменные объявленные в теле основной процедуры nonlocal Summa #Сумма заёма nonlocal Rait # Процентная ставка nonlocal Period # Срок кредита nonlocal TypeOf # Тип указанного периода (год, месяц) nonlocal DiferCalc # Тип алгоритма расчёта # строим строку с которой запустились # такую закорючку пришлось строить из за непонимания принципов работы с командной строкой myString = '' # Командная строка for arg in sys.argv: # Для всех аргументов в командной строке myString = myString + arg + ' ' # отображаем исходные параметры # это сделано для контроля, строки которую мы получили из аргументов print(myString) # Определяем регулярное выражение reg = re.compile(r"(?:-s *(\d*))|(?:-r *(\d*))|(?:-p *(\d*)(y)?)|(\/\?)|(-dfc)") # находим все совпадения find = reg.findall(myString) # заполняем исходные данные # Поскольку результат reg.findall возвращает нам в данном случае 2х мерный массив for res in find: if (Summa == -1) and (res[0] != ''): # проверяем что бы сумма ещё не была заполнена и разобранная строка была не пустой Summa = res[0] else: if (Rait == -1) and (res[1] != ''): Rait = res[1] else: if (Period == -1) and (res[2] != ''): Period = res[2] TypeOf = (res[3] != '') # проверяем не указан ли период в годах. else: if (res[4] != '') : # проверяем не запросил ли пользователь справку print(Help) exit() else: if (res[5] != '') : # определяем алгоритмы расчёта если передан требуемый ключь DiferCalc = True ''' Конец процедуры получения исходных параметров '''
Итак ничего сложного в выше описанном коде не было. Тем ни менее я не уверен, что я правильно работаю с модулем RegExp, поскольку на мой взгляд выглядит это как то кривовато.
Итого с первой задачей я разобрался.
Теперь опишем алгоритмы расчёта кредитных выплат
def Main(): ''' Процедура возведения числа _Main в степень _Power ''' def DoPowerW(_Main, _Power): result = 1 start = 1 while start < int(_Power): result = _Main * result start = start + 1 return result ''' Конец процедуры возведения в степень -------------------------------------------------------------- Начало процедуры диференциального расчёта ''' def GetDifPayment(): # переменные определённые в основном модуле nonlocal Summa nonlocal Rait nonlocal Period # определяем переменные для внутреннего пользования Payment = 1 Total = 0 # открываем файл для записи результата ключ w отмечает что файл открыт для записи и все что было в нём до будет переписанно file = open('report.txt', 'w') # высчитываем платеж за каждый месяц while int(Payment) < int(Period) + 1: CurDuty = (int(Summa) - (int(Summa) / int(Period)) * (int(Payment) - 1)) NowToPay = (int(Summa) / int(Period)) + (((int(CurDuty) / 100) * float(Rait)) / 12) file.write("номер платежа %s;\t основной долг %s;\t Платёж %s\n" % (Payment, CurDuty, NowToPay)) Total = Total + NowToPay Payment = Payment + 1 file.write("итого по кредиту к выплате: %s\t переплата: %s\n" % (Total, float(Total) - float(Summa))) file.close() ''' Конец процедуры диференциального расчёта ------------------------------------------------------------------------------------- Начало процедуры аннуитетных платежей ''' def GetApnPayment(): nonlocal Summa nonlocal Rait nonlocal Period file = open('report.txt', 'w') # вычисляем процентную ставку в месяц rait = (float(Rait)/100)/12 # вычисляем относительный платёж AP = rait + (rait/(DoPowerW((1+rait), Period) - 1)) # рассчитываем ежемесячную выплату AAP = AP * float(Summa) res = 1 summ = 0 file.write("Ежемесячный платёж составит %sб, количество платежей %s\n" % (AAP, Period)) while res < int(Period) + 1: summ = summ + AAP res = res + 1 file.write("итого по кредиту к выплате %s переплата %s\n" % (summ, float(summ) - float(Summa))) file.close() ''' Конец Процедуры аннуитентных платежей '''Итак, я описал функции расчёта кредитных ставок, осталось всё это собрать в один работающий скрипт.
''' Нацало основной программы ''' # определяем исходные переменные по умолчанию заполнены -1 Summa = -1 Rait = -1 Period = -1 TypeOf = False MonslyPayment = 0 DiferCalc = False # получаем входные параметры GetEnterData() # проверяем что бы все необходимые данные были переданы if ((Summa == -1) or (Rait == -1) or (Period == -1)): print ("Не все параметры введены") exit() # проверяем не ввёл ли пользователь год вместо месяца if TypeOf == 1: Period = int(Period) * 12 print ("заем составляет %s, процентная ставка %s %%, планируемый срок в месяцах %s" % (Summa, Rait, Period)) print ("Ежемесячные платежи составят:") if DiferCalc: GetDifPayment() else: GetApnPayment() ''' Конец основной процедуры ''' # вызов основной процедуры в модуле Main()Вот собственно и весь калькулятор. P.S. На мой взгляд абсолютно бестолковая статья. Но всё же это был мой первый осознаны опыт работы с новым Python. В целом осталось довольно приятное ощущение от 3.1 несмотря на различия с предыдущими версиями. P.P.S. Спасибо
прикольно, сам недавно начал разбираться с питоном. Пока впечатления положительные, а поводом стало то что я узнал что есть такая прикольная вещь как Google Application Engine
ОтветитьУдалитьз.ы. какой средой разработки пользуешься?
Google рулит :).
ОтветитьУдалитьСреда была Eclips Galileo.
Этот комментарий был удален администратором блога.
ОтветитьУдалитья тоже его использую
ОтветитьУдалитьА ещё что ни будь пробовал?
ОтветитьУдалитьЯ ещё в notepad++ писал но там дело было без подсветки синтаксиса.
notepad++ конечно пользовал, у меня даже синтаксис подсвечивал и слова предлагал...правда не в попад)
ОтветитьУдалитьа пока эклипсик рулит
Чёрт. Написал большой и гневный коммент, но случаеным движением руки что-то не то нажал и он затёрся :( Переписывать лень. В общем, если интересно моё мнение стучись в джабер.
ОтветитьУдалитьa. не надо вообще использовать глобальные переменные здесь, можно же передавать все через параметры, возвращать кортежем
ОтветитьУдалитьb. для возведение в степень есть оператор ** (думаю он остался и в 3.1)
c. параметры строки лучше все же парсить getopt
Ага спасибо уже в курсе. Про getopt спасибо. Поковыряю.
ОтветитьУдалитьОсталось прикруть GUI c возможностью построения графиков и будет вообще шик.
ОтветитьУдалитьДа и плюс - возможность разобраться с графическими библиотеками.
PS: А графики можно еще и в картинки экспортировать.
Это уже прям полноценное приложение какое то получается. Интересно нужно будет заняться :).
ОтветитьУдалить