Skip to content
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

Tableau v2 #1910

Merged
merged 27 commits into from
Jan 5, 2021
Merged

Tableau v2 #1910

merged 27 commits into from
Jan 5, 2021

Conversation

WinnyTroy
Copy link
Contributor

@WinnyTroy WinnyTroy commented Sep 30, 2020

Changes / Features implemented

Defines a new endpoint implementing multiple tables on Tableau repeat data collected on Onadata.
With this every repeat/nested repeat defines a new tableau table.

Steps taken to verify this change does what is intended

  • Confirming schema and data definitions on the new /api/v1/open-data/v2 endpoint

  • Add tests

An alternative solution for #1880
Part of #1885

@WinnyTroy WinnyTroy changed the title Tableau nested repeat check Tableau v2 Sep 30, 2020
@WinnyTroy WinnyTroy force-pushed the tableau_nested_repeat_check branch 2 times, most recently from 260c198 to 72e552b Compare October 13, 2020 08:50
@WinnyTroy WinnyTroy force-pushed the tableau_nested_repeat_check branch 2 times, most recently from ed167a7 to fe7c2ad Compare October 19, 2020 08:53
@DavisRayM DavisRayM force-pushed the tableau_nested_repeat_check branch 7 times, most recently from 585812c to ad257ab Compare October 28, 2020 07:07
Copy link
Member

pld commented Oct 28, 2020

Codacy Here is an overview of what got changed by this pull request:

Complexity increasing per file
==============================
- onadata/apps/api/viewsets/tableau_viewset.py  25
         

Clones added
============
- onadata/apps/api/viewsets/open_data_viewset.py  1
- onadata/apps/api/viewsets/tableau_viewset.py  1
         

See the complete overview on Codacy

@DavisRayM DavisRayM force-pushed the tableau_nested_repeat_check branch 3 times, most recently from 2f55c5d to 66949a2 Compare November 5, 2020 08:09
@WinnyTroy WinnyTroy mentioned this pull request Nov 9, 2020
Copy link
Contributor

@ivermac ivermac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments but it generally looks good

Comment on lines 62 to 64
# Pop any list within the returned repeat data.
# Lists represent a repeat group which should be in a
# separate field.
cleaned_data = []
for data_dict in repeat_data:
remove_keys = []
for k, v in data_dict.items():
if isinstance(v, list):
remove_keys.append(k)
flat_dict[k].extend(v)
# pylint: disable=expression-not-assigned
[data_dict.pop(k) for k in remove_keys]
cleaned_data.append(data_dict)
flat_dict[qstn_name] = cleaned_data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this to function that returns cleaned_data ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 77 to 90
picked_choices = value.split(" ")
choice_names = [
question["name"] for question in qstn["children"]]
list_name = qstn.get('list_name')
for choice in choice_names:
qstn_name = f"{list_name}_{choice}"

if prefix:
qstn_name = prefix + '_' + qstn_name

if choice in picked_choices:
flat_dict[qstn_name] = "TRUE"
else:
flat_dict[qstn_name] = "FALSE"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to a function outside this function that updates flat_dict?

Comment on lines 92 to 102
value_parts = value.split(' ')
gps_xpath_parts = []
for part in GPS_PARTS:
name = f"_{qstn_name}_{part}"
if prefix:
name = prefix + '_' + name
gps_xpath_parts.append((name, None))
if len(value_parts) == 4:
gps_parts = dict(
zip(dict(gps_xpath_parts), value_parts))
flat_dict.update(gps_parts)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to a function outside this function?

@WinnyTroy WinnyTroy force-pushed the tableau_nested_repeat_check branch 4 times, most recently from dde45e9 to 5ae768a Compare November 17, 2020 06:28
Copy link
Contributor

@ivermac ivermac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting close

Comment on lines 88 to 99
def unpack_select_multiple_data(picked_choices, list_name,
choice_names, prefix, flat_dict):
for choice in choice_names:
qstn_name = f"{list_name}_{choice}"

if prefix:
qstn_name = prefix + '_' + qstn_name

if choice in picked_choices:
flat_dict[qstn_name] = "TRUE"
else:
flat_dict[qstn_name] = "FALSE"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this function to return flat_dict - just like it's been done in line 116 - then assign the returned value to flat_dict in line 70

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change

Comment on lines +77 to +76
gps_parts = unpack_gps_data(
value, qstn_name, prefix)
flat_dict.update(gps_parts)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if unpack_gps_data returns None, line 79 would trigger an error, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say no. I dont believe there could be a scenerio where it would return None. Maybe this is something new we could test

The function can only be called if the element is of "geopoint" question type. All geopoint question types are space separated strings, unless the user does not provide data for this question, for which the field is then not present in the json returned by the serializer. I could be wrong Cc: @DavisRayM

@WinnyTroy WinnyTroy force-pushed the tableau_nested_repeat_check branch 2 times, most recently from 7bb5906 to e14821d Compare November 18, 2020 13:57
DavisRayM and others added 12 commits January 4, 2021 09:43
Add repeat column headers list if the headers list already exists.
…mn headers have been defined using the select multiple question.

Gnerate column headers with gps headers split into 4 column headers ie. altitude, latitude, precision and longitude
- Split gps fields into separate columns
- Ensure schema and data always have the same columns by utilizing the
  JSON of an XLS Form
- Support "select_multiple" questions
Break apart the process tableau data function into separate functions
ivermac
ivermac previously approved these changes Jan 4, 2021
@WinnyTroy WinnyTroy force-pushed the tableau_nested_repeat_check branch 6 times, most recently from 085441a to 4676dd3 Compare January 5, 2021 10:22
@DavisRayM DavisRayM merged commit 3a0154d into master Jan 5, 2021
@DavisRayM DavisRayM deleted the tableau_nested_repeat_check branch January 5, 2021 13:38
@DavisRayM DavisRayM mentioned this pull request Jan 20, 2021
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants