text:
  <meta name="generator" content=
  "HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
  <meta http-equiv="Content-Type" content=
  "text/html; charset=us-ascii">

  <title></title>

        <!DOCTYPE html>

        <!--For
        Modernizr-->

        <!--[if lt IE 7 ]> <html
        class="no-js ie6" lang="en">
        <![endif]-->

        <!--[if IE 7 ]> <html
        class="no-js ie7" lang="en">
        <![endif]-->

        <!--[if IE 8 ]> <html
        class="no-js ie8" lang="en">
        <![endif]-->

        <!--[if (gte IE
        9)|!(IE)]><!--> <html class="no-js" lang="en">
        <!--<![endif]-->

        <head>

        <meta charset="UTF-8">

        <title> Quantitatively
        Analysing Parametric Models â€“ Daniel
        Davis</title>

        <meta name="title" content=" Quantitatively Analysing
        Parametric Models â€“ Daniel
        Davis">

        <meta name="description"
        content="">

        <meta name="author" content="Daniel
        Davis">

        <meta name="Copyright"
        content="Copyright
        Daniel Davis 2013. All Rights
        Reserved.">

        <meta http-equiv="cleartype"
        content="on">

        <meta http-equiv="X-UA-Compatible"
        content="IE=edge,chrome=1">

        <meta name="viewport" content="width=device-width,
        initial-scale=1.0">

        <link rel="shortcut icon"
        href="http://www.danieldavis.com/favicon.ico">

        <link rel="apple-touch-icon"
        href="http://www.danieldavis.com/apple-touch-icon.png">

        <script type="text/javascript"
        src="//use.typekit.net/iuw0nyk.js"></script>

        <script type="text/javascript">try{Typekit.load();}catch(e){}</script>

        <link rel="stylesheet"
        href="http://www.danieldavis.com/wp-content/themes/daniel/css/global.css"
        media="all">

        <link rel="stylesheet"
        href="http://www.danieldavis.com/wp-content/themes/daniel/css/layout.css"
        media="all and (min-width:
        33.236em)">

        <script src="http://www.danieldavis.com/wp-content/themes/daniel/js/modernizr-1.7.min.js"></script>

        <meta property="fb:admins"
        content="738439514"
        />

        <link rel="pingback" href="http://www.danieldavis.com/xmlrpc.php"
        />

        <link rel="alternate"
        type="application/rss+xml"
        title="Daniel Davis &raquo;
        Feed" href="http://www.danieldavis.com/feed/"
        />

        <link rel="alternate"
        type="application/rss+xml"
        title="Daniel Davis &raquo;
        Comments Feed" href="http://www.danieldavis.com/comments/feed/"
        />

        <link rel="alternate"
        type="application/rss+xml"
        title="Daniel Davis &raquo;
        Quantitatively Analysing Parametric Models Comments
        Feed" href="http://www.danieldavis.com/quantitatively-analysing-parametric-models/feed/"
        />

        <link rel='prev' title='How to Draw a
        Hyperboloid' href='http://www.danieldavis.com/how-to-draw-a-hyperboloid/'
        />

        <link rel='next' title='Gender Inequity and Design
        Technology' href='http://www.danieldavis.com/gender-inequity-and-design-technology/'
        />

        <link rel='canonical'
        href='http://www.danieldavis.com/quantitatively-analysing-parametric-models/'
        />

        </head>

        <body class="single single-post
        postid-3977 single-format-standard">

        <div id="container"
        class="cf">

        <header>

        <h2>

        <a href="http://www.danieldavis.com"
        id="header-logo"><img
        src="http://www.danieldavis.com/wp-content/themes/daniel/img/daniel_blue.png"
        alt="Daniel
        Davis"></a>

        </h2>

        <div role="navigation"
        id="nav">

        <ul>

        <li class=""><a
        href="http://www.danieldavis.com">Blog</a></li>

        <li class="selected"><a
        href="http://www.danieldavis.com/d/portfolio/">Portfolio</a></li>

        <li class=""><a
        href="http://www.danieldavis.com/about/">About</a></li>

        <li class=""><a
        href="http://www.danieldavis.com/subscribe/">Subscribe</a></li>

        </ul>

        </div>

        </header> <div id="main" role="main">

        <article class="post-3977 post type-post
        status-publish format-standard hentry category-2014p
        category-papers category-portfolio" id="post-3977">

        <h1 class="entry-title">Quantitatively
        Analysing Parametric Models</h1>

        <p class="banner"><img
        width="480" height="238" src="http://www.danieldavis.com/wp-content/uploads/2014/10/comparison-480x238.jpg"
        class="attachment-banner-uncropped"
        alt="Cyclomatic complexity and
        dimensionality vs size." /></p>

        <h3>Daniel Davis
        â€“ October 2014</h3>

        <div class="entry-content">

        <div class="pre"><p><strong>Cite
        as:</strong> Davis,
        Daniel. 2014. â€œQuantitatively Analysing
        Parametric Models.â€ <em>International Journal of
        Architectural Computing</em> 12 (3):
        307â€“319.</p></div>

        <h4>Abstract</h4>

        <p>Architectural practices
        regularly work with parametric models, yet almost nothing
        is known about the general properties of these models. We
        do not know how large a typical model is, or how
        complicated, or even what the typical parametric model
        does. These knowledge gaps are the focus of this article,
        which documents the first large-scale quantitative
        parametric model survey. In this paper three key
        quantitative metrics â€“ dimensionality,
        size, and cyclomatic complexity â€“ are
        applied to a collection of 2002 parametric models created
        by 575 designers. The results show that parametric models
        generally exhibit a number of strong correlations, which
        reveal a practice of parametric modelling that has as much
        to do with the management of data as it does with the
        modelling of geometry. These findings demonstrate the
        utility of software engineering metrics in the description
        and analysis of parametric models.</p>

        <h2>1.
        Introduction</h2>

        <p><span class="dropcap">O</span>ur
        current understanding of parametric modelling is largely
        confined to firsthand accounts of individuals working with
        specific parametric models. These accounts have proved
        useful both in illustrating new methods of parametric
        modelling (such as [1, 2]) and in demonstrating the
        application of parametric modelling in practice (such as
        [3, 4]). In these previous studies, the subject of
        investigation has often been exceptional parametric models
        â€“ the models worthy of study because
        they constitute a novel method of working or an original
        application. This focus on the exceptional has left
        significant gaps in our understanding of the ordinary. Many
        basic questions have either gone unasked or unanswered. For
        instance, we do not know how large a typical model is, or
        how complicated, or even what the typical parametric model
        does.</p>

        <p>Software engineers have
        asked similar questions of the computer programs they
        write. In an attempt to understand software quality,
        software engineers have invented numerous quantitative
        methods for evaluating various aspects of their code. In
        the following pages I take three key quantitative metrics
        from software engineering â€“ size,
        dimensionality, cyclomatic complexity â€“
        and explain their applicability to parametric modelling. I
        use these metrics to measure 2002 parametric models created
        by 575 designers. By aggregating these measurements
        together I am able to identify general trends in the
        sampled population that help reveal the customary practices
        of parametric modelling.</p>

        <h2>2. Quantifying Software
        Engineering</h2>

        <p>For decades software
        engineers have sought to study computer code with elegant,
        repeatable, statistical studies [5]. A significant product
        of this prior research has been the formalisation of key
        metrics for measuring software quality. There are at least
        twenty-three unique measures of software quality
        categorised in the Compendium of Software Quality Standards
        and Metrics [6], and over one hundred in the ISO/IEC 9126
        standard for Software Product Quality [7]. Together these
        metrics constitute a vocabulary of software quality that
        software engineers commonly use for project planning, cost
        estimation, quality assurance, defect identification, the
        management of programmers, and software engineering
        research [8]. Two particularly fundamental metrics are the
        measurement of code size using the lines of code, and the
        measurement of code complexity with
        McCabeâ€™s cyclomatic complexity measure
        [8]. Since digital parametric models are essentially a type
        of computer program [9], there is reason to suspect that
        the metrics software engineers use to quantify code quality
        may also be applicable to architects wanting to measure
        their parametric models. Of particular interest are the
        measurements of code size (both lines of code and
        dimensionality) as well as code complexity (cyclomatic
        complexity). These metrics constitute the focus of this
        article.</p>

        <h2>3. Method</h2>

        <p>Quantitative metrics have
        never been applied to a large group of parametric models.
        This is probably because it has been difficult for
        architectural researchers to amass large, representative
        collections of parametric models. Instead, researchers
        generally only have access to parametric models created by
        themselves or their colleagues, which is a sample too
        idiosyncratic to draw any general conclusions from. The
        problem of gathering a collection of parametric models has
        been somewhat solved by the advent of websites enabling
        communities of designers to share parametric models
        publicly. One such website is McNeelâ€™s
        Grasshopper online forum (grasshopper3d.com) where, between
        8 May 2009 and 22 August 2011, 575 designers shared 2041
        parametric models.</p>

        <p>The collection of
        parametric models on the Grasshopper forum is not entirely
        representative. Most evidently, there are no models created
        in parametric modelling software other than Grasshopper.
        Numerous studies have shown that the modelling environment
        influences the model produced [10-13]. Even if the designer
        has a degree of agency that ensures the model is not
        entirely the product of its environment, it must be assumed
        that the collection of Grasshopper parametric models is not
        entirely representative of models created in other
        modelling environments. A further complication is that the
        models uploaded to the Grasshopper forum often focus on
        specific problems or solutions (generally architectural
        problems and solutions), which means they can often be
        simplifications of larger models. The implications this
        presents are discussed along with the results in each of
        the following sections of this article. Even though the
        collection of 2041 Grasshopper models is not a perfectly
        representative collection, it is a significant advancement
        over any previous study to be able to analyse how hundreds
        of designers organise models created in one popular
        parametric modelling environment.</p>

        <p>To analyse the parametric
        models from the Grasshopper forum, I first download the
        2041 models. The oldest model was from 8 May 2009 and
        created with Grasshopper 0.6.12, and the most recent model
        was from 22 August 2011 and created with Grasshopper
        0.8.0050. All the models were uploaded to the forum in the
        proprietary .ghx file format. I reverse engineered this
        format and wrote a script that extracted the parametric
        relationships from each file and parsed them into a
        directed acyclic graph. Thirty-nine models were excluded in
        this process, either because the file was corrupted or
        because the model only contained one node (which distorted
        measurements like cyclomatic complexity). The graphs of the
        remaining 2002 models were then each evaluated with the
        quantitative metrics discussed in the remainder of this
        article. The measurements were then exported to an Excel
        spreadsheet and analysed. In the analysis I have favoured
        using the median since the mean is distorted by a few large
        outliers. Each of the key quantitative metrics is discussed
        in the following sections.</p>

        <h2>4. Size</h2>

        <p>Code size is one of the
        critical measures of software quality. Software engineers
        commonly measure a programâ€™s size by
        counting the lines of code (LOC). This is a quick
        calculation that proves useful in understanding the
        softwareâ€™s relative size. Barry
        Boehmâ€™s seminal work on the economics of
        software engineering demonstrates that LOC is correlated
        with development effort [14]. In other words, programs with
        more LOC generally take more time to produce. Boehm uses
        this correlation as the basis for the COCOMO estimation
        method, which suggests that the months required to develop
        a typical project is roughly equivalent to 2.4
        Ã— KLOC1.06 (where KLOC is thousands of LOC)
        [14]. Other research has shown that the LOC measurement
        correlates highly with both code complexity [15], and the
        number of coding errors (more lines of code provide more
        opportunities for things to go wrong) [16]. These
        correlations make the LOC measure a valuable instrument for
        quickly establishing a projectâ€™s size
        and estimating its potential cost, complexity, and error
        proneness.</p>

        <p>While the LOC measure is
        quick to calculate, it is also crude. Steven McConnell has
        said â€œthe LOC measure is a terrible way
        to measure software size, except all other ways to measure
        size are worseâ€ [17]. The major limitation of
        the LOC measure is that it doesnâ€™t take
        into consideration the programming language or the
        programming style. A program may take up more or fewer
        lines of code depending on who programmed it and what
        programming language they used. For this reason, orders of
        magnitude matter more than the exact LOC measurement, with
        software engineers often rounding the LOC to the nearest
        thousand.</p>

        <p>In a visual programming
        language like Grasshopper, a node can be considered roughly
        equivalent to a line of code (but given the differences
        between textual lines of code and visual nodes, direct
        comparisons generally cannot be made between the sizes of
        textual and visual programs). The size of a Grasshopper
        model can therefore be measured by simply counting the
        number of nodes in the model.</p>

        <div id="attachment_3984"
        style="width: 490px"
        class="wp-caption
        alignnone"><a href="http://www.danieldavis.com/wp-content/uploads/2014/10/distrablution_size.jpg"><img
        class="size-banner-uncropped
        wp-image-3984" src="http://www.danieldavis.com/wp-content/uploads/2014/10/distrablution_size-480x280.jpg"
        alt="Graph showing distribution of
        parametric model size." width="480" height="280"
        /></a><p class="wp-caption-text">Figure
        1: Distribution of model size in population of 2002
        Grasshopper models.</p></div>

        <p>The sizes of the 2002
        sampled Grasshopper models vary by a number of orders of
        magnitude. The smallest model contains just two nodes while
        the largest model contains 2207 nodes. The distribution of
        sizes has a positive skew (Figure 1) with the median sized
        model containing twenty-three nodes. I suspect the skew is
        partly because many of the models uploaded to the
        Grasshopper forum are snippets of larger models. The median
        may therefore be slightly higher in practice. Even with a
        slightly higher median, the Grasshopper models (including
        the three models that contain more than one thousand nodes)
        are small relative to those seen in the context of software
        engineering â€“ where LOC is often
        measured in multiples of thousands. This is a difference in
        scale that may be the product either of architects not
        requiring larger models, or of Grasshopper being unsuitable
        for producing models of a larger scale. In either case, the
        findings show that the challenges software engineers face
        when managing large software projects are unlikely to be
        felt as acutely by architects, possibly replaced by
        discipline specific concerns of working at this
        scale.</p>

        <div id="attachment_3987"
        style="width: 490px"
        class="wp-caption
        alignnone"><a href="http://www.danieldavis.com/wp-content/uploads/2014/10/pie_chart_2.jpg"><img
        class="wp-image-3987
        size-banner-uncropped" src="http://www.danieldavis.com/wp-content/uploads/2014/10/pie_chart_2-480x195.jpg"
        alt="Pie chart showing typical
        node functions in a parametric model." width="480" height="195"
        /></a><p class="wp-caption-text">Figure
        2: Typical function of nodes in population of 2002
        Grasshopper models.</p></div>

        <p>Given the numbers of
        nodes in a model, it is telling to see the typical function
        of these nodes (Figure 2). 32% of the nodes do something
        related directly to creating, evaluating, or manipulating
        geometry â€“ the core competency of
        Grasshopper. A further 8% of nodes perform mathematic
        functions. Somewhat unexpectedly, the remaining nodes have
        nothing to do with either maths or geometry, they instead
        work to manage data (26%), manipulate lists (20%), or
        explain what is happening in the model (13%). This
        demonstrates that parametric modelling, at least within
        Grasshopper, is as much about managing lists and wrangling
        data as it is about modelling geometry.</p>

        <h2>5.
        Dimensionality</h2>

        <p>An important subset of a
        parametric modelâ€™s overall size is the
        size of the inputs (the number of nodes without parents).
        This tally of the modelâ€™s parameters is
        termed the dimensionality since it determines the number of
        dimensions in the modelâ€™s search space.
        Ideally a model has a dimensionality large enough that the
        designer can change the model by changing a parameter
        instead of changing the underlying structure of the model.
        A high dimensionality would therefore seem desirable since
        it gives the designer more parameters to work with. But
        parameters come at a cost. They require work upfront to
        implement, and they require even more work to change. This
        investment may not pay off if the parameter is rarely used.
        Therefore, the skill of creating a parametric model is
        getting the balance right between too much and too little
        flexibility; between a large dimensionality and a small one
        [18].</p>

        <div id="attachment_3989"
        style="width: 490px"
        class="wp-caption
        alignnone"><a href="http://www.danieldavis.com/wp-content/uploads/2014/10/distrablution_dim.jpg"><img
        class="size-banner-uncropped
        wp-image-3989" src="http://www.danieldavis.com/wp-content/uploads/2014/10/distrablution_dim-480x275.jpg"
        alt="Graph showing typical
        dimensionality of parametric models." width="480" height="275"
        /></a><p class="wp-caption-text">Figure
        3: Distribution of model dimensionality in population of
        2002 Grasshopper models.</p></div>

        <p>The vast majority of
        models have a similar dimensionally; 75% possess between
        one and eleven inputs with the median being six inputs
        (Figure 3). There is no correlation between model size and
        the percentage of inputs (Pearsonâ€™s r =
        âˆ’0.175). A small model with many inputs
        is just as likely as a large model with relatively few
        inputs. I suspect the comparatively low dimensionality
        shown in the vast majority of models may be because
        designers can only comfortably manipulate a few parameters
        at a time. When examining the models with a high
        dimensionality (seventeen models have more then one hundred
        inputs) it is strikingly difficult to understand what each
        input does and even more difficult to change the inputs
        meaningfully en masse. Therefore, while parameters are a
        key component of parametric modelling (some would say the
        defining component) the majority of designers use
        parameters sparingly in their models.</p>

        <div id="attachment_3990"
        style="width: 490px"
        class="wp-caption
        alignnone"><a href="http://www.danieldavis.com/wp-content/uploads/2014/10/cyclomatic_explained_v2_2.jpg"><img
        class="size-banner-uncropped
        wp-image-3990" src="http://www.danieldavis.com/wp-content/uploads/2014/10/cyclomatic_explained_v2_2-480x160.jpg"
        alt="Diagram showing differences
        between cyclomatic complexity" width="480" height="160"
        /></a><p class="wp-caption-text">Figure
        4: Top: A directed acyclic graph comprised of a single
        path, which gives it a cyclomatic complexity of one.
        Bottom: A graph with the same number of nodes as the top
        model but with three distinct paths (each colour coded).
        This graph therefore has a cyclomatic complexity of
        three.</p></div>

        <h2>6. Cyclomatic
        Complexity</h2>

        <p>Cyclomatic complexity is
        a core software engineering metric for measuring code
        structure. The metric works by decomposing textual code
        into a graph and then counting the number of independent
        paths through the graph (Grasshopper models are already a
        graph, which makes them ideally suited for this metric).
        The number of paths is important since it indicates how
        much work is involved in understanding a piece of code. For
        instance, a graph that comprises of a single sequence of
        nodes can be understood by reading sequentially along the
        line (Figure 4). But understanding a more complicated
        graph, where chains of nodes diverge and converge back
        together, requires simultaneously reading many different
        paths (Figure 4). This becomes evermore difficult as the
        number of paths increases. A high cyclomatic complexity
        therefore indicates that a piece of code has a high number
        of independent paths, which potentially requires more
        cognitive energy to understand.</p>

        <p>The original cyclomatic
        complexity formula is as follows [19]:</p>

        <p><a href="http://www.danieldavis.com/wp-content/uploads/2013/09/cyclomatic_formula1.jpg"><img
        class="alignnone size-full
        wp-image-3291" src="http://www.danieldavis.com/wp-content/uploads/2013/09/cyclomatic_formula1.jpg"
        alt="cyclomatic_formula"
        width="274" height="33"
        /></a></p>

        <p>Where:</p>

        <ul>

        <li>G: the
        graph.</li>

        <li>e: number of edges
        (connections between nodes).</li>

        <li>n: number of
        nodes.</li>

        <li>p: number of independent
        graphs.</li>

        </ul>

        <p>This formula assumes the
        graph has only one input node and one output node, which is
        infrequently the case with parametric models. In an
        appraisal of common modifications to the original formula,
        Henderson-Seller and Tegarden show that
        â€œadditional (fictitious)
        edgesâ€ can be introduced to deal with multiple
        inputs and outputs [20]. In these circumstances, the
        cyclomatic complexity formula becomes:</p>

        <p><a href="http://www.danieldavis.com/wp-content/uploads/2013/09/cyclomatic_formula_v3.jpg"><img
        class="alignnone size-full
        wp-image-3290" src="http://www.danieldavis.com/wp-content/uploads/2013/09/cyclomatic_formula_v3.jpg"
        alt="cyclomatic_formula_v3"
        width="304" height="32"
        /></a></p>

        <p>Where:</p>

        <ul>

        <li>i: number of inputs
        (dimensionality).</li>

        <li>u: number of
        outputs.</li>

        <li>While assuming that
        there is only one graph (p = 1).</li>

        </ul>

        <p>In the Grasshopper models
        I counted parallel edges between identical nodes (duplicate
        edges) as a single edge and I did not count non-functional
        nodes such as comments in text boxes.</p>

        <div id="attachment_3994"
        style="width: 490px"
        class="wp-caption
        alignnone"><a href="http://www.danieldavis.com/wp-content/uploads/2014/10/distrablution_complexity.jpg"><img
        class="size-banner-uncropped
        wp-image-3994" src="http://www.danieldavis.com/wp-content/uploads/2014/10/distrablution_complexity-480x274.jpg"
        alt="Graph showing "
        width="480" height="274"
        /></a><p class="wp-caption-text">Figure
        5: Distribution of model cyclomatic complexity in
        population of 2002 Grasshopper models.</p></div>

        <p>There is a high variance
        in the cyclomatic complexity of the sampled models. The
        median complexity is thirteen (Figure 5) but the range
        extends from simple models with a complexity of just one,
        to extremely complex models with a complexity of 1566. The
        difference between complex and simple models is visually
        apparent. The simple models have orderly chains of commands
        while the models of a similar size with a higher cyclomatic
        complexity have interwoven lines of influence that
        obfuscate the relationships between nodes. This seems to
        indicate that cyclomatic complexity is effective in
        classifying parametric models based on the intricacy of
        their structure.</p>

        <div id="attachment_3995"
        style="width: 490px"
        class="wp-caption
        alignnone"><a href="http://www.danieldavis.com/wp-content/uploads/2014/10/comparison.jpg"><img
        class="size-banner-uncropped
        wp-image-3995" src="http://www.danieldavis.com/wp-content/uploads/2014/10/comparison-480x238.jpg"
        alt="Cyclomatic complexity and
        dimensionality vs size." width="480" height="238"
        /></a><p class="wp-caption-text">Figure
        6: Left: Model complexity plotted against size for 2002
        parametric models. These two factors are strongly
        correlated. Right: Model complexity plotted against
        dimensionality and number of outputs for 2002 parametric
        models. The distribution shows inputs correlate more highly
        with complexity (the blue dots are more linear and less
        vertically spread) than outputs (the vertical spread of red
        dots).</p></div>

        <p>A
        modelâ€™s cyclomatic complexity and size
        are strongly correlated (Personâ€™s r =
        0.98; Figure 6). This correlation is significant because it
        indicates that while a parametric model can theoretically
        be both large and simple, in actuality, large models tend
        to be complex. A similar correlation exists in software
        engineering. One such example is van der Meulen and
        Revillaâ€™s survey of fifty-nine textual
        programs that found cyclomatic complexity and LOC to have a
        correlation of r = 0.95 [15]. This correlation suggests
        that complexity is an inevitable by-product of size in both
        software engineering and parametric modelling. Similar
        relationships exist for a modelâ€™s
        dimensionality (r = 0.91) and outputs (r = 0.71), although
        neither correlates with complexity to the same degree as a
        modelâ€™s size (Figure 6).</p>

        <p>McCabe recommends
        restructuring any code with a cyclomatic complexity greater
        than ten [19], a number that has been reaffirmed by many
        subsequent studies [21]. Essentially, large, complicated
        programs should get restructured into smaller, simpler
        modules [19]. Grasshopper supports such modularisation
        using the cluster feature [22]. Of the sampled models, 1553
        were created in a version of Grasshopper that supported
        clusters (either below version 0.6.12 or above version
        0.8.0). Of these, only 39 contained one or more clusters
        â€“ 97.5% were unstructured. Even if the
        definition of structure is expanded to include models that
        are organised without the clusters feature, 48% of models
        have no clusters, no groups, no explanation of what they
        do, and no naming on any of the parameters: by even the
        most generous of definitions these models are completely
        unstructured. In this context â€“ with
        architects creating parametric models that are generally
        unstructured â€“ complexity seems an
        inevitable by-product of model size. Complexity may even a
        limiting factor in the scale of parametric models,
        particularly if large models are always highly
        complicated.</p>

        <h2>7.
        Discussion</h2>

        <p>This research has
        demonstrated that three metrics borrowed from software
        engineering â€“ size, dimensionality, and
        cyclomatic complexity â€“ can be used to
        analyse parametric models. A potential direction for
        subsequent research would be the application of other
        software engineering metrics to parametric models. There
        are hundreds of potential candidates [6, 7], although many
        metrics will not be suitable since they are too specific to
        software engineering (in the ISO/IEC 9126 standard for
        Software Product Quality there are metrics for everything
        from â€˜ease of use of help
        systemâ€™ to â€˜I/O
        devices utilisation satisfactionâ€™ [7]).
        Of those potentially suitable, three promising quantitative
        metrics are construction time, modification time, and
        latency. I suspect there are many more.</p>

        <p>While this research has
        looked at quantitative measures of code, software engineers
        also use a variety of qualitative measures. Bertrand Meyer
        defines â€œsoftware qualityâ€ as
        having ten qualitative aspects: correctness, robustness,
        extendability, reusability, compatibility, efficiency,
        portability, ease of use, functionality, and timelessness
        [23]. For software engineers, these terms become a
        vocabulary through which they can begin to describe the
        nuances of what makes their code successful. There is
        certainly potential for architects to borrow from software
        engineering in order to develop a more rigorous vocabulary,
        quantitative and qualitative, to further describe
        parametric models.</p>

        <p>Another direction for
        future research would be in the application of these
        metrics to the practice of architecture. In software
        engineering, attempts to use quantitative metrics to manage
        programmers have largely failed. Paying a programmer based
        on how many lines of code they produce
        doesnâ€™t make them write faster but
        instead tends to incentivise them to write longer programs.
        Having said that, software engineers have developed a
        number of management techniques to help generate better
        code in practice. At CASE we have been experimenting with
        one method, agile development, in the production of design
        documents. The research is too preliminary to definitively
        report upon, but early results suggest that there is
        significant potential to quantitatively improve the quality
        of architectural work through the management practices of
        software engineers.</p>

        <h2>8.
        Conclusion</h2>

        <p>This study is an
        important first step towards understanding the properties
        and variations of a typical parametric model. The 2002
        Grasshopper models surveyed show that parametric models are
        generally small and complex. The average model contains
        twenty-three nodes and even the largest models, with just
        over one thousand nodes, are modest in the context of
        software engineering. The size of the model is strongly
        correlated with the modelâ€™s complexity,
        which tends to be very high overall. While one may
        intuitively expect that the majority of a parametric model
        consists of parameters and geometry, this study shows that
        organising the graph and managing data are often the most
        common components of parametric models created in
        Grasshopper. Parameters tend to be used surprisingly
        sparingly, with the vast majority of models only containing
        between one and eleven parameters.</p>

        <p>Another important outcome
        from this survey is the validation of the three
        quantitative metrics. The study demonstrates that nodes are
        a good proxy for a modelâ€™s size and that
        the dimensionality can reveal unintuitive insights
        regarding the use of parameters in parametric models.
        Furthermore, the cyclomatic complexity seems to fairly
        accurately differentiate between simple and complex models.
        These three quantitative metrics are some of the first
        words in an emerging vocabulary for articulating the
        qualities of parametric models. Hopefully this vocabulary
        will allow us to move our discussion of parametric
        modelling beyond discussions of individual models and into
        discussions of how populations of models relate and compare
        to one another.</p>

        <h4>Acknowledgements</h4>

        <p>This research was carried
        out as part of my PhD at RMIT University, Melbourne. My
        supervisors, Mark Burry and Jane Burry, both helped in
        setting the direction for this research. The research was
        funded by the Australian Research Council discovery grant
        â€œChallenging the Inflexibility of the
        Flexible Digital Modelâ€, which was led by Mark
        Burry and Jane Burry.</p>

        <h2>References</h2>

        <ol>

        <li>Williams, C., The
        analytic and numerical definition of the geometry of the
        British Museum Great Court Roof, in: Burry, M., Datta, S.,
        Dawson, A., Rollo, A., eds., <em>Mathematics
        Design</em>,
        Deakin University, Geelong, 2001, 434-440.</li>

        <li>Eigensatz, M., Kilian,
        M., Schiftner, A., Mitra, N., Pottmann, H., and Pauly, M.,
        Paneling Architectural Freeform Surfaces, <em>ACM Trans.
        Graphics</em>,
        2010, 29(4).</li>

        <li>Burry, M., Parametric
        Design and the Sagrada FamÃlia, <em>Architectural Research
        Quarterly</em>,
        1996, 1(Summer), 70â€“80.</li>

        <li>Holzer, D., Hough, R.,
        and Burry, M., Parametric Design and Structural
        Optimisation for Early Design Exploration, <em>International Journal of
        Architectural Computing</em>, 2007, 5(4),
        625â€“644.</li>

        <li>Menzies, T., and Shull,
        F., The Quest for Convincing Evidence, in Oram, A. and
        Wilson, G. eds., <em>Making Software: What
        really works, and why we believe it, California</em>,
        Oâ€™Reilly Media, 2010,
        3â€“11.</li>

        <li>Lincke, R., and Lowe,
        W., <em>Compendium of Software
        Quality Standards and Metrics</em>, Self published,
        2007.</li>

        <li>International
        Organisation for Standards, <em>ISO/IEC 9126:
        Information Technology â€“ Software
        Product Quality</em>, 2000.</li>

        <li>MÃ¶ller, K.,
        and Paulish, D., <em>Software Metrics: A
        Practitionerâ€™s Guide to Improved Product
        Development</em>, London, Chapman
        &amp; Hall, 1993.</li>

        <li>Dino, Ä°.,
        Creative Design Exploration by Parametric Generative
        Systems in Architecture, <em>METU Journal of Faculty
        of Architecture</em>, 2012, 29(1),
        207â€“224.</li>

        <li>Janssen, P., and Chen,
        K., Visual Dataflow Modelingâ€¯: A
        Comparison of Three Systems, in Leclercq, P., Heylighen,
        A., and Martin, G., eds., <em>CAAD Futures</em>, LiÃ¨ge: Les
        Ã‰ditions de
        lâ€™UniversitÃ© de
        LiÃ¨ge, 2011,
        801â€“816.</li>

        <li>LeitÃ£o, A.,
        Santos, L., and Lopes, J., Programming Languages for
        Generative Design: A Comparative Study, <em>International Journal of
        Architectural Computing</em>, 10(1), 2012,
        139â€“162.</li>

        <li>Celani, G., and Vaz, C.,
        CAD Scripting And Visual Programming Languages For
        Implementing Computational Design Concepts: A Comparison
        From A Pedagogical Point Of View, <em>International Journal of
        Architectural Computing</em>, 10(1), 2012,
        121â€“138.</li>

        <li>Davis, D., Burry, J.,
        and Burry, M., Yeti: Designing geometric tools with
        interactive programming, in Chen, L., Djajadiningrat, T.,
        Feijs, L., Fraser, S., Kyffin, S., and Steffen, D., eds.,
        <em>Meaning,
        Matter, Making: Proceedings of the 7th International
        Workshop on the Design and Semantics of Form and
        Movement</em>,
        Wellington, Victoria University of Wellington, 2012,
        196â€“202.</li>

        <li>Boehm,
        B., <em>Software Engineering
        Economics</em>,
        New Jersey, Prentice-Hall, 1981.</li>

        <li>Van der Meulen, M., and
        Revilla, M., Correlations between Internal Software Metrics
        and Software Dependability in a Large Population of Small
        C/C++ Programs, in <em>The 18th IEEE
        International Symposium on Software Reliability</em>, Sweden, IEEE Computer
        Society Press, 2007,
        203â€“208.</li>

        <li>El Emam, K., Benlarbi,
        S., Goel, N., and Rai, S., The Confounding Effect of Class
        Size on the Validity of Object-Oriented Metrics,
        <em>IEEE
        Transactions on Software Engineering</em>, 27(7), 2001,
        630â€“650.</li>

        <li>McConnell,
        S., <em>Software Estimation:
        Demystifying the Black Art</em>, Redmond, Microsoft
        Press, 2006.</li>

        <li>Scheurer, F., and
        Stehling, H., Lost in Parameter Space? <em>Architectural
        Design</em>,
        81(4), 2011, 70â€“79.</li>

        <li>McCabe, T., A Complexity
        Measure, <em>IEEE Transactions on
        Software Engineering</em>, 2(4), 1976,
        308â€“320.</li>

        <li>Henderson-Sellers, B.,
        and Tegarden, D., The theoretical extension of two versions
        of cyclomatic complexity to multiple entry/exit modules,
        <em>Software
        Quality Journal</em>, 3(4), 1994,
        253â€“269.</li>

        <li>Watson, A., and McCabe,
        T., Structured Testing: A Testing Methodology Using the
        Cyclomatic Complexity Metric, Gaithersburg, <em>National Institute of
        Standards and Technology</em>, 1996.</li>

        <li>Davis, D., Burry, J.,
        and Burry, M., Understanding Visual Scripts: Improving
        collaboration through modular programming, <em>International Journal of
        Architectural Computing</em>, 9(4), 2011,
        361â€“376.</li>

        <li>Meyer, B., <em>Object-Oriented Software
        Construction</em>, New Jersey,
        Prentice-Hall, 1997.</li>

        </ol>

        </div>

        </article>

        <div id="share">

        <h1>Share</h1>

        <div class="sharebutton"><a
        href="https://twitter.com/share"
        class="twitter-share-button"
        data-via="nzarchitecture"
        data-lang="en" data-count="vertical">Tweet</a></div>

        <div class="sharebutton"><iframe
        src="//www.facebook.com/plugins/like.php?href=http://www.danieldavis.com/quantitatively-analysing-parametric-models/&send=false&layout=box_count&width=450&show_faces=false&font&colorscheme=light&action=like&height=65"
        scrolling="no" frameborder="0"
        style="border:none; overflow:hidden;
        width:450px; height:65px;" allowTransparency="true"></iframe></div>

        <script>!function(d,s,id){var
        js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

        </div>

        <div id="comment">

        <h1>2 comments</h1>

        <ul class="commentlist">

        <li class="pingback even thread-even
        depth-1" id="comment-59146">

        <div id="div-comment-59146"
        class="comment-body">

        <h2>Mentioned <span class="date">

        <a href="http://www.danieldavis.com/quantitatively-analysing-parametric-models/#comment-59146">

        29 October 2014 at 2:17 am
        </a>

        </span>

        </h2>

        <p>[&#8230;]
        Quantitatively Analysing Parametric Models
        â€“ Daniel Davis.
        [&#8230;]</p>

        <div class="reply">

        <a class="comment-reply-link"
        href="http://castroecosta.wordpress.com/2014/10/28/quantitatively-analysing-parametric-models-daniel-davis/">Go
        to website</a>
        </div>

        </div>

        </li><!-- #comment-##
        -->

        <li class="pingback odd alt thread-odd
        thread-alt depth-1" id="comment-59147">

        <div id="div-comment-59147"
        class="comment-body">

        <h2>Mentioned <span class="date">

        <a href="http://www.danieldavis.com/quantitatively-analysing-parametric-models/#comment-59147">

        29 October 2014 at 2:21 am
        </a>

        </span>

        </h2>

        <p>[&#8230;]
        Quantitatively Analysing Parametric Models
        â€“ Daniel Davis.
        [&#8230;]</p>

        <div class="reply">

        <a class="comment-reply-link"
        href="http://dcg.fa.utl.pt/quantitatively-analysing-parametric-models-daniel-davis/">Go
        to website</a>
        </div>

        </div>

        </li><!-- #comment-##
        -->

        </ul>

        <div id="respond">

        <h2>Leave a
        comment</h2>

        <div class="cancel-comment-reply">

        <a rel="nofollow" id="cancel-comment-reply-link"
        href="/quantitatively-analysing-parametric-models/#respond"
        style="display:none;">Click
        here to cancel reply.</a> </div>

        <form action="http://www.danieldavis.com/wp-comments-post.php"
        method="post" id="commentform">

        <div>

        <input type="text" name="author" id="author" value="" size="22" tabindex="1" aria-required='true'
        />

        <label for="author">Name</label>

        </div>

        <div>

        <input type="text" name="email" id="email" value="" size="22" tabindex="2" aria-required='true'
        />

        <label for="email">Email
        (will not be published)</label>

        </div>

        <div>

        <input type="text" name="url" id="url" value="" size="22" tabindex="3" />

        <label for="url">Website
        (optional)</label>

        </div>

        <!--<p>You can use these
        tags: <code>&lt;a href=&quot;&quot;
        title=&quot;&quot;&gt; &lt;abbr
        title=&quot;&quot;&gt; &lt;acronym
        title=&quot;&quot;&gt; &lt;b&gt;
        &lt;blockquote cite=&quot;&quot;&gt;
        &lt;cite&gt; &lt;code&gt; &lt;del
        datetime=&quot;&quot;&gt; &lt;em&gt;
        &lt;i&gt; &lt;q
        cite=&quot;&quot;&gt; &lt;strike&gt;
        &lt;strong&gt;
        </code></p>-->

        <div>

        <textarea name="comment" id="comment" cols="58" rows="10" tabindex="4"></textarea>

        </div>

        <div>

        <input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment"
        />

        <input type='hidden' name='comment_post_ID'
        value='3977' id='comment_post_ID'
        />

        <input type='hidden' name='comment_parent'
        id='comment_parent'
        value='0' />

        </div>

        <p style="display:
        none;"><input type="hidden" id="akismet_comment_nonce"
        name="akismet_comment_nonce"
        value="c4e6d31e16"
        /></p><!-- BEGIN: subscribe to comments
        reloaded --><p><label for='subscribe-reloaded'><input
        style='width:30px'
        type='checkbox' name='subscribe-reloaded'
        id='subscribe-reloaded'
        value='yes' />
        Notify me of followup comments via e-mail.<br/>You can also
        <a href='http://www.danieldavis.com/comment-subscriptions?srp=3977&sra=s'>subscribe</a>
        without commenting.</label></p><!-- END: subscribe to comments
        reloaded --><p
        style="display:
        none;"><input type="hidden" id="ak_js" name="ak_js" value="148"/></p>

        </form>

        </div>

        </div>

        </div>

        <footer id="footer" class="source-org vcard
        copyright">

        <p class="me"><a
        href="http://www.danieldavis.com/about/">Daniel
        Davis</a>,
        2014</p>
        <p class="follow">Connect:
        <a href="http://www.danieldavis.com/feed/">RSS</a>,
        <a href="https://twitter.com/nzarchitecture">Twitter</a>,
        <a href="http://www.facebook.com/daniel.davis">Facebook</a>,
        <a href="http://www.linkedin.com/pub/daniel-davis/35/697/784">Linkedin</a>,
        <a href="http://instagram.com/deardanieldavis">Instagram</a></p>

        </footer>

        </div><!--container-->

        <script type='text/javascript'
        src='http://www.danieldavis.com/wp-content/plugins/akismet/_inc/form.js?ver=3.0.2'></script>

        <script type='text/javascript'
        src='http://www.danieldavis.com/wp-includes/js/comment-reply.min.js?ver=4.0'></script>

        <!-- here comes the javascript
        -->

        <!-- jQuery is called via the
        Wordpress-friendly way via functions.php -->

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

        <!--TODO: Worry about this
        later:

        <script
        src="http://www.danieldavis.com/wp-content/themes/daniel/js/jquery.easing.1.3.min.js"></script>

        <script
        src="http://www.danieldavis.com/wp-content/themes/daniel/js/jquery.quicksand2.js"></script>

        <script
        src="http://www.danieldavis.com/wp-content/themes/daniel/_/js/functions.js"></script>-->

        <script>

        // remap jQuery to $

        (function($){})(window.jQuery);

        /* trigger when page is
        ready */

        $(document).ready(function
        (){

        $("div.synopsis").mouseover(function() {

        $(this).addClass('synopsishover');

        }).mouseout(function(){

        $(this).removeClass('synopsishover');

        }).click(function() {

        var link =
        $(this).find('.more a').attr('href');

        window.location =
        link;

        });

        });

        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){

        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new
        Date();a=s.createElement(o),

        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)

        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

        ga('create',
        'UA-12083514-6', 'danieldavis.com');

        ga('send',
        'pageview');

        </script>

        </body>

        </html>


text:
package security

import (
	"context"
	"strings"
	"time"

	"github.com/cuigh/auxo/errors"
	"github.com/cuigh/auxo/log"
	"github.com/cuigh/auxo/net/web"
	"github.com/cuigh/auxo/security"
	"github.com/cuigh/auxo/security/certify"
	"github.com/cuigh/auxo/security/certify/ldap"
	"github.com/cuigh/auxo/security/passwd"
	"github.com/cuigh/swirl/biz"
	"github.com/cuigh/swirl/dao"
	"github.com/cuigh/swirl/misc"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

// Identifier identifies the user.
type Identifier struct {
	ub         biz.UserBiz
	rb         biz.RoleBiz
	sb         biz.SessionBiz
	realms     []RealmFunc
	extractors []TokenExtractor
	logger     log.Logger
}

func NewIdentifier(s *misc.Setting, ub biz.UserBiz, rb biz.RoleBiz, sb biz.SessionBiz) *Identifier {
	return &Identifier{
		ub:         ub,
		rb:         rb,
		sb:         sb,
		realms:     []RealmFunc{internalRealm(), ldapRealm(s, ub)},
		extractors: []TokenExtractor{headerExtractor, queryExtractor},
		logger:     log.Get(PkgName),
	}
}

func (c *Identifier) Apply(next web.HandlerFunc) web.HandlerFunc {
	return func(ctx web.Context) error {
		token := c.extractToken(ctx)
		if token != "" {
			var user web.User
			if len(token) == 24 {
				user = c.identifyBySession(token)
			} else {
				user = c.identifyByToken(token)
			}
			ctx.SetUser(user)
		}
		return next(ctx)
	}
}

func (c *Identifier) Identify(ctx context.Context, loginName, password string) (identify Identity, err error) {
	var (
		u security.User
		s *dao.Session
	)

	u, err = c.signIn(ctx, loginName, password)
	if err != nil {
		return
	}

	s, err = c.createSession(ctx, u)
	if err != nil {
		return nil, err
	}

	return &UserInfo{
		id:    u.ID(),
		name:  u.Name(),
		token: s.ID,
		perms: s.Perms,
	}, nil
}

func (c *Identifier) signIn(ctx context.Context, loginName, password string) (user security.User, err error) {
	privacy, err := c.ub.FindPrivacy(ctx, loginName)
	if err != nil {
		return nil, err
	}

	if privacy != nil && privacy.Status == biz.UserStatusBlocked {
		return nil, misc.Error(misc.ErrAccountDisabled, certify.ErrAccountDisabled)
	}

	for _, login := range c.realms {
		user, err = login(ctx, privacy, loginName, password)
		if user != nil && err == nil {
			return
		}
	}

	if err == nil {
		err = misc.Error(misc.ErrInvalidToken, certify.ErrInvalidToken)
	}
	return
}

func (c *Identifier) extractToken(ctx web.Context) (token string) {
	for _, e := range c.extractors {
		if token = e(ctx); token != "" {
			return
		}
	}
	return
}

func (c *Identifier) identifyBySession(token string) web.User {
	ctx, cancel := misc.Context(30 * time.Second)
	defer cancel()

	session, err := c.sb.Find(ctx, token)
	if err != nil {
		c.logger.Error("failed to find session: ", err)
		return nil
	} else if session == nil || session.Expiry.Before(time.Now()) {
		return nil
	}

	if session.Dirty {
		if err = c.updateSession(ctx, session); err != nil {
			c.logger.Error("failed to refresh session: ", err)
			return nil
		}
	} else if time.Now().Add(time.Minute * 5).After(session.Expiry) {
		c.renewSession(ctx, session)
	}

	return c.createUser(session)
}

func (c *Identifier) identifyByToken(token string) web.User {
	ctx, cancel := misc.Context(30 * time.Second)
	defer cancel()

	u, err := c.ub.FindByToken(ctx, token)
	if err != nil {
		c.logger.Errorf("failed to find user by token '%s': %s", token, err)
		return nil
	} else if u == nil {
		return nil
	}

	perms, err := c.rb.GetPerms(ctx, u.Roles)
	if err != nil {
		c.logger.Error("failed to load perms: ", err)
		return nil
	}

	return &User{
		token: token,
		id:    u.ID,
		name:  u.Name,
		admin: u.Admin,
		perm:  NewPermMap(perms),
	}
}

func (c *Identifier) createUser(s *dao.Session) web.User {
	return &User{
		token: s.ID,
		id:    s.UserID,
		name:  s.Username,
		admin: s.Admin,
		perm:  PermMap(s.Perm),
	}
}

func (c *Identifier) createSession(ctx context.Context, user security.User) (s *dao.Session, err error) {
	s = &dao.Session{
		ID:       primitive.NewObjectID().Hex(),
		UserID:   user.ID(),
		Username: user.Name(),
		Expiry:   time.Now().Add(misc.Options.TokenExpiry),
	}
	s.MaxExpiry = s.Expiry.Add(24 * time.Hour)
	if err = c.fillSession(ctx, s); err == nil {
		err = c.sb.Create(ctx, s)
	}
	return
}

func (c *Identifier) updateSession(ctx context.Context, s *dao.Session) (err error) {
	if err = c.fillSession(ctx, s); err == nil {
		err = c.sb.Update(ctx, s)
	}
	return
}

func (c *Identifier) fillSession(ctx context.Context, s *dao.Session) (err error) {
	u, err := c.ub.FindByID(ctx, s.UserID)
	if err != nil {
		return err
	} else if u == nil {
		return errors.New("user not found")
	}

	if u.Admin {
		s.Perms = []string{"*"}
	} else {
		s.Perms, err = c.rb.GetPerms(ctx, u.Roles)
		if err != nil {
			return err
		}
		s.Perm = uint64(NewPermMap(s.Perms))
	}

	s.Username = u.Name
	s.Admin = u.Admin
	s.Roles = u.Roles
	return nil
}

func (c *Identifier) renewSession(ctx context.Context, s *dao.Session) {
	expiry := time.Now().Add(misc.Options.TokenExpiry)
	if expiry.After(s.MaxExpiry) {
		expiry = s.MaxExpiry
	}
	err := c.sb.UpdateExpiry(ctx, s.ID, expiry)
	if err != nil {
		c.logger.Errorf("failed to renew token '%s': %s", s.ID, err)
	}
}

type TokenExtractor func(ctx web.Context) string

func headerExtractor(ctx web.Context) (token string) {
	const prefix = "Bearer "
	if value := ctx.Header(web.HeaderAuthorization); strings.HasPrefix(value, prefix) {
		token = value[len(prefix):]
	}
	return
}

func queryExtractor(ctx web.Context) (token string) {
	return ctx.Query("token")
}

type RealmFunc func(ctx context.Context, u *biz.UserPrivacy, loginName, password string) (security.User, error)

func internalRealm() RealmFunc {
	return func(ctx context.Context, u *biz.UserPrivacy, loginName, password string) (security.User, error) {
		if u == nil || u.Type != biz.UserTypeInternal {
			return nil, nil
		}

		if passwd.Validate(password, u.Password, u.Salt) {
			return security.NewUser(u.ID, u.Name), nil
		}
		return nil, misc.Error(misc.ErrInvalidToken, certify.ErrInvalidToken)
	}
}

func ldapRealm(s *misc.Setting, ub biz.UserBiz) RealmFunc {
	const authBind = "bind"
	var r certify.Realm

	if s.LDAP.Enabled {
		opts := []ldap.Option{
			ldap.NameAttr(s.LDAP.NameAttr),
			ldap.EmailAttr(s.LDAP.EmailAttr),
			ldap.UserFilter(s.LDAP.UserFilter),
			ldap.Security(ldap.SecurityPolicy(s.LDAP.Security)),
		}
		if s.LDAP.Authentication == authBind {
			opts = append(opts, ldap.Binding(s.LDAP.BindDN, s.LDAP.BindPassword))
		}
		r = ldap.New(s.LDAP.Address, s.LDAP.BaseDN, s.LDAP.UserDN, opts...)
	}

	return func(ctx context.Context, u *biz.UserPrivacy, loginName, password string) (security.User, error) {
		if r == nil || (u != nil && u.Type != biz.UserTypeLDAP) {
			return nil, nil
		}

		user, err := r.Login(certify.NewSimpleToken(loginName, password))
		if err != nil {
			return nil, err
		}

		var (
			id string
			lu = user.(*ldap.User)
		)
		if u == nil {
			id, err = ub.Create(ctx, &dao.User{
				Type:      biz.UserTypeLDAP,
				LoginName: loginName,
				Name:      lu.Name(),
				Email:     lu.Email(),
			}, nil)
			if err != nil {
				return nil, err
			}
			lu.SetID(id)
		} else {
			lu.SetID(u.ID)
		}
		return user, nil
	}
}

type Identity interface {
	ID() string
	Name() string
	Anonymous() bool
	Token() string
	Perms() []string
}

type UserInfo struct {
	id    string
	name  string
	token string
	perms []string
}

func (u *UserInfo) ID() string {
	return u.id
}

func (u *UserInfo) Name() string {
	return u.name
}

func (u *UserInfo) Anonymous() bool {
	return u.id == ""
}

func (u *UserInfo) Token() string {
	return u.token
}

func (u *UserInfo) Perms() []string {
	return u.perms
}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace Ob\CmsBundle\Admin;

use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormInterface;

abstract class AbstractAdmin implements AdminInterface
{
    /**
     * The entity/document class managed by the admin
     *
     * @var string
     */
    protected $class;

    /**
     * Returns the Entity class
     *
     * @return string
     */
    public function getClass()
    {
        return $this->class;
    }

    public function listPageItems()
    {
        return 25;
    }

    public function listDisplay()
    {
        return array();
    }

    public function listLinks()
    {
        return array();
    }

    public function listSort()
    {
        return array();
    }

    public function listSearch()
    {
        return array();
    }

    public function listFilter()
    {
        return array();
    }

    public function listActions()
    {
        return array();
    }

    public function listOrderBy()
    {
        return array();
    }

    public function listExport()
    {
        return array();
    }

    public function formType()
    {
        return;
    }

    public function formDisplay()
    {
        return array();
    }

    public function listTemplate()
    {
        return;
    }

    public function newTemplate()
    {
        return;
    }

    public function editTemplate()
    {
        return;
    }

    public function inlineAdmin()
    {
        return;
    }

    public function prePersist($entity, FormInterface $form)
    {
        return;
    }

    public function postPersist($entity, FormInterface $form)
    {
        return;
    }

    public function query(QueryBuilder $qb)
    {
        return $qb;
    }
}


text:
include_recipe 'heroku::standalone' if node["heroku"]["preferred_install"] == 'standalone'
include_recipe 'heroku::toolbelt' if node["heroku"]["preferred_install"] == 'toolbelt'
include_recipe 'heroku::gem' if node["heroku"]["preferred_install"] == 'gem'


text:
ES5Harness.registerTest({

    id: "15.4.4.16-2-18",

    path: "TestCases/chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-2-18.js",

    description: "Array.prototype.every applied to String object, which implements its own property get method",

    test: function testcase() {
        function callbackfn1(val, idx, obj) {
            return parseInt(val, 10) > 1;
        }

        function callbackfn2(val, idx, obj) {
            return parseInt(val, 10) > 2;
        }

        var str = new String("432");
        try {
            String.prototype[3] = "1";
            return Array.prototype.every.call(str, callbackfn1) &&
            !Array.prototype.every.call(str, callbackfn2);
        } finally {
            delete String.prototype[3];
        }
    },

    precondition: function prereq() {
        return fnExists(Array.prototype.every);
    }

});


text:
<!doctype html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="Site oficial do Programa de Educação Tutorial da UFMG">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
    <title>PETEE UFMG</title>

    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=pt-BR">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.min.css">

    <link href="css/bootstrap.min.css" rel="stylesheet">

    <link href="css/mdb.min.css" rel="stylesheet">
    <link rel="stylesheet" href="styles.css">

    <link rel="shortcut icon" href="images/logo_manual_oficial.png">

              <input class="mdl-textfield__input" type="text" id="search-field">

              Home
              Currículo Interativo
              Disciplinas
              Atividades Extracurriculares
              Certificados

              <button class="android-more-button mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" id="more-button">
                more_vert
              </button>

Matrícula

Comprovação de Estudos

Intercâmbio

Monitoria/IC/Estágio

Aproveitamento de estudos

Trancamento

Seção de Ensino

FUMP/CEU

Eventos

Carteirinha de Estudante

Contato Professores

Salas

Mapas

          Home
          Currículo Interativo
          Disciplinas
          Atividades Extracurriculares
          Certificados

          Matrícula
          Comprovação de Estudos
          Intercâmbio
          Monitoria/IC/Estágio
          Aproveitamento de Estudos
          Trancamento
          Seção de Ensino
          FUMP/CEU
          Eventos
          Carteirinha de Estudante
          Contato Professores

Carteira de Estudante

arrow_forwardtCarteira de Identificação Única

                Os alunos, professores e servidores  da UFMG recebem uma carteira de identificação que permite o acesso a todos os acervos de bibliotecas da Universidade, aos restaurantes universitários, ao CEU (Centro Esportivo Universitário) e aos demais prédios da UFMG. Não sabe como habilitar a sua carteirinha? A gente te ajuda!

                Primeiro passo: Acesse o portal Minha UFMG e clique, na parte de Sistemas, em "Sistema de Controle de Acesso aos Espaços Físicos".

                Segundo passo: O link em "Clique aqui para acessar seu crachá" vai te levar a uma tela onde está a opção de desbloqueio.

                Nessa tela também existe a opção de bloqueio no caso de perda ou roubo e a opção de solicitar a segunda via. Fácil, não é?

                IMPORTANTE:  Lembre-se que a carteira de identificação serve somente para os ambientes da UFMG, e não é válida para nenhum tipo de meia- entrada.

arrow_forwardtCarteira do DCE

                A carteirinha do DCE (Diretório Central dos Estudantes) proporciona meia entrada em eventos e atividades culturais, artísticas, esportivas e de entretenimento e pode ser adquirida na praça de serviços, na sede do DCE.

                Para confecção da carteirinha, você precisa levar :

                - Formulário para emissão (que pode ser preenchido no momento da solicitação);

                - Comprovante de matrícula atualizado;

                - Documento de Identidade;

                - Foto 3x4;

                - Taxa de R$10,00 (dez reais)

                Se você for assistido pela FUMP nos níveis 1, 2 ou 3, você fica isento da taxa!

© 2017 PETEE UFMG
 -->


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN" "http://www.gemstone.com/dtd/cache7_0.dtd">
<cache search-timeout="60" lock-lease="300">
  <region name="root">
  	<region-attributes/>
  	<!-- Add one entry to the root region -->
	<entry>
		<key><string>Application Version</string></key>
		<value><string>1.0</string></value>
	</entry>

	<!-- Create a new sub region -->
	<region name="PartitionedSubRegion">
    	    <region-attributes early-ack="false" multicast-enabled="false">
      	        <partition-attributes redundant-copies="1" local-max-memory="200" total-num-buckets="11"/>
                <cache-loader>
		    <class-name>org.apache.geode.internal.cache.PartitionedRegionCacheLoaderForSubRegion</class-name>
		    <parameter name="URL">
		        <string>jdbc:cloudscape:rmi:MyData</string>
		    </parameter>
	        </cache-loader>
            </region-attributes>
        </region>
    </region>
</cache>


text:
<!DOCTYPE html>

		<title>404 handler for CMS 11 is out</title>
		<meta http-equiv="REFRESH" content="0; url=/2017/12/18/handler-for-cms11-is-out/">
		<link rel="canonical" href="/2017/12/18/handler-for-cms11-is-out/" />

		This page has moved. You will be automatically redirected to its new location. If you aren't forwarded to the new page, click here.


text:
from django.conf.urls.defaults import *
from django.conf import settings
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from django.views.generic.simple import direct_to_template

from django.contrib import admin
admin.autodiscover()

from account.openid_consumer import PinaxConsumer

if settings.ACCOUNT_OPEN_SIGNUP:
    signup_view = "account.views.signup"
else:
    signup_view = "signup_codes.views.signup"

urlpatterns = patterns('',
    url(r'^$', direct_to_template, {
        "template": "homepage.html",
    }, name="home"),

    url(r'^admin/invite_user/$', 'signup_codes.views.admin_invite_user', name="admin_invite_user"),
    url(r'^account/signup/$', signup_view, name="acct_signup"),

    (r'^about/', include('about.urls')),
    (r'^account/', include('account.urls')),
    (r'^openid/(.*)', PinaxConsumer()),
    (r'^profiles/', include('basic_profiles.urls')),
    (r'^notices/', include('notification.urls')),
    (r'^announcements/', include('announcements.urls')),
    (r'^waitinglist/', include('waitinglist.urls')),

    (r'^admin/(.*)', admin.site.root),
)

if settings.SERVE_MEDIA:
    urlpatterns += patterns('',
        (r'', include('staticfiles.urls')),
    )