Conversion of some functions to generators.

This commit is contained in:
lwark
2024-07-31 13:08:56 -05:00
parent eb6cdc63e2
commit 8266275354
15 changed files with 374 additions and 369 deletions

View File

@@ -84,7 +84,7 @@ class ControlType(BaseClass):
Returns:
List[ControlType]: Control types that have targets
"""
return [item for item in cls.query() if item.targets]# != []]
return [item for item in cls.query() if item.targets]
@classmethod
def build_positive_regex(cls) -> Pattern:
@@ -141,7 +141,9 @@ class Control(BaseClass):
# logger.debug("calculating kraken count total to use in percentage")
kraken_cnt_total = sum([kraken[item]['kraken_count'] for item in kraken])
# logger.debug("Creating new kraken.")
new_kraken = [dict(name=item, kraken_count=kraken[item]['kraken_count'], kraken_percent="{0:.0%}".format(kraken[item]['kraken_count'] / kraken_cnt_total)) for item in kraken]
new_kraken = [dict(name=item, kraken_count=kraken[item]['kraken_count'],
kraken_percent="{0:.0%}".format(kraken[item]['kraken_count'] / kraken_cnt_total)) for item in
kraken]
new_kraken = sorted(new_kraken, key=itemgetter('kraken_count'), reverse=True)
# logger.debug("setting targets")
if not self.controltype.targets:

View File

@@ -8,7 +8,7 @@ from sqlalchemy.ext.associationproxy import association_proxy
from datetime import date
import logging, re
from tools import check_authorization, setup_lookup, Report, Result
from typing import List, Literal
from typing import List, Literal, Generator
from pandas import ExcelFile
from pathlib import Path
from . import Base, BaseClass, Organization
@@ -168,9 +168,9 @@ class KitType(BaseClass):
return [item.reagent_role for item in relevant_associations]
# TODO: Move to BasicSubmission?
def construct_xl_map_for_use(self, submission_type: str | SubmissionType) -> dict:
def construct_xl_map_for_use(self, submission_type: str | SubmissionType) -> Generator[str, str]:
"""
Creates map of locations in excel workbook for a SubmissionType
Creates map of locations in Excel workbook for a SubmissionType
Args:
submission_type (str | SubmissionType): Submissiontype.name
@@ -178,7 +178,7 @@ class KitType(BaseClass):
Returns:
dict: Dictionary containing information locations.
"""
info_map = {}
# info_map = {}
# NOTE: Account for submission_type variable type.
match submission_type:
case str():
@@ -193,10 +193,10 @@ class KitType(BaseClass):
# logger.debug("Get all KitTypeReagentTypeAssociation for SubmissionType")
for assoc in assocs:
try:
info_map[assoc.reagent_role.name] = assoc.uses
yield assoc.reagent_role.name, assoc.uses
except TypeError:
continue
return info_map
# return info_map
@classmethod
@setup_lookup
@@ -409,6 +409,7 @@ class Reagent(BaseClass):
rtype = reagent_role.name.replace("_", " ")
except AttributeError:
rtype = "Unknown"
# logger.debug(f"Role for {self.name}: {rtype}")
# NOTE: Calculate expiry with EOL from ReagentType
try:
place_holder = self.expiry + reagent_role.eol_ext
@@ -611,7 +612,8 @@ class SubmissionType(BaseClass):
) #: Association of equipmentroles
equipment = association_proxy("submissiontype_equipmentrole_associations", "equipment_role",
creator=lambda eq: SubmissionTypeEquipmentRoleAssociation(equipment_role=eq)) #: Proxy of equipmentrole associations
creator=lambda eq: SubmissionTypeEquipmentRoleAssociation(
equipment_role=eq)) #: Proxy of equipmentrole associations
submissiontype_kit_rt_associations = relationship(
"KitTypeReagentRoleAssociation",
@@ -665,7 +667,7 @@ class SubmissionType(BaseClass):
def construct_info_map(self, mode: Literal['read', 'write']) -> dict:
"""
Make of map of where all fields are located in excel sheet
Make of map of where all fields are located in Excel sheet
Args:
mode (Literal["read", "write"]): Which mode to get locations for
@@ -673,15 +675,16 @@ class SubmissionType(BaseClass):
Returns:
dict: Map of locations
"""
info = {k:v for k,v in self.info_map.items() if k != "custom"}
info = {k: v for k, v in self.info_map.items() if k != "custom"}
logger.debug(f"Info map: {info}")
output = {}
match mode:
case "read":
output = {k: v[mode] for k, v in info.items() if v[mode]}
case "write":
output = {k: v[mode] + v['read'] for k, v in info.items() if v[mode] or v['read']}
output = {k: v for k, v in output.items() if all([isinstance(item, dict) for item in v])}
case _:
output = {}
output['custom'] = self.info_map['custom']
return output
@@ -694,36 +697,38 @@ class SubmissionType(BaseClass):
"""
return self.sample_map
def construct_equipment_map(self) -> dict:
def construct_equipment_map(self) -> Generator[str, dict]:
"""
Constructs map of equipment to excel cells.
Returns:
dict: Map equipment locations in excel sheet
"""
output = {}
# output = {}
# logger.debug("Iterating through equipment roles")
for item in self.submissiontype_equipmentrole_associations:
emap = item.uses
if emap is None:
emap = {}
output[item.equipment_role.name] = emap
return output
# output[item.equipment_role.name] = emap
yield item.equipment_role.name, emap
# return output
def construct_tips_map(self) -> dict:
def construct_tips_map(self) -> Generator[str, dict]:
"""
Constructs map of tips to excel cells.
Returns:
dict: Tip locations in the excel sheet.
"""
output = {}
# output = {}
for item in self.submissiontype_tiprole_associations:
tmap = item.uses
if tmap is None:
tmap = {}
output[item.tip_role.name] = tmap
return output
# output[item.tip_role.name] = tmap
yield item.tip_role.name, tmap
# return output
def get_equipment(self, extraction_kit: str | KitType | None = None) -> List['PydEquipmentRole']:
"""
@@ -1280,15 +1285,16 @@ class EquipmentRole(BaseClass):
Returns:
dict: This EquipmentRole dict
"""
output = {}
for key, value in self.__dict__.items():
match key:
case "processes":
pass
case _:
value = value
output[key] = value
return output
# output = {}
return {key: value for key, value in self.__dict__.items() if key != "processes"}
# match key:
# case "processes":
# pass
# case _:
# value = value
# yield key, value
# # output[key] = value
# return output
def to_pydantic(self, submission_type: SubmissionType,
extraction_kit: str | KitType | None = None) -> "PydEquipmentRole":
@@ -1668,7 +1674,6 @@ class SubmissionTipsAssociation(BaseClass):
back_populates="tips_submission_associations") #: associated equipment
role_name = Column(String(32), primary_key=True) #, ForeignKey("_tiprole.name"))
def to_sub_dict(self) -> dict:
"""
This item as a dictionary

View File

@@ -25,7 +25,7 @@ from openpyxl.worksheet.worksheet import Worksheet
from openpyxl.drawing.image import Image as OpenpyxlImage
from tools import row_map, setup_lookup, jinja_template_loading, rreplace, row_keys, check_key_or_attr, Result, Report
from datetime import datetime, date
from typing import List, Any, Tuple, Literal
from typing import List, Any, Tuple, Literal, Generator
from dateutil.parser import parse
from pathlib import Path
from jinja2.exceptions import TemplateNotFound
@@ -289,7 +289,7 @@ class BasicSubmission(BaseClass):
try:
reagents = [item.to_sub_dict(extraction_kit=self.extraction_kit) for item in
self.submission_reagent_associations]
for k in self.extraction_kit.construct_xl_map_for_use(self.submission_type):
for k, v in self.extraction_kit.construct_xl_map_for_use(self.submission_type):
if k == 'info':
continue
if not any([item['role'] == k for item in reagents]):
@@ -841,6 +841,7 @@ class BasicSubmission(BaseClass):
for k, v in fields.items():
sheet = xl[v['sheet']]
sample[k] = sheet.cell(row=idx, column=v['column']).value
# yield sample
samples.append(sample)
return samples
@@ -1381,7 +1382,7 @@ class Wastewater(BasicSubmission):
return input_dict
@classmethod
def parse_pcr(cls, xl: Workbook, rsl_plate_num: str) -> list:
def parse_pcr(cls, xl: Workbook, rsl_plate_num: str) -> List[dict]:
"""
Parse specific to wastewater samples.
"""
@@ -1393,6 +1394,7 @@ class Wastewater(BasicSubmission):
sample['sample'] = re.sub('-N\\d$', '', sample['sample'])
# NOTE: if sample is already in output skip
if sample['sample'] in [item['sample'] for item in output]:
logger.warning(f"Already have {sample['sample']}")
continue
# NOTE: Set ct values
sample[f"ct_{sample['target'].lower()}"] = sample['ct'] if isinstance(sample['ct'], float) else 0.0