%run prelude.ipy
%%html
<link rel="stylesheet" href="files/custom_devel.css" />
Software complexity is "a measure of resources expended by a system [human or other] while interacting with a piece of software to perform a given task."
Basili, 1980
Property | Description |
---|---|
\((\exists P, Q)(|P| \ne |Q|)\) | Not all programs should have the same complexity |
\((\forall c)( \{ P \; | \; |P| = c \} \textrm{ is finite})\) | The set of programs whose complexity is \(c\) is finite |
\((\exists P, Q)(|P| = |Q| \textrm{ and } P \ne Q)\) | Some programs share the same complexity |
\((\exists P, Q)(P \equiv Q \textrm{ and } |P| \ne |Q|)\) | Functional equivalence does not imply complexity equivalence |
\((\forall P, Q)(|P| \le |P; Q| \textrm{ and } |Q| \le |P; Q|)\) | Concatenation cannot decrease complexity |
\((\exists P, Q, R)(|P| = |Q| \textrm{ and } |P; R| \ne |Q; R|)\) | Context matters for complexity after concatenation |
\((\exists P)(|P| \ne |\textrm{permute}(P)|)\) | The order of statements matters |
\((\forall P)(|P| = |\textrm{rename}(P)|)\) | Identifier and operator names do not matter |
\((\exists P, Q)(|P| + |Q| < |P; Q|)\) | Concatenated programs may be more complex than the sum of their parts |
One feature which all of these [theoretical] approaches have in common is that they begin with certain characteristics of the software and attempt to determine what effect they might have on the difficulty of the various programmer tasks.
A more useful approach would be first to analyze the processes involved in programmer tasks, as well as the parameters which govern the effort involved in those processes. From this point one can deduce, or at least make informed guesses, about which code characteristics will affect those parameters.
Cant et. al, 1995
Term | Description |
---|---|
\(R_F\) | Speed of recall or review (familiarity) |
\(R_S\) | Chunk size |
\(R_C\) | Type of control structure in which chunk is embedded |
\(R_E\) | Difficulty of understanding complex Boolean or other expressions |
\(R_R\) | Recognizability of chunk |
\(R_V\) | Effects of visual structure |
\(R_D\) | Disruptions caused by dependencies |
\(T_F\) | Dependency familiarity |
\(T_L\) | Localizatio |
\(T_A\) | Ambiguit |
\(T_S\) | Spatial distance |
\(T_C\) | Level of cueing |
fig = plot.misc.demographics(experiments)
fig.savefig("images/demographics-all.png", dpi=50)
pyplot.clf()
fig = plot.misc.demographics(experiments[experiments.location == "bloomington"])
fig.savefig("images/demographics-bloomington.png", dpi=50)
pyplot.clf()
between
- filter two lists, intersection
functions
- between/common in functions (24 lines)inline
- no functions (19 lines)counting
- simple for
loop with bug
nospace
- no blank lines in loop body (3 lines)twospaces
- 2 blank lines in loop body (5 lines)funcall
- simple function call with different values
nospace
- calls on 1 line, no spaces (4 lines)space
- calls on 1 line, spaced out (4 lines)vars
- calls on 3 lines, different vars (7 lines)overload
- overloaded + operator (number strings)
multmixed
- numeric *, string + (11 lines)plusmixed
- numeric +, string + (11 lines)strings
- string + (11 lines)partition
- partition list of numbers
balanced
- odd number of items (5 lines)unbalanced
- even number of items (5 lines)unbalanced_pivot
- even number of items, pivot var (6 lines)initvar
- summation and factorial
bothbad
- bug in both (9 lines)good
- no bugs (9 lines)onebad
- bug in summation (9 lines)order
- 3 simple functions called
inorder
- call order = definition order (14 lines)shuffled
- call order \(\ne\) definition order (14 lines)rectangle
- compute area of 2 rectangles
basic
- x,y,w,h in separate vars, area() in function (18 lines)class
- x,y,w,h,area() in class (21 lines)tuples
- x,y,w,h in tuples, area() in function (14 lines)scope
- function calls with no effect
diffname
- local/global var have same name (12 lines)samename
- local/global var have different name (12 lines)whitespace
- simple linear equations
linedup
- code is aligned on operators (14 lines)zigzag
- code is not aligned (14 lines)print "1" + "2"
print 4 * 3
12 12
"12",12
3 12
barney
trial_id = 17
screen_img = data.hansen_2012.trial_screen(trial_id)
img = plot.fixations.circles(all_fixations[all_fixations.trial_id == trial_id], screen_img, alpha=0.6)
img.thumbnail((1000, 1000), Image.ANTIALIAS)
img.save("images/17-circles.jpg")
from nltk.util import ngrams
fixations = data.hansen_2012.all_fixations()
aois = data.hansen_2012.areas_of_interest()
trial_id = 17
t_fixes = fixations[fixations.trial_id == trial_id]
t_aois = aois[aois.trial_id == trial_id]
line_scan = aoi.scanpath_from_fixations(
t_fixes, repeats=False,
aoi_names = { "line": [] })
tri_grams = pandas.Series(
ngrams(line_scan, 3)).value_counts()
ax = tri_grams[:10].plot(kind="barh")
ax.invert_yaxis()
ax.figure.tight_layout()
ax.figure.savefig("images/example-hist.png")
pyplot.clf()
# Load library and experiment data
from eyecode import data, aoi
fixes = data.hansen_2012.all_fixations()
aois = data.hansen_2012.areas_of_interest()
# Filter down to a single trial
trial_id = 17
t_fixes = fixes[fixes.trial_id == trial_id]
t_aois = aois[aois.trial_id == trial_id]
# Compute scanpath and plot top 10 tri-grams
line_scan = aoi.scanpath_from_fixations(
t_fixes, repeats=False,
aoi_names = { "line": [] })
pandas.Series(nltk.util.ngrams(line_scan, 3))\
.value_counts()[:10].plot(kind="barh")
p_y
when p_x
is seen