Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
.idea
__pycache__
*/output/
*/ignored/
*.egg-info/
.idea/
build/
dev/
dist/
env/
__pycache__
*.pyc
*~$*
*.pyc
*.DS_Store
dist/
build/
MANIFEST
tags
*.swp
/*.html
*.egg-info
output/
tags
MANIFEST
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v0.5.0, 24 January 2019
* XlsForm now has a warnings attribute
* Updated requirements: requirements-unlock.txt list base, non-transitive depdendencies, while requirements.txt lists the results of pip freeze.

v0.4.0, 12 December 2018
* Added direct python API for borrow, e.g. from pmix.borrow import borrow.

Expand Down
3 changes: 3 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ clean:
rm -rf ./*.egg-info
build: clean
python3 setup.py sdist bdist_wheel
install:
pip install -r requirements-unlocked.txt --no-cache-dir; \
pip freeze > requirements.txt
pypi: build
twine upload --repository-url https://upload.pypi.org/legacy/ dist/*;
pypi_test: build
Expand Down
1 change: 1 addition & 0 deletions pmix/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
"""A mixed bag of utilities for PMA2020."""

2 changes: 1 addition & 1 deletion pmix/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Semantic versioning for the package pmix."""
VERSION = (0, 4, 0)
VERSION = (0, 5, 0)
__version__ = '.'.join(map(str, VERSION))
4 changes: 4 additions & 0 deletions pmix/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class Cell:
def __init__(self, value=None):
"""Initialize cell to have value as Python object.

Attributes:
value: A python object that is stored in the cell. Should be
castable as str.

Args:
value: The value of the cell. Defaults to None for a blank cell.
"""
Expand Down
1 change: 0 additions & 1 deletion pmix/workbook.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Module defines a Workbook class to represent Excel files."""

import itertools
import copy
import os.path
Expand Down
42 changes: 42 additions & 0 deletions pmix/xlsform.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Module defining Xlsform class to work with ODK XLSForms."""
from copy import deepcopy
from xlsxwriter.utility import xl_col_to_name
from typing import List, Optional

from pmix.xlstab import Xlstab
Expand Down Expand Up @@ -26,6 +28,8 @@ def __init__(self, path: str, stripstr: bool = True):
self.data = [Xlstab.from_worksheet(ws) for ws in self]
self.settings = {}
self.init_settings()
self.warnings = {}
self.init_warnings()

def init_settings(self):
"""Get settings from Xlsform.
Expand Down Expand Up @@ -86,6 +90,44 @@ def form_language(self) -> Optional[str]:
pass
return language

def init_warnings(self):
"""Validate data and return warnings.

Side effects:
self.warnings (dict): sets warnings

Examples:
self.warnings =
'#VALUE!': {
'survey': [X10, C56, E122]
},
'#REF!': {
'survey': [T5, C53]
},
}
"""
warnings_schema = { # taken from xlrd.error_text_from_code
'#NULL!': {}, # Intersection of two cell ranges is empty
'#DIV/0': {}, # Division by zero
'#VALUE!': {}, # Wrong type of operand
'#REF!': {}, # Illegal or deleted cell reference
'#NAME?': {}, # Wrong function or range name
'#NUM!': {}, # Value range overflow
'#N/A': {}, # Argument or function not available
}
warnings = deepcopy(warnings_schema)
error_codes = [k for k, v in warnings.items()]
for ws in self.data:
for i, row in enumerate(ws.data):
for j, cell in enumerate(row):
if cell.value in error_codes:
if ws.name not in warnings[cell.value]:
warnings[cell.value][ws.name] = []
label = xl_col_to_name(j)
warnings[cell.value][ws.name].append(label + str(i))
warnings = {k: v for k, v in warnings.items() if v != {}}
self.warnings = warnings

def add_language(self, language: str):
"""Add appropriate language columns to an Xlsform.

Expand Down
File renamed without changes.
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,24 @@ def status(s):
print('\033[1m{0}\033[0m'.format(s))

def initialize_options(self):
"""Initialize options"""
pass

def finalize_options(self):
"""Finalize options"""
pass

def run(self):
"""Run"""
try:
self.status('Removing previous builds…')
rmtree(os.path.join(here, 'dist'))
except OSError:
pass

self.status('Building Source and Wheel (universal) distribution…')
os.system(
'{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))
os.system('{0} setup.py sdist bdist_wheel --universal'
.format(sys.executable))

self.status('Uploading the package to PyPI via Twine…')
os.system('twine upload dist/*')
Expand Down