Skip to main content

Between Programs

In [1]:
%run prelude.ipy

The between programs are intended to test the effects of pulled-out versus inline functionality.

We expected that having functionality pulled out would benefit experienced programmers, who would more quickly chunk the definitions and interpret the main body of the program. Less experienced programmer were expected to take more time and refer to function definitions more often.

Code

between_functions.py

def between(numbers, low, high):
    winners = []
    for num in numbers:
        if (low < num) and (num < high):
            winners.append(num)
    return winners

def common(list1, list2):
    winners = []
    for item1 in list1:
        if item1 in list2:
            winners.append(item1)
    return winners

x = [2, 8, 7, 9, -5, 0, 2]
x_btwn = between(x, 2, 10)
print x_btwn 

y = [1, -3, 10, 0, 8, 9, 1]
y_btwn = between(y, -2, 9)
print y_btwn 

xy_common = common(x, y)
print xy_common 

between_inline.py

x = [2, 8, 7, 9, -5, 0, 2]
x_between = []
for x_i in x:
    if (2 < x_i) and (x_i < 10):
        x_between.append(x_i)
print x_between

y = [1, -3, 10, 0, 8, 9, 1]
y_between = []
for y_i in y:
    if (-2 < y_i) and (y_i < 9):
        y_between.append(y_i)
print y_between

xy_common = []
for x_i in x:
    if x_i in y:
        xy_common.append(x_i)
print xy_common


Output

[8, 7, 9]
[1, 0, 8, 1]
[8, 9, 0]

Metrics

  • Lines of code: 24
  • Cyclomatic complexity: 7
  • Halstead effort: 94192
  • Halstead volume: 830

Output

[8, 7, 9]
[1, 0, 8, 1]
[8, 9, 0]

Metrics

  • Lines of code: 19
  • Cyclomatic complexity: 7
  • Halstead effort: 45596
  • Halstead volume: 661


Response Data

In [2]:
between_responses = util.filter_program(responses, "between")
functions_responses = util.filter_program(responses, "between", "functions")
inline_responses = util.filter_program(responses, "between", "inline")
In [14]:
axes = plot.misc.grade_distributions(between_responses)
axes[0].figure
Out[14]:
In [13]:
axes = plot.misc.duration_distributions(between_responses)
axes[0].figure
Out[13]:
In [23]:
print "both"
print between_responses[["duration", "grade_value"]].corr(method="spearman").values[0, 1]
print ""

for version, frame in between_responses.groupby("version"):
    print version
    print frame[["duration", "grade_value"]].corr(method="spearman").values[0, 1]
    print ""
both
0.244076969364

functions
0.235377441066

inline
0.251958270835


In [15]:
axes = plot.misc.python_experience_distributions(between_responses)
axes[0].figure
Out[15]:
In [16]:
axes = plot.misc.programming_experience_distributions(between_responses)
axes[0].figure
Out[16]:
In []:
print "both"
print between_responses[["duration", "grade_value"]].corr(method="spearman").values[0, 1]
print ""

for version, frame in between_responses.groupby("version"):
    print version
    print frame[["duration", "grade_value"]].corr(method="spearman").values[0, 1]
    print ""
In [113]:
results = eye_analysis.classify.feature_importances(between_responses, 
                            ["prog_years", "py_years", "degree_num", "age", "gender_num", "duration"], "grade_common",
                            num_estimators=250)

ax = plot.misc.feature_importances(results)
ax.set_title("Feature Importances")
ax.figure.tight_layout()
ax.figure
Out[113]:
In [73]:
results = eye_analysis.classify.area_under_curve(between_responses, ["prog_years", "py_years", "degree_num", "age", "gender_num", "duration"], "grade_common")
fig = pyplot.figure()
ax = pyplot.axes()
results.boxplot(by="classifier", ax=ax)
fig
Out[73]:
In [7]:
a, b = util.split_by_boolean(functions_responses, "grade_correct")
In [10]:
pyplot.figure()
a.duration.hist().figure
Out[10]:
In [11]:
pyplot.figure()
b.duration.hist().figure
Out[11]:
In [14]:
a.duration.median(), b.duration.median()
Out[14]:
(191.0, 136.5)
In [19]:
pyplot.figure()
a.py_years.hist().figure
Out[19]:
In [20]:
pyplot.figure()
b.py_years.hist().figure
Out[20]:

Eye-Tracking

In [3]:
functions_fixations = util.filter_program(line_fixations, "between", "functions")
In [21]:
img = plot.fixations.line_code_image(functions_fixations, code_image("between", "functions"))
img.thumbnail((800,800), Image.ANTIALIAS)
img
Out[21]:
In [25]:
ax = plot.fixations.line_transitions(functions_fixations, num_lines=24, figsize=(20, 10), show_probs=False)
ax.set_title("Line Transitions (between functions)")
ax.figure
Out[25]:
In [73]:
ax = plot.fixations.line_timeline(functions_fixations, step_size=200)
ax.figure.tight_layout()
ax.figure
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-73-6f0d150fbb5e> in <module>()
      1 ax = plot.fixations.line_timeline(functions_fixations, step_size=200)
----> 2 ax.figure.tight_layout()
      3 ax.figure

/usr/local/lib/python2.7/dist-packages/matplotlib/figure.pyc in tight_layout(self, renderer, pad, h_pad, w_pad)
   1349 
   1350         if renderer is None:
-> 1351             renderer = get_renderer(self)
   1352 
   1353         subplotspec_list = []

/usr/local/lib/python2.7/dist-packages/matplotlib/tight_layout.pyc in get_renderer(fig)
    197 
    198         if canvas and hasattr(canvas, "get_renderer"):
--> 199             renderer = canvas.get_renderer()
    200         else:
    201             # not sure if this can happen

/usr/local/lib/python2.7/dist-packages/matplotlib/backends/backend_agg.pyc in get_renderer(self)
    433 
    434         if need_new_renderer:
--> 435             self.renderer = RendererAgg(w, h, self.figure.dpi)
    436             self._lastKey = key
    437         return self.renderer

/usr/local/lib/python2.7/dist-packages/matplotlib/backends/backend_agg.pyc in __init__(self, width, height, dpi)
     70         self.height = height
     71         if __debug__: verbose.report('RendererAgg.__init__ width=%s, height=%s'%(width, height), 'debug-annoying')
---> 72         self._renderer = _RendererAgg(int(width), int(height), dpi, debug=False)
     73         self._filter_renderers = []
     74 

ValueError: width and height must each be below 32768
In [5]:
ax = plot.fixations.line_timeline_steps(functions_fixations)
ax.figure.tight_layout()
ax.figure
Out[5]:
In [154]:
metrics.num_fixations(functions_fixations)
Out[154]:
trial_id
17          410
49          700
70          199
88          463
105         410
121         298
141         364
169         800
181         183
206         288
230         233
241         207
261         452
281         394
310         233
dtype: int64
In [131]:
metrics.fixation_duration_per_aoi(functions_fixations, text_lengths)
Out[131]:
line 1     5539.70
line 13    1495.76
dtype: float64
In [146]:
metrics.time_to_first_fixation(functions_fixations, "line 10")
Out[146]:
2865
In [152]:
metrics.percent_fixations_on_aoi(functions_fixations, "line 10", 10)
Out[152]:
0.53333333333333333
In [153]:
metrics.average_fixation_duration(functions_fixations)
Out[153]:
trial_id
17          283.424390
49          249.107143
70          185.412060
88          257.816415
105         228.660976
121         301.000000
141         249.310440
169         309.405000
181         317.311475
206         253.774306
230         278.712446
241         221.864734
261         286.373894
281         218.124365
310         255.334764
Name: duration, dtype: float64
In [60]:
import matplotlib.cm as cm
In [69]:
first_trial = functions_fixations.trial_id.values[0]
trial_fixations = functions_fixations[functions_fixations.trial_id == first_trial]
density, counts = metrics.fixation_spatial_density(trial_fixations, 
                grid_bbox=(0, 0, 1920, 1080), num_rows=20, num_cols=20, threshold=1)
print density
screen_image = data.hansen_2012.trial_screen(first_trial)
img = plot.fixations.spatial_density_heatmap(counts, screen_image, cmap=cm.coolwarm)
img
0.11

Out[69]:
In [71]:
masked_counts = np.ma.masked_where(counts < 1, counts)
In [72]:
masked_counts
Out[72]:
masked_array(data =
 [[-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- 4.0 -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- 3.0 -- 1.0 12.0 3.0 -- -- -- -- -- -- -- -- -- -- --]
 [-- -- 10.0 1.0 8.0 1.0 14.0 21.0 3.0 -- -- -- -- -- -- -- -- -- -- --]
 [-- -- 26.0 18.0 6.0 9.0 19.0 17.0 5.0 -- -- -- -- -- -- -- -- -- -- --]
 [-- 2.0 11.0 42.0 8.0 5.0 17.0 24.0 2.0 -- -- -- -- -- -- -- -- -- -- --]
 [-- 3.0 4.0 8.0 3.0 3.0 16.0 43.0 3.0 -- -- -- -- -- -- -- -- -- -- --]
 [-- -- 7.0 -- -- 3.0 2.0 7.0 -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- 5.0 4.0 -- 1.0 -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- 3.0 3.0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]],
             mask =
 [[ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True False  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True False  True False False False  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True False False False False False False False  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True False False False False False False False  True  True  True
   True  True  True  True  True  True  True  True]
 [ True False False False False False False False False  True  True  True
   True  True  True  True  True  True  True  True]
 [ True False False False False False False False False  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True False  True  True False False False  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True False False  True False  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True False False  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True  True  True  True  True
   True  True  True  True  True  True  True  True]],
       fill_value = 1e+20)

In [7]:
trial_groups = functions_fixations.groupby("trial_id")
In [19]:
visited, ids = metrics.lines_by_time(functions_fixations, step_size=1000)
In [22]:
visited.shape
Out[22]:
(15, 343)
In [23]:
functions_fixations
Out[23]:
&ltclass 'pandas.core.frame.DataFrame'&gt
Int64Index: 5634 entries, 35 to 38845
Data columns (total 15 columns):
exp_id         5634  non-null values
trial_id       5634  non-null values
base           5634  non-null values
version        5634  non-null values
fix_id         5634  non-null values
offset_kind    5634  non-null values
hit_kind       5634  non-null values
aoi_kind       5634  non-null values
aoi_name       5634  non-null values
start_ms       5634  non-null values
end_ms         5634  non-null values
fix_x          5634  non-null values
fix_y          5634  non-null values
line           5634  non-null values
duration       5634  non-null values
dtypes: int64(9), object(6)