1
- '''
2
- Helper functions to make data handling and conversions easier
3
- '''
1
+ """Helper functions to make data handling and conversions easier
2
+
3
+ # Figures 0.3.13 - Defining scope of this module
4
+
5
+ The purpose of this module is to provide conveniece methods around commonly
6
+ executed statements. These convenience methods should serve as shorthand for
7
+ code we would repeatedly execute which don't yet have a module of their own.
8
+
9
+ The idea is that if there is not yet a module for some helper function, we put
10
+ it in here until we see a pattern. We then either identify a new module and
11
+ transplate these like functions out of this module into the new one. Or we
12
+ identify that functions in here actually should go in an existing module.
13
+
14
+ The purposes for this are:
15
+
16
+ 1. Reduce development time cost by not having to stop and design (informally or
17
+ formally) a new module or inspect all the existing modules to find an
18
+ appropriate home. The second point is helpful for those not intimately
19
+ familiar with the Figures codebase
20
+
21
+ 2. Avoid premature optimization in building out new module functionality because
22
+ we are adding a single method (Avoid the desire to fill this new module with
23
+ more than the new functionality that serves our immediate needs)
24
+
25
+ 3. Avoid over specificifity, which can results in an explosion of tiny modules
26
+ that may be too specific in their context
27
+
28
+
29
+ ## Background
30
+
31
+ Originally this module served as a variant of a 'utils' module, but with the
32
+ express purpose of providing convenience "helper" functions to help DRY (do not
33
+ repeat yourself) the code and make the code more readable
34
+
35
+ ## What does not belong here?
36
+
37
+ * "Feature" functionality does not belong here
38
+ * Long functions do not belong here
39
+ * Code that communicates outside of Figures does not belong here. No database,
40
+ filesystem, or network connectiviely functionality belongs here
41
+
42
+ This is not an exhaustive list. We'll grow it as needed.
43
+
44
+ An important point is that we should not expect this module to be a permanent
45
+ home for functionality.
46
+ """
4
47
5
48
import calendar
6
49
import datetime
@@ -19,6 +62,8 @@ def is_multisite():
19
62
A naive but reliable check on whether Open edX is using multi-site setup or not.
20
63
21
64
Override by setting ``FIGURES_IS_MULTISITE`` to true in the Open edX FEATURES.
65
+
66
+ TODO: Move to `figures.sites`
22
67
"""
23
68
return bool (settings .FEATURES .get ('FIGURES_IS_MULTISITE' , False ))
24
69
@@ -28,19 +73,23 @@ def log_pipeline_errors_to_db():
28
73
Capture pipeline errors to the figures.models.PipelineError model.
29
74
30
75
Override by setting ``FIGURES_LOG_PIPELINE_ERRORS_TO_DB`` to false in the Open edX FEATURES.
76
+
77
+ TODO: This is an environment/setting "getter". Should be moved to `figures.settings`
31
78
"""
32
79
return bool (settings .FEATURES .get ('FIGURES_LOG_PIPELINE_ERRORS_TO_DB' , True ))
33
80
34
81
35
82
def as_course_key (course_id ):
36
- ''' Returns course id as a CourseKey instance
83
+ """ Returns course id as a CourseKey instance
37
84
38
85
Convenience method to return the paramater unchanged if it is of type
39
86
``CourseKey`` or attempts to convert to ``CourseKey`` if of type str or
40
87
unicode.
41
88
42
89
Raises TypeError if an unsupported type is provided
43
- '''
90
+
91
+ NOTE: This is a good example of a helper method that belongs here
92
+ """
44
93
if isinstance (course_id , CourseKey ):
45
94
return course_id
46
95
elif isinstance (course_id , basestring ): # noqa: F821
@@ -54,6 +103,11 @@ def as_datetime(val):
54
103
'''
55
104
TODO: Add arg flag to say if caller wants end of day, beginning of day
56
105
or a particular time of day if the param is a datetime.date obj
106
+
107
+
108
+ NOTE: The date functions here could be in a `figures.datetools` module.
109
+
110
+ Not set on the name `datetools` but some date specific module
57
111
'''
58
112
if isinstance (val , datetime .datetime ):
59
113
return val
@@ -74,10 +128,15 @@ def as_datetime(val):
74
128
75
129
76
130
def as_date (val ):
77
- ''' Casts the value to a ``datetime.date`` object if possible
131
+ """ Casts the value to a ``datetime.date`` object if possible
78
132
79
133
Else raises ``TypeError``
80
- '''
134
+
135
+ NOTE: This is a good example of a helper method that belongs here
136
+ We could also move this and the other date helpers to a "date"
137
+ labeled module in Figures. Then at some future time, move those out
138
+ into a "toolbox" package to abstrac
139
+ """
81
140
# Important to check if datetime first because datetime.date objects
82
141
# pass the isinstance(obj, datetime.date) test
83
142
if isinstance (val , datetime .datetime ):
@@ -117,13 +176,11 @@ def days_in_month(month_for):
117
176
118
177
# TODO: Consider changing name to 'months_back_iterator' or similar
119
178
def previous_months_iterator (month_for , months_back ):
120
- ''' Iterator returns a year,month tuple for n months including the month_for
179
+ """ Iterator returns a year,month tuple for n months including the month_for
121
180
122
181
month_for is either a date, datetime, or tuple with year and month
123
182
months back is the number of months to iterate
124
-
125
- includes the month_for
126
- '''
183
+ """
127
184
128
185
if isinstance (month_for , tuple ):
129
186
# TODO make sure we've got just two values in the tuple
0 commit comments