Module libratools.lbt_experiment
The libratools.lbt_experiment module contains functions related to various experimental procedures, such as defining and assigning a treatment value.
Expand source code
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
The libratools.lbt_experiment module contains functions related to various
experimental procedures, such as defining and assigning a treatment value.
"""
import random # standard library
import datetime
import numpy as np # 3rd party packages
def get_feeding_times(activity_vals, min_time=2, max_time=180,
end_time='12:00:00', round_min=False):
"""
Returns feeding times based on range of daily activity.
Args:
activity_vals (list): list of activity values.
min_time (int, default=2): minimum feeding time in mins.
max_time (int, default=180): maximum feeding time in mins.
end_time (str, default='12:00:00') time at which to stop
feeding, if end_time='12:00:00' then feeding times will
be computed to end at 12:00:00.
round_min (bool, default=False): decide whether to round
begin treatment time to the nearest minute, if round_min=
True then time will be provided in format HH:MM:SS.
Returns:
feeding_time (list): list of feeding times in mins as ints
start_times (list): list of feeding start times as strings.
"""
# return nan string values if activity has not been computed
if len(activity_vals) <= 1:
return [np.nan], [np.nan]
else:
# get current date
today = datetime.datetime.today().strftime('%b %m %Y')
# declare end of feeding time as datetime object
end = datetime.datetime.strptime(f'{today} {end_time}', '%b %m %Y %H:%M:%S')
# get feeding time values as list of ints using linear mapping
feeding_times = apply_linear_mapping(
activity_vals, y_min=min_time, y_max=max_time)
# get feeding start times as strings in 12-hour clock time format
if round_min is True:
time_format = '%H:%M'
else:
time_format = '%H:%M:%S'
start_times = [(end-datetime.timedelta(minutes=t)).strftime(f'{time_format} %p')
for t in feeding_times]
return feeding_times, start_times
def apply_linear_mapping(x_set, y_min, y_max):
"""
Applies a straight line equation in the form y = mx + b to a set of x
values. First computes the slope-intercept form of the equation using
the minimum and maximum of the provided x values alongside given minimum
and maximum y values as points and then inputs each x value to the
equation.
Args:
x_set (list): list of x coordinates.
y_min (int): minimum y coordinate.
y_max (int): maximum y coordinate.
Returns:
y_vals (list).
"""
# check x values are list
if x_set == [0]:
return np.nan
# declare range of y values
y_set = list(range(y_min, y_max+1))
# get constants for treatment equation
m, b = get_slope_intercept_vars(
(min(x_set), min(y_set)), (max(x_set), max(y_set)))
# get y value for each activity value and return as list
y_vals = [(m * x) + b for x in x_set]
return y_vals
def get_slope_intercept_vars(p1, p2):
"""
Returns slope and y-intercept for a straight line given two points.
Args:
p1 (tuple): first point.
p2 (tuple): second point.
Returns:
m (float), b (float)
"""
try:
m = (p2[1] - p1[1]) / (p2[0] - p1[0])
except ZeroDivisionError:
m = (p2[1] - p1[1]) / 1
b = p2[1] - (m * p2[0])
return m, b
# if __name__ == '__main__':
# generate 12 random values for daily activity
# activity_vals = random.sample(range(1000, 20000), 12)
# compute feeding times and start times based activity using defaults
# feeding_times, feeding_start_times = get_feeding_times(activity_vals)
# return feeding time dict
# treatment_dict = {x: {str(t): str(start)} for x, t, start in zip(
# activity_vals, feeding_times, feeding_start_times)
}
# iterate over the list of dict(s)
# print('Activity (cm) | Feeding time | Begin treatment at}')
# print('------------------------------------')
# for val in treatment_dict:
# print(val, treatment_dict[val])
Functions
def apply_linear_mapping(x_set, y_min, y_max)
-
Applies a straight line equation in the form y = mx + b to a set of x values. First computes the slope-intercept form of the equation using the minimum and maximum of the provided x values alongside given minimum and maximum y values as points and then inputs each x value to the equation.
Args
x_set
:list
- list of x coordinates.
y_min
:int
- minimum y coordinate.
y_max
:int
- maximum y coordinate.
Returns
y_vals (list).
Expand source code
def apply_linear_mapping(x_set, y_min, y_max): """ Applies a straight line equation in the form y = mx + b to a set of x values. First computes the slope-intercept form of the equation using the minimum and maximum of the provided x values alongside given minimum and maximum y values as points and then inputs each x value to the equation. Args: x_set (list): list of x coordinates. y_min (int): minimum y coordinate. y_max (int): maximum y coordinate. Returns: y_vals (list). """ # check x values are list if x_set == [0]: return np.nan # declare range of y values y_set = list(range(y_min, y_max+1)) # get constants for treatment equation m, b = get_slope_intercept_vars( (min(x_set), min(y_set)), (max(x_set), max(y_set))) # get y value for each activity value and return as list y_vals = [(m * x) + b for x in x_set] return y_vals
def get_feeding_times(activity_vals, min_time=2, max_time=180, end_time='12:00:00', round_min=False)
-
Returns feeding times based on range of daily activity.
Args
activity_vals
:list
- list of activity values.
min_time
:int
, default=2
- minimum feeding time in mins.
max_time
:int
, default=180
- maximum feeding time in mins.
- end_time (str, default='12:00:00') time at which to stop
- feeding, if end_time='12:00:00' then feeding times will
- be computed to end at 12:00:00.
round_min
:bool
, default=False
- decide whether to round begin treatment time to the nearest minute, if round_min= True then time will be provided in format HH:MM:SS.
Returns
feeding_time (list): list of feeding times in mins as ints start_times (list): list of feeding start times as strings.
Expand source code
def get_feeding_times(activity_vals, min_time=2, max_time=180, end_time='12:00:00', round_min=False): """ Returns feeding times based on range of daily activity. Args: activity_vals (list): list of activity values. min_time (int, default=2): minimum feeding time in mins. max_time (int, default=180): maximum feeding time in mins. end_time (str, default='12:00:00') time at which to stop feeding, if end_time='12:00:00' then feeding times will be computed to end at 12:00:00. round_min (bool, default=False): decide whether to round begin treatment time to the nearest minute, if round_min= True then time will be provided in format HH:MM:SS. Returns: feeding_time (list): list of feeding times in mins as ints start_times (list): list of feeding start times as strings. """ # return nan string values if activity has not been computed if len(activity_vals) <= 1: return [np.nan], [np.nan] else: # get current date today = datetime.datetime.today().strftime('%b %m %Y') # declare end of feeding time as datetime object end = datetime.datetime.strptime(f'{today} {end_time}', '%b %m %Y %H:%M:%S') # get feeding time values as list of ints using linear mapping feeding_times = apply_linear_mapping( activity_vals, y_min=min_time, y_max=max_time) # get feeding start times as strings in 12-hour clock time format if round_min is True: time_format = '%H:%M' else: time_format = '%H:%M:%S' start_times = [(end-datetime.timedelta(minutes=t)).strftime(f'{time_format} %p') for t in feeding_times] return feeding_times, start_times
def get_slope_intercept_vars(p1, p2)
-
Returns slope and y-intercept for a straight line given two points.
Args
p1
:tuple
- first point.
p2
:tuple
- second point.
Returns
m (float), b (float)
Expand source code
def get_slope_intercept_vars(p1, p2): """ Returns slope and y-intercept for a straight line given two points. Args: p1 (tuple): first point. p2 (tuple): second point. Returns: m (float), b (float) """ try: m = (p2[1] - p1[1]) / (p2[0] - p1[0]) except ZeroDivisionError: m = (p2[1] - p1[1]) / 1 b = p2[1] - (m * p2[0]) return m, b