<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Endless Wyrd]]></title><description><![CDATA[The official blog of The Wizard & The Wyrd, LLC.  We are engaged in software and systems research and development with an emphasis on information security, evolutionary machine learning, and AI.]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/</link><generator>Ghost 0.5</generator><lastBuildDate>Tue, 14 Apr 2026 22:27:18 GMT</lastBuildDate><atom:link href="http://wizardandthewyrdblog.azurewebsites.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Benchmarking Python 3, Flask, and Heroku]]></title><description><![CDATA[<h2 id="moresemantics">More semantics...  </h2>

<p>Recently, I have been picking up Python with renewed interest now that a lot of libraries I'm interested in have stable Python3 releases.  Perhaps, again, it is conditioning, but I really love a good IDE when using a language; especially an IDE that gets out of my way, and allows me to be productive.  For me, the biggest advantage of a good IDE is object/class/library browsing.  For this example, I used Visual Studio 2015 Community and the Python Tools for Visual Studio to flawlessly setup my Flask project, configure my Virtual Environment, and manage my requirements.txt.</p>

<p>You can find the source code for this project on <a href="https://github.com/wizardbeard/demoservice_flask">GitHub</a>.</p>

<p>In my last post, I did some benchmarking of <a href="https://wizardandthewyrdblog.azurewebsites.net/ghost/8/">Go, Gin, and Heroku</a>.  I chose Heroku because it is fairly trivial to spin up a new Heroku app: just install the toolbelt, and inside your git repo, run:</p>

<pre><code class="language-bash">$ heroku create
$ git push heroku master
</code></pre>

<p>Also, another interesting aspect to Heroku is that we are deploying our software to a shared PaaS environment on top of some sophisticated virtualization, containerization, and service orchestration layers.  Your compute resources are shared, and this can seriously affect the performance characteristics of your software.  </p>

<p>(I understand I'm not saying anything revolutionary about Heroku, but these comments are for readers that might be entirely new web development and using a Platform as a Service like Heroku or Azure.)</p>

<h2 id="keepdoingonethingwell">Keep doing one thing well  </h2>

<p>Again, I am a huge proponent of the first axiom of <a href="https://en.wikipedia.org/wiki/Unix_philosophy">UNIX philosophy</a>:</p>

<blockquote>
  <p>Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new "features".</p>
</blockquote>

<p>Therefore, from a business perspective, we can roughly state that our Python3/Flask exammple fulfills the same business objectives as our previous Go/Gin example.  The both produce a JSON object containing an "rng" and a random number generated by a Mersenne Twister PRNG.</p>

<p>As stated previously, the Mersenne Twister is often used in regulated gaming (casinos/Class III, Class II, etc.) as an acceptable software psuedo random number generator.  Gaming has different P/RNG needs than, say, cryptography, so using a deterministic algorithm like the Mersenne Twister is perfectly acceptable so that labs can verify the randomness of the PRNG over so many iterations.</p>

<p>In our <a href="https://wizardandthewyrdblog.azurewebsites.net/ghost/editor/8/">Go, Gin, and Heroku</a> example, we used an implementation of the Mersenne Twister written by GitHub user <a href="https://github.com/CasualSuperman/Mersenne-Twister">@CasualSuperman</a>.  In Python 3's standard library, the Mersenne Twister is the default PRNG in <a href="https://docs.python.org/3/library/random.html">random.random()</a>:</p>

<blockquote>
  <p>Almost all module functions depend on the basic function random(), which generates a random float uniformly in the semi-open range [0.0, 1.0). Python uses the Mersenne Twister as the core generator. It produces 53-bit precision floats and has a period of 2**19937-1. The underlying implementation in C is both fast and threadsafe. The Mersenne Twister is one of the most extensively tested random number generators in existence. However, being completely deterministic, it is not suitable for all purposes, and is completely unsuitable for cryptographic purposes.</p>
</blockquote>

<h2 id="interpretedvscompiled">Interpreted vs. Compiled  </h2>

<p>The standard, default implementation of Python, CPython, provides a relatively fast execution environment for our Python code.  Since the underlying Mersenne Twister in Lib\random.py is written in C (as noted above), I was certain that we would see some impressive results for an interpreted language.  Python did not disappoint.  In the future, I'd like to try Jython due to the amazing optimization characteristics of long-running software on top of the JVM.</p>

<p>Go, on the other hand, is interesting due to its garbage collection in addition to being compiled to machine code.</p>

<p>So, while from a technical perspective, comparing an interpreted Python application to a compiled Go application may seem unfair, I tend to look at tooling comparisons, at a high level, from a business and operations perspective.  </p>

<p>At the end of the day, I really like creating durable software that doesn't require a high level of operational maintenance and babysitting.  As noted above, from a business perspective, the Python3/Flask and Go/Gin demo micro services fulfill the same business function.</p>

<p>So, the question becomes, is Flask better than Gin at reducing operating expenses (OpEx) due to reduced compute resources needed to serve our application at scale?  And, do those OpEx savings come with hidden costs in engineering time?  </p>

<h2 id="somecode">Some code  </h2>

<p>Here is the small snippet that handles the default route serving up our JSON:</p>

<pre><code class="language-python">from flask import render_template, jsonify  
from demoservice_flask import app  
import random

@app.route('/')
def generate_rng():  
    """Renders a random number using Python's built-in Mersenne Twister."""
    return jsonify(rng = random.random())
</code></pre>

<h2 id="meatandpotatoes">Meat and Potatoes  </h2>

<p>We ran the same 5 test conditions, using Loader.io, as we did for our Go/Gin test. </p>

<p><strong>Test 1</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/7cc797151210ff3e3b16508420a62adb/widget/results/6dbe1b4290b2ae00346c85389ffafcae"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/7cc797151210ff3e3b16508420a62adb/results/6dbe1b4290b2ae00346c85389ffafcae" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 2</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/7cc797151210ff3e3b16508420a62adb/widget/results/a434569ca59933c4f3576f1e3084ea16"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/7cc797151210ff3e3b16508420a62adb/results/a434569ca59933c4f3576f1e3084ea16" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 3</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/7cc797151210ff3e3b16508420a62adb/widget/results/462c7fd4c5bb60a3c68080e81fb500bf"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/7cc797151210ff3e3b16508420a62adb/results/462c7fd4c5bb60a3c68080e81fb500bf" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 4</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/7cc797151210ff3e3b16508420a62adb/widget/results/8546f400bb29d69d8c9b76ff9dd01cef"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/7cc797151210ff3e3b16508420a62adb/results/8546f400bb29d69d8c9b76ff9dd01cef" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 5</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/7cc797151210ff3e3b16508420a62adb/widget/results/7ea290d7e383e91e6d72b0f6c128dffe"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/7cc797151210ff3e3b16508420a62adb/results/7ea290d7e383e91e6d72b0f6c128dffe" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<h2 id="notevenclose">Not even close  </h2>

<p>Not surpisingly, the Go/Gin performance (over 300,000 without a single HTTP 40x/50x) completely dwarfed the best Python3/Flask response of 49,322 responses in 1 min.</p>

<p>These tests could be more accurate, but they serve as a high level exploratory test of performance capabilities of a single task.  Load testing a web service requires testing every interaction between end-points in the system.</p>

<h2 id="shouldiuseflaskorgin">Should I use Flask or Gin?  </h2>

<p>Like most aspects of software development and engineering, the answer is:</p>

<p><strong>It depends.</strong></p>

<p>Performance isn't the only useful metric by which to decide your tools.  Computations time is usually far less expensive than developers' time.  </p>

<p>There are pros and cons to each languae and framework.  Compared to Python, Go is rather young, and while there are many libraries, answers on StackOverflow, and blogs, the simple fact of the matter is that, today, Python has a much larger community.</p>

<p>And community matters when scouting for talent.</p>

<p>However, it may be that Go provides you performance characteristics that provide a huge benefit to your problem domain, or provides a competitive advantage against your competitors; especially at scale.</p>

<p>Then again, if a team can't get features to market fast enough, it doesn't really matter how fast their code runs.</p>

<blockquote>
  <p>The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming. </p>
  
  <p>Donald Knuth, "Computer Programming as an Art (1974)"</p>
</blockquote>

<p>The performance characteristics of Go may be a premature optimization for your project.  Then again, maybe not.</p>

<p>It depends.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/benchmarking-python-3-flask-and-heroku/</link><guid isPermaLink="false">b7587430-b36f-488a-9bcd-37984a1028cf</guid><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Sat, 02 Jul 2016 06:35:52 GMT</pubDate></item><item><title><![CDATA[Benchmarking Go, Gin, and Heroku]]></title><description><![CDATA[<h2 id="semanticssemantics">Semantics, semantics...  </h2>

<p>I'm not sure if it is conditioning, or aesthetics, but I enjoy C-style syntax, and I feel at home in languages that follow similar semantics.  As a full stack web developer, I am constantly looking for new techniques to build services and applications at scale.  Surprisingly enough, I'm just now taking a look at Google's Go.</p>

<p>Having recently completed the design and implementation of an online game system to support lottery games built in Unity 3D (and targeting WebGL), I am interested in using hindsight to assess how I might have engineered various pieces a bit differently.  In the regulated gaming industry, the Mersenne Twister is often used as a software pseudo-random number generator (PRNG).  Since RNGs form a crucial component of various regulated gaming systems, it seems creating a durable RNG service that combines speed and stability is a high priority.</p>

<p>(In the future, we may explore porting this example to Erlang, Elixir, and other slightly esoteric languages.)</p>

<h2 id="doonethingwell">Do one thing well  </h2>

<p>As a huge fan of "The UNIX Philosophy," it always occurs to me that a micro-service should do one task, and do it rather well.</p>

<p>The code for this demo service is on <a href="http://www.github.com/wizardbeard/demoservice">GitHub</a> and released under the MIT License.</p>

<p>Here is the main code listing (with some thanks to @CasualSuperman on GitHub for the Mersenne Twister in Go):</p>

<h2 id="thecode">The code  </h2>

<pre><code class="language-go">package main

import (  
    "log"
    "net/http"
    "os"
    "sync"
    "math/rand"
    "github.com/gin-gonic/gin"
)

// https://github.com/CasualSuperman/Mersenne-Twister
type Generator struct{  
    state [624]uint32
    index uint32
    generating sync.Mutex
}

func Init(a uint32) *Generator{  
    var t Generator
    t.init(a)
    return &amp;t
}

func (g *Generator) init(a uint32){  
    g.generating.Lock()
    g.state[0] = a
    var i uint32 = 0
    for i=1; i&lt;624; i++{
        g.state[i] = uint32(0x6c078965 * (g.state[i-1] ^
        g.state[i-1]&gt;&gt;30) + i)
    }
    g.generating.Unlock()
}

func (g *Generator) Next() uint32{  
    g.generating.Lock()
    if g.index == 0{
        g.generateNumbers()
    }
    y := g.state[g.index]
    g.index++
    g.index %= 624
    g.generating.Unlock()
    y ^= y&gt;&gt;11
    y ^= y&lt;&lt;7 &amp; 0x9d2c5680
    y ^= y&lt;&lt;15 &amp; 0xefc60000
    y ^= y&gt;&gt;18
    return y
}

func (g *Generator) generateNumbers(){  
    var i uint32
    for i=0; i&lt;624; i++{
        y := g.state[i]&gt;&gt;31 + g.state[(i+1)%624] &amp; 0x7fffffff
        g.state[i] = g.state[(i+397)%624] ^ y&gt;&gt;1
        if y%2 == 1{
            g.state[i] ^= 0x9908b0df
        }
    }
}

func main() {  
    port := os.Getenv("PORT")

    rng := Init(rand.Uint32())

    if port == "" {
        log.Println("$PORT must be set.  Setting to 8080.")
        port = "8080"
    }

    router := gin.New()
    router.Use(gin.Logger())
    router.Static("/static", "./static")

    router.GET("/loaderio-fad37ceadee65cb4bdf707027748bd42", func(c *gin.Context) {
        c.Writer.Write([]byte("loaderio-fad37ceadee65cb4bdf707027748bd42")) // Passes Loader.io verification :)
    })

    router.GET("/", func(c *gin.Context) {
        //c.HTML(http.StatusOK, "index.tmpl.html", nil)
        c.JSON(http.StatusOK, gin.H{
            "rng": rng.Next(),
        })
    })

    router.Run(":" + port)
}
</code></pre>

<h2 id="dynomight">Dyno Might  </h2>

<p>For this project, I decided to deploy our Go micro service, written using the Gin framework, to a free Heroku instance.  To be honest, I wasn't very surprised at the results (well, after a bit of trouble getting the slug to compile and bind to $PORT).</p>

<p>My reasoning is that squeezing some great performance out of a single free-tier Heroku dyno is an interesting exercise in tasting the potential of Go micro services.  Also, I didn't want to provision my own dedicated application server, nor add this micro service to an existing application server.  </p>

<p>(In the future, it wil be interesting to see if I can get this micro service running on an Azure Service Fabric cluster; both on localhost, and on Azure.)</p>

<h2 id="measuretwicethencut">Measure twice, then cut  </h2>

<p>Here are some results from <a href="http://loader.io/">Loader.io</a>.  Here, I also used their free plan; particularly since their free plan is adequate to test my single end-point.</p>

<p><strong>Test 1</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/a08028c80c5436e09d9152f97c655a55/widget/results/306f7881b154f0be3405fcbba964cb8c"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/a08028c80c5436e09d9152f97c655a55/results/306f7881b154f0be3405fcbba964cb8c" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 2</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/a08028c80c5436e09d9152f97c655a55/widget/results/272a44ef6d7b99d41e7126ce84958d6b"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/a08028c80c5436e09d9152f97c655a55/results/272a44ef6d7b99d41e7126ce84958d6b" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 3</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/a08028c80c5436e09d9152f97c655a55/widget/results/85d0593a63f7cc1ebe781cdb8bdd5022"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/a08028c80c5436e09d9152f97c655a55/results/85d0593a63f7cc1ebe781cdb8bdd5022" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 4</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/a08028c80c5436e09d9152f97c655a55/widget/results/926bd4e8015c5afa0a7d2801fdd39036"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/a08028c80c5436e09d9152f97c655a55/results/926bd4e8015c5afa0a7d2801fdd39036" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<p><strong>Test 5</strong></p>

<div style="width: 600px;">  
<iframe width="600" height="300" frameborder="0" src="http://share.loader.io/reports/a08028c80c5436e09d9152f97c655a55/widget/results/548327fecda8f20f099c227eccdd5f2b"></iframe>  
<div style="width: 100%; text-align: right;">  
<a href="http://loader.io/reports/a08028c80c5436e09d9152f97c655a55/results/548327fecda8f20f099c227eccdd5f2b" target="_blank" style="padding: 0 10px 10px 0; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px;">View on loader.io</a>  
</div></div>

<h2 id="over300000">Over 300,000  </h2>

<p>Test 5 was the most successful.  In one minute, we were able to serve up 374,307 pseudo-random numbers with each request returning a 200 OK.</p>

<p><strong>374,307 successful requests/responses.  Not a single 400/500 error.  On a single free dyno.</strong></p>

<p>And that with an average response time of 190 ms.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/benchmarking-go-gin-and-heroku/</link><guid isPermaLink="false">0c724ec0-b8bd-4adb-bb36-12775055ed57</guid><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Thu, 30 Jun 2016 09:47:17 GMT</pubDate></item><item><title><![CDATA[Full Flavor Press?  Delicious.]]></title><description><![CDATA[<p>I am proud to officially announce the creation of our publishing division, <a href="http://fullflavorpress.azurewebsites.net/">Full Flavor Press</a>.</p>

<p>Delicious.  ;)</p>

<p>FFP is now accepting manuscript submission for all types of poetry and prose; everything from novels, to art books, to compilations, to tabletop role playing game supplements and core systems.</p>

<p>FFP is a full-service small press, and we are looking forward to serving authors and audiences of all persuasions.  </p>

<p>After all, Full Flavor Press firmly believes that freedom of speech is more important than political correctness.</p>

<p>Let's write and publish together.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/full-flavor-press/</link><guid isPermaLink="false">878d26c9-4bb7-499c-b6ed-fa706c7f5551</guid><category><![CDATA[Full Flavor Press]]></category><category><![CDATA[Small Press]]></category><category><![CDATA[Full Service Publisher]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Wed, 04 Nov 2015 05:08:15 GMT</pubDate></item><item><title><![CDATA[Existing ERP Systems are Terrible]]></title><description><![CDATA[<p>The great dilemma of Enterprise Resource Planning (ERP) systems is that, by the time an organization is ready and willing to invest in a top-tier ERP system, few projects are as disastrous to an enterprise's resource planning as an ERP implementation!</p>

<p>ERP systems and packages (like SAP, Epicor, Dynamics AX/NAV/GP, Oracle ERP, etc.) have their roots in automating manufacturing processes in the 1960's and 1970's.  A quick glance at database schemas, heavy reliance on procedural programming, licensing models, and user interfaces of these diverse ERP systems shows their age.</p>

<h1 id="terriblearchitectureclosedsource">Terrible Architecture &amp; Closed Source  </h1>

<p>From a software architecture perspective, one of the largest problems with commercial ERP systems is that they try to be all things to all businesses while shoehorning an organization's business processes into the opinionated workflow of the ERP vendor.  Any deviations from the vendors' conflicting visions comes at great cost to an organzition; both in operating expenses, and capital expenses - not to mention the opportunity cost of implementing ERP at the expense of internal innovation. Add, on top of this, integration with existing business systems, and the costs become astronomical.</p>

<p>Not only are the software architectures of existing ERP systems too mature for their own good (meaning, beneficial changes are slow to come and hard to integrate into brittle systems), the source code for the typical ERP system is closed.  This means orgnaizations lose the ability to draw on the software development expertise of thousands of developers at no additional cost to the organization implementing an ERP system.</p>

<h1 id="highlevelcostestimatesfordynamicsax">High-Level Cost Estimates for Dynamics AX  </h1>

<p>Let's look at three common deployment scenarios for Dyanmics AX:</p>

<ul>
<li>3 concurrent users, Financial Modules Only (~$20,000 - $30,000 USD):
<ul><li><strong>Software:</strong> ~$5,000 - 8,000.</li>
<li><strong>Implementation Services:</strong> ~90 to 120 hours of consulting fees including brief requirements analysis (~8 hours), setup, configuration, testing, and training.</li>
<li><strong>Hardware Purchase and Deployment:</strong> ~$12,000 - $20,000 USD if new hardware hasn't been purchased (not including hypervisor and operating system licensing fees).</li></ul></li>
<li>7 - 10 concurrent users, Financials, Sales, &amp; Inventory Modules (~$60,000 - $90,000 USD):
<ul><li><strong>Software:</strong> ~$30,000 USD.</li>
<li><strong>Implementation Services:</strong> ~220 to 320 hours of consulting fees including requirements analysis, setup, configuration, testing, training, and go-live support.</li>
<li><strong>Hardware Purchase and Deployment:</strong> ~$25,000 - $40,000 USD if new hardware hasn't already been purchased (not including hypervisor and operating system licensing fees).</li></ul></li>
<li>12 - 15 concurrent users,  Financials, Sales, &amp; Inventory Modules (~$120,000 - $180,000 USD):
<ul><li><strong>Software:</strong> ~$48,000 USD.</li>
<li><strong>Implementation Services:</strong> ~300 to 450 hours of consulting fees including requirements analysis, setup, configuration, testing, training, and go-live support.</li>
<li><strong>Hardware Purchase and Deployment:</strong> ~$35,000 - $50,000 USD if new hardware hasn't already been purchased (not including hypervisor and operating system licensing fees).</li></ul></li>
</ul>

<p>None of these scenarios include support beyond the first year within the purchase date of the software (support usually starts as soon as you buy, not when you deploy).  It should also be noted that the above scenarios assume the highly unlikely scenario that the implementation will happen on time, within budget, and not need any customizations for an organization's existing business processes.</p>

<h1 id="abetterway">A Better Way  </h1>

<p>ERP systems don't have to be rigid, monolithic, wastes of capital.  By using modern, well-architected ERP software supported by an open source community, flexibility and adaptability become first-class citizens in enterprise.</p>

<p>Arcana ERP is a modern, open source, enterprise resource planning system built upon the OpenCLR and .NET stacks (allowing deployment to Windows Server and Linux infrastructure) supporting a wide range of database back-ends; from SQL Server, to Oracle, to MySQL, to PostgreSQL.</p>

<p>Arcana ERP is built for highly concurent and distributed work-loads using funtional programming and software transactional memory built upon a micro-services architecture built for fault-tolerance and performance.  (Other blog posts go father into depth on the architecture and development of Arcana ERP).</p>

<h3 id="opensourcesoftwaresuccessstories">Open Source Software Success Stories</h3>

<p>The success of open source software can be be seen with:</p>

<ul>
<li>Linux</li>
<li>Apache Software Foundation</li>
<li>GNU</li>
<li>Java</li>
<li>Ruby on Rails</li>
<li>Python</li>
<li>R</li>
<li>MySQL</li>
<li>PostgreSQL</li>
<li>Git</li>
<li>SVN</li>
<li>OpenCLR</li>
<li>Too many more applications to count in a single blog post!</li>
</ul>

<h1 id="stopwastinghardearnedcapital">Stop Wasting Hard-Earned Capital</h1>

<p>Consider trying Arcana ERP today.  Arcana ERP has feature parity with large, entrneched packages like SAP and Dynamics AX, but with full-featured and easy to install open source packages (with well documented APIs for your Developers :).  You can do a complete in-house installation and deployment of Arcana ERP without ever paying a single license fee for Arcana ERP; meaning, your organization can eliminate exorbitant annual licensing fees while drastically reducing development and support costs.</p>

<h1 id="commercialsupportandcustomdevelopment">Commercial Support and Custom Development</h1>

<p>Although Arcana ERP gives you broad and deep functionality our of the box, we understand the need for commercial support and Service Level Agreements.  The Wizard &amp; The Wyrd, LLC offers Arcna ERP long-term support and custom development at a fixed-rate of 25% of your current annual ERP licensing fees.  We will never raise our rates, and you are not required to share any custom developments with the rest of the open source community (we understand the need to protect intellecutal property and the competitive advantages of your well-tuned business processes).</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/practically-all-erp-is-terrible/</link><guid isPermaLink="false">a533225a-67a9-4e5f-b005-3b5bd41987f8</guid><category><![CDATA[erp]]></category><category><![CDATA[project management]]></category><category><![CDATA[licensing fees]]></category><category><![CDATA[dynamics ax]]></category><category><![CDATA[SAP]]></category><category><![CDATA[open source]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Thu, 15 Oct 2015 10:53:37 GMT</pubDate></item><item><title><![CDATA[F#, C#, and dotPeek]]></title><description><![CDATA[<p>As development continues on Arcana ERP, we see that in order to fulfill our design goals of high availability and distributed concurrency, portions of ArcanaErp.Core are being re-written piece by piece in F# (a general purpose functional programming langauge, targeting .NET, and originally developed at <a href="https://en.wikipedia.org/wiki/Microsoft_Research">Microsoft Research, Cambridge</a>).</p>

<p>An interesting outcome of this experiment is that we can see concise, expressive, and terse idiomatic F# "expand" into equivalent, and more verbose, C#:</p>

<h2 id="fsource">F# Source  </h2>

<pre><code class="language-fsharp">namespace ArcanaErp.Core.Lambda

open System

module Interfaces =

    type IBaseErpModel =
        abstract member Id : int with get, set
        abstract member Description : string with get, set
        abstract member ExternalIdentifier : string with get, set
        abstract member ExternalIdSource : string with get, set
        abstract member CreatedAt : DateTime with get, set
        abstract member UpdatedAt : DateTime with get, set
</code></pre>

<h2 id="dotpeekdc">dotPeek'd C#  </h2>

<pre><code class="language-csharp">using Microsoft.FSharp.Core;  
using System;

namespace ArcanaErp.Core.Lambda  
{
  [CompilationMapping(SourceConstructFlags.Module)]
  public static class Interfaces
  {
    [CompilationMapping(SourceConstructFlags.ObjectType)]
    [Serializable]
    public interface IBaseErpModel
    {
      int Id { get; set; }

      string Description { get; set; }

      string ExternalIdentifier { get; set; }

      string ExternalIdSource { get; set; }

      DateTime CreatedAt { get; set; }

      DateTime UpdatedAt { get; set; }
    }
  }
}
</code></pre>

<h1 id="abiggerexample">A Bigger Example  </h1>

<h2 id="firstinf">First, in F#  </h2>

<p>The previous example was fairly straightforward.  We see some extra curly braces and some attributes we can get rid of.  Here is a sample from the FSharp.Core assembly in the <a href="https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/seq.fs">Microsoft.FSharp.Collections namespace</a>:</p>

<pre><code class="language-fsharp">        [&lt;CompiledName("IterateIndexed")&gt;]
        let iteri f (source : seq&lt;'T&gt;) = 
            checkNonNull "source" source
            use e = source.GetEnumerator()
            let f = OptimizedClosures.FSharpFunc&lt;_,_,_&gt;.Adapt(f)
            let mutable i = 0 
            while e.MoveNext() do
                f.Invoke(i, e.Current);
                i &lt;- i + 1;
</code></pre>

<h2 id="decompiledtoc">Decompiled to C#  </h2>

<pre><code class="language-csharp">    [CompilationArgumentCounts(new int[] {1, 1})]
    [CompilationSourceName("iteri")]
    public static void IterateIndexed&lt;T&gt;(FSharpFunc&lt;int, FSharpFunc&lt;T, Unit&gt;&gt; action, IEnumerable&lt;T&gt; source)
    {
      if ((object) source == null)
        throw new ArgumentNullException("source");
      System.Collections.Generic.IEnumerator&lt;T&gt; enumerator = source.GetEnumerator();
      try
      {
        OptimizedClosures.FSharpFunc&lt;int, T, Unit&gt; fsharpFunc = OptimizedClosures.FSharpFunc&lt;int, T, Unit&gt;.Adapt(action);
        int num = 0;
        while (enumerator.MoveNext())
        {
          fsharpFunc.Invoke(num, enumerator.Current);
          ++num;
        }
      }
      finally
      {
        IDisposable disposable = enumerator as IDisposable;
        if (disposable != null)
          disposable.Dispose();
      }
    }
</code></pre>

<h1 id="wrappingup">Wrapping Up  </h1>

<p>It is clear to see that F# is the winner here.  The F# code is more compact, more expressive, and easier to reason about (after, admittedly, a small learning curve on the F# syntax).  </p>

<p>Writing software as complex as an ERP systems, and enterprise software in general, requires code that can be reasoned about fairly easily.  On all accounts, for us, F# makes sense.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/initial-experiments-with-fsharp-and-csharp/</link><guid isPermaLink="false">462503e0-324f-481f-8057-e48aad63bbda</guid><category><![CDATA[enterprise development]]></category><category><![CDATA[F#]]></category><category><![CDATA[FSharp]]></category><category><![CDATA[dotPeek]]></category><category><![CDATA[Programming]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Tue, 13 Oct 2015 04:34:15 GMT</pubDate></item><item><title><![CDATA[Flawfinder 1.31 & Ruby 2.2.x-master]]></title><description><![CDATA[<p><a href="https://www.ruby-lang.org/en/">Ruby</a> is one of the most popular pogramming languages in production use for a variety of systems and applications; most notably, we see wide adoption in web application development with the Ruby on Rails framework and DevOps tooling with the likes of Puppet and Chef.</p>

<p>The Ruby language, compared to other languages used to build and deliver web applications, has a comparitively small list of disclosed exploits on the CVE (Common Vulnerabilities and Exposures) list.</p>

<p>For reference, here is a list of historical CVE disclosures to date for a handful of languages/platforms used to develop web applications:</p>

<ol>
<li>Python: <a href="http://www.cvedetails.com/product/18230/Python-Python.html?vendor_id=10210">23</a>  </li>
<li>Ruby: <a href="http://www.cvedetails.com/vulnerability-list/vendor_id-7252/product_id-12215/Ruby-lang-Ruby.html">45</a>  </li>
<li>PHP: <a href="https://www.cvedetails.com/vulnerability-list/vendor_id-74/product_id-128/PHP-PHP.html">409</a>  </li>
<li>Oracle JRE: <a href="https://www.cvedetails.com/vulnerability-list/vendor_id-93/product_id-19117/Oracle-JRE.html">413</a></li>
</ol>

<p>Here is the result of running Flawfinder 1.31, with the default rules in the Homebrew distribution, against the master branch of the <a href="https://github.com/ruby/ruby">current Ruby 2.2.x source code</a>:</p>

<pre><code>ANALYSIS SUMMARY:

Hits = 636  
Lines analyzed = 197285 in approximately 3.93 seconds (50139 lines/second)  
Physical Source Lines of Code (SLOC) = 141537  
Hits@level = [0]   0 [1] 246 [2] 288 [3]  35 [4]  52 [5]  15  
Hits@level+ = [0+] 636 [1+] 636 [2+] 390 [3+] 102 [4+]  67 [5+]  15  
Hits/KSLOC@level+ = [0+] 4.49352 [1+] 4.49352 [2+] 2.75546 [3+] 0.72066 [4+] 0.473374 [5+] 0.105979  
Minimum risk level = 1  
Not every hit is necessarily a security vulnerability.  
There may be other security vulnerabilities; review your code!  
See 'Secure Programming for Linux and Unix HOWTO'  
(http://www.dwheeler.com/secure-programs) for more information.
</code></pre>

<p>These results, at first glance, may prove interesting:  </p>

<pre><code>./addr2line.c:449:  [4] (buffer) strcpy:
  Does not check for buffer overflows when copying to destination (CWE-120).
  Consider using strcpy_s, strncpy, or strlcpy (warning, strncpy is easily
  misused).
./addr2line.c:450:  [4] (buffer) strcpy:
  Does not check for buffer overflows when copying to destination (CWE-120).
  Consider using strcpy_s, strncpy, or strlcpy (warning, strncpy is easily
  misused).
./addr2line.c:723:  [4] (buffer) strcpy:
  Does not check for buffer overflows when copying to destination (CWE-120).
  Consider using strcpy_s, strncpy, or strlcpy (warning, strncpy is easily
  misused).
</code></pre>

<p>For the complete test results, see this <a href="http://pastebin.com/Bu8TNgBp">Paste</a>.</p>

<p>Simply scanning the Ruby source of this particular implementation of Ruby with a single static analysis tool should be considered a preliminary exercise for more research.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/flawfinder_and_ruby/</link><guid isPermaLink="false">8d67efef-6471-41c8-811e-b03ec43442ed</guid><category><![CDATA[ruby]]></category><category><![CDATA[static analysis]]></category><category><![CDATA[infosec]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Sat, 03 Oct 2015 02:02:45 GMT</pubDate></item><item><title><![CDATA[The Snow Would Thaw]]></title><description><![CDATA[<p>Interest in Ariticial Intelligence leads one to the famed "AI Winter," and there were two majors seasons: from 1974 - 1980, and another "AI Winter" from 1987 - 1993.  During these times, the promises of a new paradigm in computing ushered in by the prophets of artiifical intelligence did not come to pass.</p>

<blockquote>
  <p>The snow would thaw, the rivers begin to run and the world would wake into itself again.</p>
</blockquote>

<p>So wrote Neil Gaiman in "Odd and The Frost Giants."</p>

<p>Today, in 2015, we see an encroachment of Ariticial Intelligence, under the form of deep machine learning, penetrating nearly every aspect of our interconnected social lives.</p>

<p>Unfortunately, like most advancements in the sum of human knowledge, this amazing technology is being used to siphon more dollars from your provate coffers.  Afterall, the greatest virtue of modern business appears to be maximizing value for shareholders.</p>

<p>Let me be perfectly clear: as a small business, we love revenue and profit.  What we don't love is the commoditization of the invasion of personal privacy to slake the lusts of marketing executives in their never-ending quest to sell you garbage.  We are critical of Facebook's strategy to pursue deep machine learning in order to creat an even more effective advertising platform.</p>

<p>Of course, painting in broad strokes while creating generalizations is fraught with the danger that communication will degenerate into disinformation and propaganda.  However, we are not convinced that the ubiquitous proliferation of social media over the past decade is an automatic net benefit to the prosperity of humanity.</p>

<p>Yes, information technology, and social media in particular, are allowing groups of dissatisfied populations the ability to coordinate everything from revolutions to corporate boycotts.</p>

<p>But at what price?  </p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/the-snow-would-thaw/</link><guid isPermaLink="false">4ada19d3-cfea-4c2d-92f8-077b1182ba5d</guid><category><![CDATA[philosophy]]></category><category><![CDATA[ai winter]]></category><category><![CDATA[marketing]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Sat, 03 Oct 2015 00:26:08 GMT</pubDate></item><item><title><![CDATA[Is passion always necessary?]]></title><description><![CDATA[<p>Throughout my career, I have had the great fortune - at various times - of being mentored by self-made men and women.  A casual reading of any success story usually reveals a protagonist to be a heroic character full of passion.</p>

<p>I think most of us, at some time or another, have felt an overhwelming feelings of desire to achieve personal excellence along a particular path; whether that be something as abstract as "entrepreneurship" or some definite goal like "published author" or "professional game developer."</p>

<p>But is passion really necessary for any measure of success?</p>

<p>I often find that consistent self-discipline is far more useful to success than any amount of passion.  A long view of history means we should take the perspective that we take the immortal perspective of having omnipotence and eternity at our disposal while being acutely aware that time is a finite resource.  </p>

<p>We can always find new lovers, earn more money, have new adventures, play more games, and drink more beer.  However, every passing day rapidly depletes our store of Time which we find rapidly appreciates in combinatorial explosions of value as supplies accelerate towards oblivion in lock-step with our mortality.</p>

<p>If popular notions of reincarnation are somehow objectively true, then there is no reason to delay doing whatever needs to be done - today! - to come closer the far-end of the bell curve of human potential so that we can reap the rewards of our creative success for lifetimes to come (even if that success comes posthumously!).</p>

<p>If popular notions of reincarnation are nothing more than confortable lies we tell ourselves to soothe the knowledge that every breath hurls us closer to the grave, there is no reason to avoid doing whatever needs to be done - right now! - to traverse the abyss of time, pregnant with habitually discipline, that separates the average from the legendary.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/personal-satisfaction/</link><guid isPermaLink="false">9218afa7-353d-4f0d-a02d-516cdbc05f34</guid><category><![CDATA[philosophy]]></category><category><![CDATA[business]]></category><category><![CDATA[success]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Wed, 23 Sep 2015 05:36:56 GMT</pubDate></item><item><title><![CDATA[Hello]]></title><description><![CDATA[<p>Thanks for stopping by.  We are currently working on our first book, and after our trademarks and copyrights are filed with the appropriate big brothers, we will start tantalizing our audience with dark tales of the macabre; with stories of pain, initiation, and cold-blooded revenge.</p>

<h2 id="whoarewe">Who are we?</h2>

<p>The Wizard &amp; The Wyrd, LLC, a small studio with big aspirations, was formed by long-time friends Ramon J. Long III and Jeremy Dolan.  Jeremy is a sleeping titan waiting to unleash his illustrative talents upon a global audience, and Ramon is a writer with a gruesomely psychedelic and mystical story inspired by the underbelly power elite.</p>

<h3 id="whatisthewizard">What is The Wizard?</h3>

<p>The Wizard represents the primordial archetype of the cunning folk, of the wise man versed in the mysteries of cosmos (including its numerous heavens and hells).  The Wizard is the master of Magick whereby, through his art and science, his Will is made to reverberate throughout the Universe is a wide variety of forces and forms.</p>

<h3 id="whatisthewyrd">What is The Wyrd?</h3>

<blockquote>
  <p>Wyrd is a term for concepts roughly corresponding to those of fate or destiny but involving complex interactions of universal necessity and individual choice within a cosmos beyond any fixed notions or concepts of mortal minds.</p>
</blockquote>

<p>Since the Autumn of 2002, Ramon has been brooding over creating an independent studio to publish the works of his extremely talented friends, cohorts, and accomplices.  A lot has changed since then, and this vision to create a multi-media production studio - on our own terms - remains unchanging, and we have begun working on our first comic series; a six issue comic series that will be bound into a hard-cover graphic novel.</p>]]></description><link>http://wizardandthewyrdblog.azurewebsites.net/hello/</link><guid isPermaLink="false">a3df8471-3459-4f4c-896d-70759a9964f2</guid><category><![CDATA[news]]></category><dc:creator><![CDATA[Ramon J. Long III]]></dc:creator><pubDate>Mon, 26 Jan 2015 04:24:15 GMT</pubDate></item></channel></rss>