Как решить проблему соотношения количества лекарств (MPR)? - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь решить проблему с рационом владения лекарствами.

Я пытался использовать интервалы, а затем сравнивать их с периодом наблюдения.

(ns clara-rules.mpr-new
  (:require [clj-time.core :as t]
            [clj-time.format :as f]))

(defn observe [interval]
  (def start (map #(f/parse (f/formatter "dd MM yyyy") (% :start_)) interval))
  (def end (map #(f/parse (f/formatter "dd MM yyyy") (% :end_)) interval))

  )
(observe '({:start_ "20 01 2012" :end_ "20 02 2012"}
           {:start_ "20 02 2012" :end_ "20 03 2012"}
           {:start_ "20 04 2012" :end_ "20 05 2012"}
           {:start_ "20 06 2012" :end_ "20 07 2012"}))


(defn calc[a b]
(def start_date (f/parse (f/formatter "dd MM yyyy") a)
  )

  (def end_date (f/parse (f/formatter "dd MM yyyy")b)
      )

  (def observation_period(t/in-days(t/interval start_date end_date)))
  (println observation_period)
  )
(calc "01 02 2012" "01 12 2012")

(defn mpr_ratio[]

  (def overlp (map #(t/overlap (t/interval start_date end_date) (t/interval %1 %2))start end))

  (def x (map #(t/in-days %)overlp))
  (println x)
  (def ratio (reduce +(map #(float(*(/ % observation_period)100))x)))
  (println ratio)
  )
(mpr_ratio)

Я ожидаю расчетное соотношение всех интервалов ипериод наблюдения.

Ответы [ 2 ]

2 голосов
/ 09 июля 2019

так может выглядеть функция дневных интервалов:

(defn process []
  (let [from ["20 01 2012"
              "20 03 2012"
              "20 06 2012"
              "20 08 2012"]
        to ["20 02 2012"
            "20 05 2012"
            "20 07 2012"
            "20 09 2012"]
        get-date (partial f/parse (f/formatter "dd MM yyyy"))
        days (map #(t/in-days (t/interval (get-date %1) (get-date %2)))
                  from to)]
    days))

user> (process)
;;=> (31 61 30 31)

Тем не менее, я советую вам прочитать введение в clojure

1 голос
/ 11 июля 2019

Несколько предложений:

  1. Используйте функцию с возвращаемым значением вместо того, чтобы полагаться на побочный эффект (println и def внутри функции), чтобы получить свой результат
  2. Использованиеdef только для переменной верхнего уровня, используйте let для любой временной переменной внутри функции
  3. Создайте несколько функций специального назначения (например, функция для анализа даты; функция для преобразования списка наблюдений в даты), затем используйтеэти функции для создания вашего решения
  4. Использование макроса потока (например, -> ->>) для улучшения читабельности

Возможное решение:

(def fmt
  "default date formatter"
  (f/formatter "dd MM yyyy"))

(def ->date
  "utility function to convert string to date"
  (partial f/parse fmt))

(->date "01 02 2012")
;; => #object[org.joda.time.DateTime 0x6e880ccd "2012-02-01T00:00:00.000Z"]

(defn ->observations
  [intervals]
  (->> intervals
       (map (fn [{:keys [start_ end_]}]
              {:start (->date start_)
               :end   (->date end_)}))))

(->observations '({:start_ "20 01 2012" :end_ "20 02 2012"}
                  {:start_ "20 02 2012" :end_ "20 03 2012"}))
;; => ({:start #object[org.joda.time.DateTime 0x4eb450bd "2012-01-20T00:00:00.000Z"], :end #object[org.joda.time.DateTime 0x558bd20f "2012-02-20T00:00:00.000Z"]} {:start #object[org.joda.time.DateTime 0x4009d145 "2012-02-20T00:00:00.000Z"], :end #object[org.joda.time.DateTime 0x42e32d6 "2012-03-20T00:00:00.000Z"]})

(defn mpr_ratio
  [start_date end_date intervals]
  (let [intrvrl   (t/interval start_date end_date)
        obsrv-prd (t/in-days intrvrl)]
    (->> (map t/interval (map :start intervals) (map :end intervals))
         (map (partial t/overlap intrvrl))
         (map t/in-days)
         (map #(-> %
                   (/ obsrv-prd)
                   (* 100.0)))
         (reduce +))))

(mpr_ratio (->date "01 02 2012")
           (->date "01 12 2012")
           (->observations '({:start_ "20 01 2012" :end_ "20 02 2012"}
                             {:start_ "20 02 2012" :end_ "20 03 2012"}
                             {:start_ "20 04 2012" :end_ "20 05 2012"}
                             {:start_ "20 06 2012" :end_ "20 07 2012"})))
;; => 35.526315789473685

UPDATE - функция полезности PDC

(defn covered [state interval]
  (if (some #(t/overlaps? interval %) state)
    (->> state
         (map #(if (t/overlaps? interval %)
                 (t/interval (t/min-date (t/start %) (t/start interval))
                             (t/max-date (t/end %) (t/end interval)))
                 %))
         (into (empty state)))
    (conj state interval)))

(covered #{} (t/interval (->date "01 02 2012") (->date "05 02 2012")))
;; => #{#object[org.joda.time.Interval 0x30addc0b "2012-02-01T00:00:00.000Z/2012-02-05T00:00:00.000Z"]}
(covered *1 (t/interval (->date "04 02 2012") (->date "07 02 2012")))
;; => #{#object[org.joda.time.Interval 0x7f8893c1 "2012-02-01T00:00:00.000Z/2012-02-07T00:00:00.000Z"]}
(covered *1 (t/interval (->date "02 03 2012") (->date "07 03 2012")))
;; => #{#object[org.joda.time.Interval 0x7f8893c1 "2012-02-01T00:00:00.000Z/2012-02-07T00:00:00.000Z"] #object[org.joda.time.Interval 0x67adc8d1 "2012-03-02T00:00:00.000Z/2012-03-07T00:00:00.000Z"]}
(reduce + (map (comp inc t/in-days) *1))
;; => 13

функция pdc в полном объеме: (обратите внимание, что нужно добавить только одну строку)

(defn pdc_ratio
  [start_date end_date intervals]
  (let [intrvrl   (t/interval start_date end_date)
        obsrv-prd (t/in-days intrvrl)]
    (->> (map t/interval (map :start intervals) (map :end intervals))
         (map (partial t/overlap intrvrl))
         ;; get covered days only
         (reduce covered #{})
         (map t/in-days)
         (map #(-> %
                   (/ obsrv-prd)
                   (* 100.0)))
         (reduce +))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...