@bituke

Как правильно стыковать данные по датам из нескольких массивов?

Задача следующая:
Имеются кредит и данные по оплате кредита:
-дата оплаты
-сумма оплаты
кредитов может быть несколько, данные по его оплате растягиваются от даты получения кредита, до конца его срока, в итоге мы имеем массив данных на весь этот период, допустим:
первый кредит: от начала 12 мая 2021, до конца 21 февраля 2024;
Второй кредит: от начала 16 февраля 2023 до конца 6 июня 2026;
Задача:
Нужно сложить все данные по оплате кредита по всем месяцам, где они стыкуются в ОПРЕДЕЛЕННОМ ПЕРИОДЕ.
Допустим устанавливаем период от 12 июня 22 года до 15 февраля 25 года, в этом периоде нужно высчитать сумму всех оплат по всем кредитам на каждый месяц периода. В итоге у нас должен выйти массив с месяцами установленного периода, и суммой оплаты по всем кредитам на этот месяц.
Так же нужно учесть, что дата оплаты кредита может быть 1 января 2021 года, а установленный период начинается 10 января 2021. Значит сумма оплаты по кредиту тут должна быть не полная, только за 20 дней. 20 дней - это процентов 65% от всего месяца, значит сумма оплаты за месяц установленного периода должна быть 65%) Как это учесть? Если дней в месяцах бывает не всегда 30)

Задача сложная, могу сделать через тысячу циклов, списков и условий, но уверен это будет ужасно выглядеть, пока даже нет представления как и в чем хранить все эти массивы.

Полного решения не требую - не настолько наглый) Но за общее описание правильного решения буду крайне благодарен. Может есть какие-то библиотеки и функции для таких задач? В чем хранить все эти данные и как ими манипулировать? Как поставить условие "если этот месяц совпадает с этим месяцем.." Ведь сравнивать по дате нельзя - дни могут не сойтись, а сойтись должно именно по месяцам.
Входные данные:
-сумма кредита, платеж кредита в месяц, срок кредита, дата получения кредита
-начальная дата, конченая дата периода, за который нужно получить все платежи
  • Вопрос задан
  • 61 просмотр
Решения вопроса 1
seven5674
@seven5674
Старый я уже что бы что-то в себе менять
Как это учесть? Если дней в месяцах бывает не всегда 30

spoiler

import datetime
import calendar

summa = 1000

d1 = '2022-02-01'
d2 = '2022-02-05'

d1 = datetime.datetime.strptime(d1, "%Y-%m-%d")
d2 = datetime.datetime.strptime(d2, "%Y-%m-%d")

year = d1.year
month = d1.month

days_diff = d2 - d1
month_days = calendar.monthrange(year, month)[1]
summa_news = (month_days - days_diff.days) * summa / month_days

print("Полная сумма {}".format(summa))
print("Сумма с учетом дней {:.0f}".format(summa_news))

и...
Полная сумма 1000
Сумма с учетом дней 857



Ведь сравнивать по дате нельзя - дни могут не сойтись, а сойтись должно именно по месяцам.

ну значит не сравнивай дни а сравнивай только по году и месяцу
spoiler

import datetime

d1 = '2022-02-01'
d2 = '2022-02-05'

d1 = datetime.datetime.strptime(d1, "%Y-%m-%d")
d2 = datetime.datetime.strptime(d2, "%Y-%m-%d")

# v1 - как строки
if d1.strftime("%Y-%m") == d2.strftime("%Y-%m"):
    print("Ok")
else:
    print("No")

# v2 - как обьекты
if d1.year == d2.year and d1.month == d2.month:
    print("Ok")
else:
    print("No")


проверить принадлежность даты периоду можно еще так
spoiler

import datetime

d1 = '2022-02-01'
d2 = '2022-02-05'
d3 = '2022-05-05'

d1 = datetime.datetime.strptime(d1, "%Y-%m-%d").timestamp()
d2 = datetime.datetime.strptime(d2, "%Y-%m-%d").timestamp()
d3 = datetime.datetime.strptime(d3, "%Y-%m-%d").timestamp()

if d1 <= d2 <= d3:
    print("Ok")
else:
    print("No")


В чем хранить все эти данные

ну для тестового примере храни в sqlite - сгенерировать fake data не особо сложная задача
как и в целом в данной задаче я не вижу больших проблем - тут только работа с датами

в сухом остатке БД у тебя будет содержать две таблицы
1. Таблица с платежами - id, payer_id, period, summa
2. Таблица с информацией по плательщикам - id, payer_id, fio
По payer_id ты легко можешь их связать. Выборку из БД делаешь по диапазону дат.
В основном скрипте проверяешь и суммируешь - как вариант промежуточного хранилища используй словарь
spoiler

credits = {
    "Иванов" : {
        "credit_1" : {
            '2021-01': 21221,
            .
            .
            .
            '2021-11': 234234
        }
    }
}



Значительно упросить задачу можно правильной выборкой данных
Вот пример (в твоем случае category_sub_name - это заемщик, category_cur_name - это кредит)
spoiler

SELECT category_cur_name, category_cur_name, SUM(summa) AS summa FROM (
	SELECT category_sub_name, category_cur_name, SUM(view_count) AS summa, 
       strftime("%Y-%m", created_at) AS 'period' 
       FROM orders WHERE period >= '2021-01' AND period <= '2021-12'
	   GROUP BY category_sub_name, category_cur_name, period) 
   GROUP BY category_cur_name ORDER BY summa DESC

62983194ca346600365564.png

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

Конечный вариант можно визуализировать в табличной форме например в pyqt
Но с учетом специфики равных платежей у тебя скорее всего будет просто прямая

Вот пример для расчета сезонности
6298333332598997344560.png
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы