@bituke

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

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

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

Полного решения не требую - не настолько наглый) Но за общее описание правильного решения буду крайне благодарен. Может есть какие-то библиотеки и функции для таких задач? В чем хранить все эти данные и как ими манипулировать? Как поставить условие "если этот месяц совпадает с этим месяцем.." Ведь сравнивать по дате нельзя - дни могут не сойтись, а сойтись должно именно по месяцам.
Входные данные:
-сумма кредита, платеж кредита в месяц, срок кредита, дата получения кредита
-начальная дата, конченая дата периода, за который нужно получить все платежи
  • Вопрос задан
  • 60 просмотров
Решения вопроса 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
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
07 мая 2024, в 14:11
4000 руб./за проект
07 мая 2024, в 14:10
10000 руб./за проект
07 мая 2024, в 14:04
1300 руб./за проект