# -*- coding: utf-8 -*-
from __future__ import absolute_import
import time
import datetime
import calendar
from comm.db import db
from bson import ObjectId
def get_time():
year = datetime.date.today().year
month = datetime.date.today().month
firstDayWeekDay, monthRange = calendar.monthrange(year, month)
start = str(datetime.date(year= year, month=month, day=1))
end = str(datetime.date(year=year, month=month, day=monthRange))
return time.mktime(time.strptime(str(start),'%Y-%m-%d')), \
time.mktime(time.strptime(str(end),'%Y-%m-%d')), start[0:7]
def format_aggregate_result_date(data):
"""
时间处理
"""
num = len(data)
if num == 4:
return '%04d-%02d-%02d %02d' % (data['y'], data['m'], data['d'], data['h'])
elif num == 3:
return '%04d-%02d-%02d' % (data['y'], data['m'], data['d'])
elif num == 2:
return '%04d-%02d' % (data['y'], data['m'])
else:
return str(data['y'])
def mktime_to_hms(t):
"""
将时间戳取出'HH:MM:SS'
"""
t = time.strftime('%H:%M', time.localtime(t))
return t
era = datetime.datetime(1970, 1, 1)
class HeartReport(object):
def __init__(self, watch_id):
self.watch_id = watch_id
self.start, self.end, self.rpt_date=get_time()
self.heart_rate_data = []
def get_heart_rate(self):
query = {'watch_id': self.watch_id, 'maketime': {'$gte': self.start, '$lte':self.end}}
cursor = db.heart_rate.aggregate([
{'$match': query},
{'$group': {
'_id': '$bpm',
'count': {'$sum': 1}
}}
])
for c in cursor:
c['bpm'] = c['_id']
del c['_id']
self.heart_rate_data.append(c)
def risk_evaluation(self):
for i in self.heart_rate_data:
print i
if i['bpm'] > 90:
print i['count']
class SportReport(object):
def __init__(self, watch_id):
self.start, self.end, self.rpt_date = get_time()
self.data = {}
self.watch_id = watch_id
self.sport_total = 0
self.sport_advise = ''
def create_report(self):
self.get_total_data()
self.get_step_data()
self.get_sport_type_data()
self.risk_evaluation()
self.run_advise()
self.save_to_mongo()
def get_total_data(self):
"""
获取step和 calorie总数
"""
query = {'watch_id': self.watch_id,
'maketime': {'$gte': self.start, '$lte': self.end}}
total = db.step.find(query)
step_total = 0
calorie_total = 0
for c in total:
step_total += c.get('step', 0)
calorie_total += c.get('calorie', 0)
self.data = {'step': step_total, 'calorie': calorie_total}
def get_step_data(self):
"""
获取step图表数据(日期:步数)
"""
query = {'watch_id': self.watch_id,
'maketime': {'$gte': self.start, '$lte': self.end}}
# date_mode = '%Y-%m-%d'
date_group_mode = {'y': {'$year': '$time'}, 'm': {'$month': '$time'}, 'd': {'$dayOfMonth': '$time'}}
cursor = db.step.aggregate([
{'$match': query},
{'$project': {
'time': {'$add': [{'$multiply': [1000, {'$add': ['$maketime', 28800]}]}, era]},
'n': '$step',
}},
{'$group': {
'_id': date_group_mode,
'n': {'$sum': '$n'},
}}
])
result_step = []
for data in cursor:
result_step.append({
'date': format_aggregate_result_date(data['_id']),
'step': data['n'],
})
self.data['step_data'] = result_step
def get_sport_type_data(self):
"""
获取各种运动类型运动 次数/时长/卡路里消耗
"""
start = time.strftime('%Y-%m',time.localtime(self.start))
end = time.strftime('%Y-%m',time.localtime(self.end))
query = {'watch_id': self.watch_id, 'date': {'$gte': start, '$lte': end}}
cursor = db.exercise_log.find(query)
sport_num_dic = {}
result = []
for i in cursor:
if sport_num_dic.has_key(i['type']):
sport_num_dic[i['type']][0] += 1
sport_num_dic[i['type']][1] += int(i.get('long', 0))
sport_num_dic[i['type']][2] += int(i.get('calorie', 0))
continue
sport_num_dic.setdefault(i['type'], [1, int(i.get('long', 0)), int(i.get('calorie', 0))])
sport_calorie = 0
for k, v in sport_num_dic.items():
r = {}
i = v
r['sport_num'] = i.pop(0)
r['sport_time_long'] = i.pop(0)
r['calorie'] = i.pop(0)
r['sport_type'] = k
sport_calorie += r['calorie']
result.append(r)
self.sport_total += 1
self.data['sport_type_data'] = result
self.data['sport_type_calorie'] = sport_calorie
def risk_evaluation(self):
if self.data['step'] - 280000 > 20000:
sport_status = '运动过量'
elif 260000 < self.data['step'] <= 299999:
sport_status = '运动量适中'
else:
sport_status = '运动量较少'
self.sport_advise = sport_status
self.data['sport_analysis'] = {
'sport_status': sport_status,
'month_step': self.data['step'],
'sport_num': self.sport_total,
'month_calorie': self.data['sport_type_calorie']
}
def run_advise(self):
if self.sport_advise == '运动过量':
advise = '您本月运动过量,过度锻炼会对身体造成损伤,特别是每天的运动时间超过90分钟,会伤害肌腱、韧带、骨头、 \
关节和肌肉,而且受伤之后痊愈的几率很小。建议您每周坚持运动3~5次,每次运动30分钟为最佳'
elif self.sport_advise == '运动量适中':
advise = '您本月运动量适中,适当的锻炼可以强身健体。'
else:
advise = '您本月运动量较少,请加油锻炼。'
self.data['run_advise'] = advise
def save_to_mongo(self):
db.doctor_rpt_sport.insert({
'date': self.rpt_date,
'step_info': self.data['step_data'],
'step_total': self.data['step'],
'step_calorie_total': self.data['calorie'],
'sport_type_info': self.data['sport_type_data'],
'sport_calorie_total': self.data['sport_type_calorie'],
'sport_analysis': self.data['sport_analysis'],
'run_advise': self.data['run_advise']
})
class SleepReport(object):
def __init__(self, watch_id):
self.start, self.end, self.rpt_date = get_time()
self.watch_id = watch_id
self.data = {}
def create_sleep_rpt(self):
self.get_sleep_month_info()
self.get_sleep_daily_info()
self.sleep_advise()
self.sleep_status()
self.sleep_analysis()
self.save_to_mongo()
def get_sleep_month_info(self):
"""
获取睡眠月视图,以及每晚平均睡眠时间
"""
query = {'watch_id': self.watch_id, 'maketime': {'$gte': self.start, '$lte': self.end}}
date_group_mode = {'y': {'$year': '$time'}, 'm': {'$month': '$time'}, 'd': {'$dayOfMonth': '$time'}}
cursor = db.sleep.aggregate([
{'$match': query},
{'$project': {
'time': {'$add': [{'$multiply': [1000, {'$add': ['$maketime', 28800]}]}, era]},
'n': '$duration',
}},
{'$group': {
'_id': date_group_mode,
'n': {'$sum': '$n'},
}}
])
result = []
avg_sleep_time = 0
day = 0
for data in cursor:
avg_sleep_time +=data['n']
result.append({
'date': format_aggregate_result_date(data['_id']),
'curation': data['n'],
})
day += 1
self.data['sleep_analysis']['avg_sleep_time'] = float(avg_sleep_time) /day
self.data['month_info'] = result
def get_sleep_daily_info(self):
"""
睡眠日视图
"""
query = {'watch_id': self.watch_id, 'maketime': {'$gte': self.start, '$lte': self.end}}
cursor = db.sleep.find(query)
result = []
for data in cursor:
result.append({
'date': data['maketime'],
'quiet_percent': int(data['duration'] * float((data['quiet_percent']))//100),
'heart_percent': int(data['duration'] * float((data['heart_percent']))//100),
'start_time': data['start_time'],
'end_time': data['end_time']
})
self.data['daily_info'] = result
def sleep_analysis(self):
"""
睡眠分析: 一般入睡时间,一般起床时间,每晚实际睡眠时间由get_sleep_month_info获取平均值
上床到入睡时间暂时固定.20分钟
"""
query = {'watch_id': self.watch_id, 'maketime': {'$gte': self.start, '$lte': self.end}}
st = db.sleep.aggregate([
{'$match': query},
{'$project': {
'start': '$start_time',
'end': '$end_time'
}},
{'$group': {
'_id': '$start',
'count': {'$sum': 1},
}}
])
et = db.sleep.aggregate([
{'$match': query},
{'$project': {
'start': '$start_time',
'end': '$end_time'
}},
{'$group': {
'_id': '$end',
'count': {'$sum': 1},
}}
])
st_dic = {}
et_dic = {}
for i in st:
st_dic[i['_id']] = i['count']
for k, v in st_dic.items():
if v == max(st_dic.values()):
self.data['sleep_analysis']['start_sleep_time'] = mktime_to_hms(k)
for e in et:
et_dic[e['_id']] = e['count']
for k, v in et_dic.items():
if v == max(et_dic.values()):
self.data['sleep_analysis']['end_sleep_time'] = mktime_to_hms(k)
self.data['sleep_analysis']['to_sleep_time'] = 20
def sleep_advise(self):
"""
暂时不做判断建议
"""
pass
def sleep_status(self):
"""
后期根据手表功能决定是否做睡眠状态数据
"""
pass
def save_to_mongo(self):
db.doctor_rpt_sleep.insert({
'date': self.rpt_date,
'sleep_month_info': self.data['month_info'],
'sleep_daily_info': self.data['daily_info'],
'sleep_analysis': self.data['sleep_analysis'],
'sleep_status': '',
'sleep_advise': ''
})
class HabitReport(object):
def __init__(self, watch_id):
self.watch_id = watch_id
self.start, self.end, self.rpt_date = get_time()
self.data = {}
self.score_count = 0
def create_habit_rpt(self):
self.get_diet_info()
self.get_habit_info()
self.get_diet_month_info()
self.get_score_main()
self.get_life_advise()
def get_diet_info(self):
"""
获取膳食记录
"""
query = {'maketime': {'$gte': self.start, '$lte': self.end},
'watch_id': self.watch_id}
date_group_mode = {'m': {'$month': '$time'}, 'd': {'$dayOfMonth': '$time'}, 'name': '$name'}
cursor = db.diet.aggregate([
{'$match': query},
{'$project': {
'time': {'$add': [{'$multiply': [1000, {'$add': ['$maketime', 28800]}]}, era]},
'name': '$food_name',
'n': '$food_value',
'c': '$calorie'
}},
{'$group': {
'_id': date_group_mode,
'n': {'$sum': '$n'},
'c': {'$sum': '$c'}
}}
])
calorie = 0
self.data.setdefault('diet_info', [])
for i in cursor:
day = str(i['_id']['m']) + '-' + str(i['_id']['d'])
calorie += i['c']
self.data['diet_info'].append({'date':day, 'name':i['_id']['name'], 'value':i['n'] })
self.data['calorie']= calorie
def get_diet_month_info(self):
query = {'maketime': {'$gte': self.start, '$lte': self.end},
'watch_id': self.watch_id}
date_group_mode = {'m': {'$month': '$time'}, 'name': '$name'}
cursor = db.diet.aggregate([
{'$match': query},
{'$project': {
'time': {'$add': [{'$multiply': [1000, {'$add': ['$maketime', 28800]}]}, era]},
'name': '$food_name',
'n': '$food_value',
'c': '$calorie'
}},
{'$group': {
'_id': date_group_mode,
'n': {'$sum': '$n'},
'c': {'$sum': '$c'}
}}
])
self.data.setdefault('diet_month_info', [])
for i in cursor:
day = str(i['_id']['m'])
self.data['diet_month_info'].append({'month':day, 'name':i['_id']['name'], 'value':i['n'] })
def get_habit_info(self):
"""
获取生活习惯记录
"""
self.data.setdefault('habit', {'cigarette':0, 'alcoholic': []})
results = db.habit.find({'maketime': {'$gte': self.start, '$lte': self.end}, 'watch_id': self.watch_id}).sort([('maketime', -1)])
for result in results:
habit = {'cigarette': 0, 'alcoholic': {}}
if 'wine' in result['alcoholic'].keys() and result['alcoholic']['wine']:
result['alcoholic']['wine'] = float(result['alcoholic']['wine'])
if 'wine' in result['alcoholic'].keys() and not result['alcoholic']['wine']:
result['alcoholic']['wine'] = 0.0
if 'red' in result['alcoholic'].keys() and result['alcoholic']['red']:
result['alcoholic']['red'] = float(result['alcoholic']['red'])
if 'red' in result['alcoholic'].keys() and not result['alcoholic']['red']:
result['alcoholic']['red'] = 0.0
if 'beer' in result['alcoholic'].keys() and result['alcoholic']['beer']:
result['alcoholic']['beer'] = float(result['alcoholic']['beer'])
if 'beer' in result['alcoholic'].keys() and not result['alcoholic']['beer']:
result['alcoholic']['beer'] = 0.0
self.data['habit']['alcoholic'].append(result['alcoholic'])
self.data['habit']['cigarette'] += int(result['cigarette'])
def get_score_main(self):
"""
评分
food_dic{
高膳食纤维
谷类食物
食物搭配合理
能量摄入
肉类
蔬菜类
食物种类丰富
吸烟
喝酒
}
"""
food_dic = {
'high_fiber': [u'米', u'豆', u'麦'],
'cereal': [u'米', u'麦'],
'food_collocation': [u'米', u'肉', u'菜', u'面', u'豆', u'奶'],
'energy_intake': 2000.0,
'meat': 0.35,
'vegetable': 0.65,
'food_types': 6,
'smoke': 5,
'drink': 200,
}
score = {}
for k, v in food_dic.items():
if type(v) is not list:
continue
else:
score = self.get_score(k, v, score, 10)
score.setdefault('energy', {})
if self.data['calorie'] <1000:
score['energy']['state'],score['energy']['advise'] = [u'较少', u'立即改善']
score['energy']['score'] = round(self.data['calorie'] / food_dic['energy_intake']*20, 0)
else:
score['energy']['state'],score['energy']['advise'] = [u'适量', u'继续保持']
score['energy']['score'] = round(self.data['calorie'] / food_dic['energy_intake']*20, 0)
meat = 0
for i in self.data['diet_info']:
if u'肉' in i['name'] or u'蛋' in i['name']:
meat += 1
try:
meat_b = float(meat) / len(self.data['diet_info'])
except ZeroDivisionError:
meat_b = 1.21
score.setdefault('m_and_v', {})
if meat_b < food_dic['meat']:
score['m_and_v']['state'],score['m_and_v']['advise'] = [u'否', u'立即改善']
else:
score['m_and_v']['state'],score['m_and_v']['advise'] = [u'是', u'继续保持']
score['m_and_v']['score'] = round((1 - abs(food_dic['meat'] - meat_b)) *10, 0)
food_types_count = len(self.data['diet_month_info'])
score.setdefault('food_type', {})
if food_types_count < 5:
score['food_type']['state'], score['food_type']['advise'] = [u'不丰富', u'努力改善']
else:
score['food_type']['state'], score['food_type']['advise'] = [u'丰富', u'继续保持']
score['food_type']['score'] = 10.0 if food_types_count >= 10.0 else float(food_types_count)
score.setdefault('smoke', {})
if 0 <= self.data['habit']['cigarette'] <= 10:
score['smoke']['score'] = float(10-self.data['habit']['cigarette'])
score['smoke']['state'], score['smoke']['advise'] = [u'适量', u'继续保持']
else:
score['smoke']['score'],score['smoke']['state'],score['smoke']['advise'] = [1, u'过量', u'立即改善']
score.setdefault('drink', {})
drink = 0
try:
for a, v in self.data['habit']['alcoholic']:
drink += v
if drink == 0:
raise KeyError
if drink - food_dic['drink'] < -50:
score['drink']['score'] = 20 - round(drink/food_dic['drink']*20, 0)
score['drink']['state'], score['drink']['advise']= [ u'适量', u'继续保持']
elif drink - food_dic['drink'] >= 0:
score['drink']['score'] = 20 - round(food_dic['drink']/drink*20, 0)
score['drink']['state'], score['drink']['advise']= [ u'过量', u'立即改善']
except KeyError:
score['drink']['score'], score['drink']['state'], score['drink']['advise']= [20, u'适量', u'继续保持']
self.data.setdefault('score_count', 0)
for k, v in score.items():
self.data['score_count'] += v['score']
self.data['score'] = score
print self.data
def get_score(self, score_type, types_dic, score_dic, standard_socre):
"""
计算单项得分
socre_type: 计分项名称(high_fiber...)
types_dic: 计分项内容 [u'米', u'豆'...]
scoer_dic: 返回值的总项
standard_socre: 标准分数
"""
score_dic.setdefault(score_type, {'score': 0})
for i in self.data['diet_info']:
for h in types_dic:
if h in i['name']:
score_dic[score_type]['score'] += 1
if self.data['diet_info']!=0 and score_dic[score_type]['score'] != 0:
if round(float(score_dic[score_type]['score']) / len(self.data['diet_info'])*20, 0) > 10:
score_dic[score_type]['score'] = 10.0
else:
score_dic[score_type]['score'] = round(float(score_dic[score_type]['score']) / len(self.data['diet_info'])*20, 0)
score_dic[score_type]['state'], score_dic[score_type]['advise'] = self.get_state_advise(score_dic[score_type]['score'], standard_socre)
else:
pass
return score_dic
def get_state_advise(self, s, d):
"""
根据分数判断状态以及建议
"""
if d == 10:
if s < 5 :
return [u'否', u'努力提升']
else:
return [u'是', u'继续保持']
else:
if s < 10:
return [u'否', u'努力提升']
else:
return [u'是', u'继续保持']
def get_life_advise(self):
"""
生活习惯建议
"""
self.data['life_advise'] = ''
def save_to_mongo(self):
db.doctor_rpt_habit.insert({
'date': self.rpt_date,
'diet_month_info': self.data['diet_month_info'],
'diet_info': self.data['date_info'],
'calorie': self.data['calorie'],
'smoke': self.data['haibt']['cigarette'],
'drink': self.data['habit']['alcoholic'],
'health_score_info': self.data['score'],
'score': self.data['score_count'],
'life_advise': self.data['life_advise']
})
if __name__ == '__main__':
# watch_id = ObjectId('589545425f1d6569e76622af')
cursor = db.watch.find()
for i in cursor:
HR = HabitReport(i['_id'])
HR.create_habit_rpt()
医生健康报告
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 一般来说,喜欢站立的人,比喜欢躺着或或坐着的人,身材更好。与躺着的姿势相比,站姿所消耗的能量要多出10%。而单腿站...