Поставил перед собой простую задачу: Сделать кредитный калькулятор, ты ему сумму кредита, период и процентную ставку, а он тебе график погашения и сумму переплаты.
Задача была разбита на 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: А графики можно еще и в картинки экспортировать.
Это уже прям полноценное приложение какое то получается. Интересно нужно будет заняться :).
ОтветитьУдалить