-
Notifications
You must be signed in to change notification settings - Fork 80
List proc data in search #1039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
List proc data in search #1039
Changes from 1 commit
28e6f57
59286a7
9227ee3
6f08836
7b386c3
545a213
07c9da2
350b864
7e8c447
7eedf17
48c6760
dba9942
917c003
10b0c5c
3fe2af9
c16b429
ccd7d4a
179b582
b6c0f44
fbcd86c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,41 @@ def _get_shared_links_for_study(study): | |
return ", ".join(shared) | ||
|
||
|
||
def _build_single_study_info(study, info): | ||
# Clean up and add to the study info for HTML purposes | ||
PI = StudyPerson(info['principal_investigator_id']) | ||
status = study.status | ||
if info['pmid'] is not None: | ||
info['pmid'] = ", ".join([pubmed_linkifier([p]) | ||
for p in info['pmid']]) | ||
else: | ||
info['pmid'] = "" | ||
if info["number_samples_collected"] is None: | ||
info["number_samples_collected"] = 0 | ||
info["shared"] = _get_shared_links_for_study(study) | ||
info["num_raw_data"] = len(study.raw_data()) | ||
info["status"] = status | ||
info["study_id"] = study.id | ||
info["pi"] = study_person_linkifier((PI.email, PI.name)) | ||
del info["principal_investigator_id"] | ||
del info["email"] | ||
return info | ||
|
||
|
||
def _build_proc_data_info(study, study_proc, proc_samples): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMOO, this function should follow the structure of the previous one. It should be |
||
# Build the proc data info list for the child row in datatable | ||
proc_data_info = [] | ||
for pid in study_proc[study.id]: | ||
proc_data = ProcessedData(pid) | ||
proc_info = proc_data.processing_info | ||
proc_info['pid'] = pid | ||
proc_info['data_type'] = proc_data.data_type() | ||
proc_info['samples'] = sorted(proc_samples[pid]) | ||
proc_info['processed_date'] = str(proc_info['processed_date']) | ||
proc_data_info.append(proc_info) | ||
return proc_data_info | ||
|
||
|
||
def _build_study_info(user, study_proc=None, proc_samples=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although the code on this function looks good, I had a hard time understanding completely what the function is doing. I think it will improve the readability and maintenance of the code if parts of this function are encapsulated in their own functions. For example, the construction of the Also, IMOO the html introduced here is hard to read. Is it possible to move it to a global so it becomes easier to read (less problems with PEP8)... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. refactored and now renders the gnarly stuff client-side usingt he datatables module itself. |
||
"""builds list of dicts for studies table, with all html formatted | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. builds -> Builds and html -> HTML |
||
|
||
|
@@ -61,21 +96,22 @@ def _build_study_info(user, study_proc=None, proc_samples=None): | |
------- | ||
infolist: list of dict of lists and dicts | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. o.O possible to have a format description, this is really convoluted... Something like: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking a bit more on how this looks like and reading a bit further the code, I think you will take advantage of using namedtuples. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly. How do those work when JSON serialized? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know, probably worth give it a shot and try different things. The code as it is right now is really hard to follow and I don't think that is maintainable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has to be JSON because all this is sent over AJAX to the datatable, which is what allows the table to be dynamic for each metadata search. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, it looks like serializing namedtuples to json is a bit tricky http://stackoverflow.com/q/5906831/3746629. Giving this, I think that breaking the function in multiple functions (as I suggested before) and introducing a highly detailed documentation, will help to make this code maintainable. IMOO, this function should only create the list. The outer dictionary should be created by another function, and the inner dictionary by another function. This will put a logical break up in the code that will be easier to follow, as well as easier testable, since the error (if any) will be in 1 of these 3 functions rather than in a single one as it is right now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
study and processed data info for JSON serialiation for datatables | ||
Each dict in the list is a single study, and contains the text | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing the return description. |
||
Notes | ||
----- | ||
Both study_proc and proc_samples must be passed, or neither passed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest also adding a comment on the description of each parameter: |
||
""" | ||
build_samples = False | ||
# Logic check to make sure both needed parts passed | ||
build_info = False | ||
if study_proc is not None and proc_samples is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's no tests for these exception cases. Would you mind adding those? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added |
||
raise IncompetentQiitaDeveloperError( | ||
'Must pass proc_samples when study_proc given') | ||
elif proc_samples is not None and study_proc is None: | ||
raise IncompetentQiitaDeveloperError( | ||
'Must pass study_proc when proc_samples given') | ||
elif proc_samples is None: | ||
build_info = True | ||
elif study_proc is None: | ||
build_samples = True | ||
|
||
# get list of studies for table | ||
study_set = user.user_studies.union( | ||
|
@@ -93,48 +129,24 @@ def _build_study_info(user, study_proc=None, proc_samples=None): | |
study_info = Study.get_info(study_set, cols) | ||
|
||
infolist = [] | ||
for row, info in enumerate(study_info): | ||
for info in study_info: | ||
# Convert DictCursor to proper dict | ||
info = dict(info) | ||
study = Study(info['study_id']) | ||
PI = StudyPerson(info['principal_investigator_id']) | ||
status = study.status | ||
# if needed, get all the proc data info since no search results passed | ||
if build_info: | ||
proc_data = study.processed_data() | ||
proc_samples = {} | ||
study_proc = {study.id: proc_data} | ||
for pid in proc_data: | ||
proc_samples[pid] = ProcessedData(pid).samples | ||
|
||
# Clean up and add to the study info for HTML purposes | ||
if info['pmid'] is not None: | ||
info['pmid'] = ", ".join([pubmed_linkifier([p]) | ||
for p in info['pmid']]) | ||
else: | ||
info['pmid'] = "" | ||
if info["number_samples_collected"] is None: | ||
info["number_samples_collected"] = 0 | ||
info["shared"] = _get_shared_links_for_study(study) | ||
info["num_raw_data"] = len(study.raw_data()) | ||
info["status"] = status | ||
info["study_id"] = study.id | ||
info["pi"] = study_person_linkifier((PI.email, PI.name)) | ||
del info["principal_investigator_id"] | ||
del info["email"] | ||
# Build the processed data info for the study if none passed | ||
if build_samples: | ||
proc_data = study.processed_data() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The indentation in this block has a few extra spaces. |
||
proc_samples = {} | ||
study_proc = {study.id: proc_data} | ||
for pid in proc_data: | ||
proc_samples[pid] = ProcessedData(pid).samples | ||
|
||
study_info = _build_single_study_info(study, info) | ||
# Build the proc data info list for the child row in datatable | ||
proc_data_info = [] | ||
for pid in study_proc[study.id]: | ||
proc_data = ProcessedData(pid) | ||
proc_info = proc_data.processing_info | ||
proc_info['pid'] = pid | ||
proc_info['data_type'] = proc_data.data_type() | ||
proc_info['samples'] = sorted(proc_samples[pid]) | ||
proc_info['processed_date'] = str(proc_info['processed_date']) | ||
proc_data_info.append(proc_info) | ||
info["proc_data_info"] = proc_data_info | ||
|
||
infolist.append(info) | ||
study_info["proc_data_info"] = _build_proc_data_info(study, study_proc, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is weird that this is done here. If "proc_data_info" is part of the study info (which it is) it should be created on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is to make a clear separation between proc data and study info. It also makes it so I don't have to pass as many things into the single_study_info function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is that there is no separation. The "proc_data_info" is added 2015-04-12 16:48 GMT-07:00 Joshua Shorenstein notifications@github.com:
Jose Navas |
||
proc_samples) | ||
|
||
infolist.append(study_info) | ||
return infolist | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This auxuliary functions are missing the docstring. I think that putting the docstring is what will make the return structure more understandable, w/o the necessity to go over the code... (that's also what I meant by breaking the functions...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done