Why is “Bug-free” so Hard for Large Systems?

Let us compare a large software system to a group report in school.

Here are the quality requirements for your school report:

  1. Perfect Grammar
  2. Perfect Spelling
  3. Zero Logical Fallacies
  4. Zero Typos
  5. Consistent Voice
  6. Adheres to the Style Guide (e.g. MLA, APA, or Chicago)

Here are some of the facts of the report:

  1. It is over 1000 pages long.
  2. You only wrote 10% of it while the other 90% was written by others.
  3. It was written and edited over the course of several years.
  4. A new Style Guide is chosen every few months.
  5. The teacher changes the report’s topic every month.
  6. Instead of one due date, the report is re-graded every few weeks.
  7. New sections are required for every grading.
  8. After every grading, old sections are returned with edit notes that must be applied.

Easy or Hard? 😛

And of course, we cannot forget this concept:

tasks_2x

Advertisements
Why is “Bug-free” so Hard for Large Systems?

ПИТОН ОБЪЕКТЫ: ИЗМЕНЧИВЫЙ VS. НЕИЗМЕННЫЙ

Note: this is a Russian language translation of the following English post: Python Objects: Mutable vs. Immutable. Thank you to my friends Andrei Rybin and Dimitri Kozlenko for their help in translating!

Не все объекты в Питон обрабатывают изменения одинаково. Некоторые объекты являются изменяемыми, то есть они могут быть изменены. Другие неизменны; они не могут быть изменены, а возвращают новые объекты при попытке обновить. Что это значит при написании кода в Питон?

Этот пост будет об (а) мутабильность общих типов данных и (б) случаях, когда вопрос переменчивости важен.

Изменчивость по типовым разновидностям

Ниже приведены некоторые неизменяемые объекты:

  • int
  • float
  • decimal
  • complex
  • bool
  • string
  • tuple
  • range
  • frozenset
  • bytes

Ниже приведены некоторые изменяемые объекты:

  • list
  • dict
  • set
  • bytearray
  • определяемые пользователем классы (если это специально не сделано неизменяемым)

То, что помогает мне помнить, какие типы изменчивы а какие нет, это что контейнеры и определяемые пользователем типы, как правило, изменяемые, в то время, как скалярные типы почти всегда неизменны. Потом я вспоминаю некоторые заметные исключения: tuple является неизменяемым контейнером, frozenset неизменяемая версия set. Строки неизменны; что если вы хотите, чтобы можно было изменять chars в определенном индексе? Используйте bytearray.

КОГДА мутабильность ВАЖНА

Изменчивость может показаться безобидной темой, но при написании эффективной программы ее необходимо понимать. Например, следующий код является простым решением для складывания строк вместе:

string_build = ""
for data in container:
    string_build += str(data)

На самом деле, это очень неэффективно. Поскольку строки являются неизменяемыми, складывание двух строк вместе фактически создает третью строку, которая является комбинацией двух предыдущих. Если вы перебираете много и строите большую строку, вы будете тратить много памяти на создание и удаление объектов. Кроме того, в конце итерации вы будете выделять и выбрасывать очень большие объекты, что является еще более дорогостоящим.

Ниже приводится более эффективный код в стиле Питона::

builder_list = []
for data in container:
    builder_list.append(str(data))
"".join(builder_list)

### Another way is to use a list comprehension
"".join([str(data) for data in container])

### or use the map function
"".join(map(str, container))

Этот код использует преимущества изменяемости одного объекта LIST, чтобы собрать свои данные вместе, а затем выделить результат в одну строку.. Это сокращает общее число выделяемых объектов почти вдвое.

Еще один подводный камень, связанные с изменчивостью является следующий сценарий:

def my_function(param=[]):
    param.append("thing")
    return param

my_function() # ["thing"]
my_function() # ["thing", "thing"]

То, что вы могли бы подумать, что произойдет в том, что, давая пустой LIST в качестве значения по умолчанию из параметров, это то, что новый пустой LIST будет выделятся каждый раз, когда функция вызывается и ни один LIST не передается. Но что на самом деле происходит, что каждый вызов, который использует LIST по умолчанию будет использовать один и тот же LIST. Это происходит потому, что Python (а) оценивает функции и сигнатуры только один раз (б) оценивает аргументы по умолчанию как часть определения функции, и (с) выделяет один изменяемый LIST для каждого вызова этой функции.

Не ставьте изменяемый объект в качестве значения по умолчанию для параметра функции. Неизменные типы совершенно безопасны. Если вы хотите получить желаемый эффект, сделайте это:

def my_function2(param=None):
    if param is None:
        param = []
    param.append("thing")
    return param

ВЫВОД

Изменчивость важна. Знайте ее Выучите ее. Примитивные типы, скорее всего, неизменны. Контейнерные типы, скорее всего, изменчивые.

References

ПИТОН ОБЪЕКТЫ: ИЗМЕНЧИВЫЙ VS. НЕИЗМЕННЫЙ

Implementing a Mini-React-Redux Framework on a Django Page

Introduction

I have built several production web applications using React and Redux and generally have had an excellent experience with those technologies.  One of React’s greatest assets IMO is it’s ability to integrate into all kinds of stacks and setups but still play nice with the other kids.  That was something that impressed me back in Spring 2014 when I first used React.  We got React running in the jQuery spaghetti code of a massive, legacy Ruby on Rails application with incredibly little effort and huge productivity benefits to the team.  Redux is also incredible for the amount of good it does you with so little code.

There are lot’s of blogs and tutorials on how to build a full single-page application (SPA) complete with client-side routing, persistent state, and even server-side rendering to boost that time-to-interactivity metric.  What if I don’t need that?  What if I already have a site built using an “old-school” server-side framework like Ruby on Rails or Django, but I have one specific page that should be highly interactive and need something more robust than simple jQuery?  React and Redux could still be hugely beneficial, but how do I do it without (a) getting bogged down in boilerplate or (b) over-engineering the solution?

Mini React-Redux Framework to the rescue!

Ready, Set, Go!

Let’s make the skeleton of a super, tiny JavaScript framework that can fit our use case for a Django website.

Here are the steps we’ll follow:

  1. Install our client dependencies
  2. Setup Webpack with Django
  3. Implement the Mini React-Redux Framework

Install our client dependencies

The following are the NPM dependencies I am relying on:

{
  "dependencies": {
    "babel-core": "~6.3.26",
    "babel-loader": "~6.2.0",
    "babel-preset-es2015": "~6.3.13",
    "babel-preset-react": "~6.16.0",
    "react": "~15.4.2",
    "react-dom": "~15.4.2",
    "redux": "~3.6.0",
    "redux-logger": "~2.7.4",
    "redux-thunk": "~2.2.0",
    "webpack": "~1.13.2",
    "webpack-bundle-tracker": "0.0.93"
  }
}

Include these dependencies in your package.json and run npm install.

Setup Webpack with Django

For this step, we are going to use the django-webpack-loader tool to give us the power to load Webpack bundles onto a templated page.  The setup is very simple if you have a vanilla Django application; just follow the loader tutorial.  If you are using Django-Mako-Plus add-on, supplement the regular loader tutorial with my own little tutorial.  I will give a high-level overview.

We need a webpack.config.js. Here is a pre-v2 webpack config file that we can use:

var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');

module.exports = {
  context: __dirname,
  entry: {
    myapp: './client/myapp/index',
  },
  output: {
      // IMPORTANT: Need to match this up with settings STATICFILES_DIRS and WEBPACK_LOADER
      path: path.resolve('./static/bundles/'),
      filename: "[name]-[hash].js",
      // OPTIONAL: In this setup, it can be helpful to namespace the exported files
      library: 'MyCompanyApp',
      libraryTarget: 'var'
  },

  plugins: [
    // IMPORTANT: django-webpack-loader needs to know where this file is
    new BundleTracker({filename: './webpack-stats.json'})
  ],

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          plugins: ['transform-runtime'],
          presets: ['es2015', 'react', 'stage-2'],
          cacheDirectory: true
        }
      }
    ]
  }
}

You will need to throw in some settings for the Django webpack loader plugin so it knows where to find certain key files. Here are some simple defaults:

INSTALLED_APPS = (
    # ...
    'webpack_loader'
)

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

WEBPACK_LOADER = {
    'DEFAULT': {
        # Lets not cache for dev builds; you can enable for prod builds
        'CACHE': False,
        # NOTE: where, inside the staticfiles, are the output? Must end with slash
        'BUNDLE_DIR_NAME': 'bundles/',
        # NOTE: STATS_FILE is the path to the file that the BundleTracker webpack plugin is writing.
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
        'POLL_INTERVAL': 0.1,
        'TIMEOUT': None,
        'IGNORE': ['.+\.hot-update.js', '.+\.map']
    }
}

That should do for now.

Implement the Mini React-Redux Framework

Dan Abramov is a smart guy. He wrote Redux. He encourages devs not to use Redux until you know that you need it; just use Props and State. I strongly support that! However, in this post I want to demonstrate the more complicated case of using Redux including with some middlewares just to show how simple it is. I encourage you to pair this example down to only what you need.

Here is the source I came up with for our mini framework:

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import MyComponent from './components/MyComponent'

/**
 * Redux Reducer.
 * @params:
 *  - state: the previous state of the store
 *  - action: an object describing how the state should change
 * @returns:
 *  - state: a new state after apply appropriate changes
 */
const rootReducer = (state = { clicks: 0 }, action) => {
  // ... change state based on action
  return state
}

/**
 * Redux Store object with three functions you should care about:
 *  - getState(): returns the current state of the store
 *  - dispatch(action): calls the reducer with a given action
 *  - subscribe(): called after a reducer runs
 *
 * The store has two optional middlewares to showcase how you would add them:
 *  - redux-thunk: allows `store.dispatch()` to receive a thunk (function) or an object
 *                 See http://stackoverflow.com/questions/35411423/how-to-dispatch-a-redux-action-with-a-timeout/35415559#35415559
 *  - redux-logger: logs out redux store changes to the console. Only in dev.
 */
const middlewares = process.env.NODE_ENV === 'production'
    ? applyMiddleware(thunk)
    : applyMiddleware(thunk, createLogger())
let store = compose(middlewares)(createStore)(rootReducer)

/**
 * Helper function to render the Gradebook component to the DOM.
 * Makes the following props available to the Gradebook component:
 *  - storeState: an object of the latest state of the redux store.
 *  - dispatch: a function that dispatches actions to the store/reducer.
 */
const render = (nodeId, component) => {
  let node = document.getElementById(nodeId)
  ReactDOM.render(<component storeState={store.getState()} dispatch={store.dispatch} />, node)
}

/**
 * Function that bootstraps the app.
 *  - render the component with initial store state.
 *  - re-render the component when the store changes.
 */
const start = () => {
  render('app', MyComponent)
  store.subscribe(() => render('app', MyComponent))
}

To start the application, (a) load the bundle on the page and (b) call the exported start function when the page loads. Here’s an example using jQuery:

{% load render_bundle from webpack_loader %}
{% render_bundle 'myapp' %}

<script>$(() => MyCompanyApp.start())</script>

Explanation

This little proof-of-concept is interesting to me because of how much usefulness it provides with so little code.  With this code, we create a Redux store with some basic middlewares and a reduce that does nothing interesting (yet).  Then we render a component to the DOM, giving it the current store state and a function for the component to dispatch actions if necessary, and setting up a store subscription so that the component will be re-rendered whenever the store changes.

Another cool part about this approach is that a lot of the setup code can be pulled out and made reusable.  The render(), start(), and store setup would probably be the same for every Mini App we would create.  Then we could simplify this whole file down to just the reducer and passing in the node and component to the start function (not implemented here).

Conclusion

With very little effort and Boilerplate, we have a React application using Redux as it’s storage system.  With this in place, you can build quite sophisticated widgets and still have the flexibility to get more complex if you need to do something more involved.

Implementing a Mini-React-Redux Framework on a Django Page

Adding Webpack Bundles to your Django-Mako-Plus (DMP) Site

This post describes how to hook up Webpack to a Django site using the django-webpack-loader tool in the special case where your Django site is running the Django-Mako-Plus (DMP) library.

Why Webpack?

In the last few years, the ecosystem of JavaScript build tools has grown in both size and quality.  One of my favorite build tools is Webpack.  If you have not heard of it, I highly recommend it to you for bundling your JavaScript, CSS, and other static assets.  To get the most out of this post, please go do a little cursory research on the use case of the webpack bundler before continuing on here.

I also appreciate the Django framework for building dynamic web applications in Python. If you would like to use Django with Webpack, it takes a little extra work to get things hooked together in a clean, scalable way.  Webpack outputs “bundles” that can be formatted in many ways (Common.js, UMD, Require.js, etc.) depending on how they should be consumed and can even output the bundles with the md5 hash in the name to improve the caching of your bundles on the internet.

What is “django-webpack-loader”?

Django, for all its great features, handles static files poorly by modern standards which is where the django-webpack-loader (hereafter referred to as “the loader”) tool comes in.  It provides a way to load a webpack bundle by name into a Django template by mapping the webpack bundle’s “logical name” (e.g. main) to it’s filename (e.g. main-be0da5014701b07168fd.js) which filename changes whenever the contents of the bundle change.  To learn how the loader works, read the documentation and tutorial.

DMP with The Loader

The loader integrates with the templating system of Django.  If you are using Django-Mako-Plus (DMP), you replaced the default templating engine with Mako so the prepared require_bundle helper is not available anymore.  Lucky for us, Mako is so powerful that we can import python functions with ease.  All we need to do in a template is import the right function and call it using Mako syntax:

<%! from webpack_loader.templatetags.webpack_loader import render_bundle %>
<html>
  <head> 
    ${ render_bundle('main') }
  ...

Simple! We can even simplify this a bit by adding the import statement as a DEFAULT_TEMPLATE_IMPORTS for our Mako templates like so:

TEMPLATES = [
  {
    'BACKEND': 'django_mako_plus.MakoTemplates',
    'OPTIONS': {
      # Import these names into every template by default
      # so you don't have to import them explicitly
      'DEFAULT_TEMPLATE_IMPORTS': [
        'from webpack_loader.templatetags.webpack_loader import render_bundle',
      ]
    }
  }
]

BAM!

Conclusion

All done!  You are now ready to start using the django-webpack-loader to include Webpack bundles in your Django-Mako-Plus website!

 

Adding Webpack Bundles to your Django-Mako-Plus (DMP) Site

What is Elm and Why Should I Care?

I gave a talk at Pandamonium 2016, the Instructure engineering conference earlier this year about Elm, the front-end programming language (https://pandamonium2016.sched.org/event/5w4r/what-is-elm-and-why-should-i-care).

The talk is about diving into some of the clever ideas of the Elm programming language and how they can be applied to modern JavaScript development.

After a short introduction to the language, I go into a discussion on the following Elm concepts and their corollaries in the modern JavaScript ecosystem:

  1. Static Analysis
  2. Signal Graphs
  3. Tasks and Effects

The following are the slides from that talk:

Alternate format: http://tgroshon.github.io/elm-pandamonium-pres

What is Elm and Why Should I Care?

Defending JavaScript

In a forum thread, a member brought up the following critiques of JavaScript.  I quickly recognized many of these arguments as ones I have heard before and really wanted to address. In my attempt to not hijack the thread (which was not about “To JavaScript, or Not To JavaScript”), I collected my thoughts here.  This is not meant to be a passive-aggressive post, but rather as an aboveboard rebuttal in a logical discussion.

The Argument Against JS:

…(skipped for brevity)…

I think Javascript has gone a long ways since [I] first started using it, but here are some issues that I have had with it over the time I have used it:

  1. Javascript has a lot of “cute” and “neat” tricks in it, and I feel like people abuse those tricks constantly. In Python there are some cute tricks that you can use, but the community tends to frown upon it.
  2. NPM is such a good and bad experience. Compared to some other package systems its kind of messy. The other issue is that they have this
    “microservice” where instead of writing a one line piece of code they instead pull from NPM to get the same thing done. There was an issue a few months ago where one developer removed his package that thousands of people depended on, and it caused a “dependency hell” per se.
  3. Documentation is lousy on almost all javascript projects. The documentation tools for javascript projects are pretty lousy. When you have worked with docutils/sphinx for python you start to wonder what is wrong with the javascript documentation process.
  4. Lack of stability – this is getting better, but still pretty lousy at times. Almost all javascript projects including node has this issue. Everybody is so into “progressing” the platform that they push
  5. Too many kludges to make it imitate OO
  6. Poor unittesting tools.

My Defense of JavaScript

The arguments above use Python as a language reference point. That’s great! I have used Python for years and love it as well; so I will focus on comparing JS with Python.

1. (Terrible) Language Tricks

Every language has “cute and neat tricks” (read terribleness). JavaScript has more than some languages, but also less than other languages. Many of the “terrible things” in JS are a result of how it runs in the browser (DOM, globals, namespacing) rather than language problems (although JS itself has some bad ones)

The BIG difference with JS you are forgetting is that almost every language can break compatibility relatively freely (e.g. Python 3, Ruby 2, Lua [every version]). JavaScript can’t, because it would break the internet. Bad, wrong-headed decisions can not be removed once people start using them. Websites need to stop using features before they can be removed. Very few other languages have these strict deprecation requirements.

Python has it’s share of weirdness that people use and had a rather large set of breaking changes with Python 3.  Let’s read from the official sources about Python 3:

There are more changes than in a typical release, and more that are important for all Python users. Nevertheless, after digesting the changes, you’ll find that Python really hasn’t changed all that much – by and large, we’re mostly fixing well-known annoyances and warts, and removing a lot of old cruft.

Python had (still has) a big problem with Python 2.7 -> Python 3 upgrades.  Even now, years later, many projects still rely on 2.7 and haven’t upgraded. That situation would never work on the world wide web!

2. NPM

Your argument is against how people have used NPM, not against NPM itself. And the issues you cited are definitely problems, but they are problems for every package manager that reaches the nexus of popularity and ease-of-use. RubyGems had the exact same problem with excessive “micro-gems” 10 years ago.

And that NPM “left-pad” issue that broke everything earlier this year … yeah that could still happen on NPM, PyPi, RubyGems, INSERT_PACKAGE_MANAGER.  Nothing special/bad about NPM made it happen.  Just that a guy decided to be a jerk and remove a package that everyone depended on.

Compare PyPi to RubyGems and NPM and it makes sense why it was such a big deal for NPM: PyPi is notoriously fractured and wierd to publish on (hence smaller); RubyGems and NPM are notoriously easy (hence bigger). The problem of package management is a classic hard problem that nobody has figured out completely from JavaScript, Python, and Ruby to widely used Linux distributions.

3. Docs

JavaScript sucks because a lot of projects don’t write good docs? Not sure I follow the argument. But if you wanted to argue it, you could easily attribute that to the massive number of JavaScript projects vs. Python projects. JavaScript actually has many excellent automated tools for documention.

4. Instability

Patently false. Microsoft, Google, Facebook, Walmart, Mozilla, etc. have poured so much time, effort, and money into the JS ecosystem (specifically Node.js, NPM, and JS Engine implementations) that it has become one of the most stable platforms you can be on. And don’t forget the JS language guarantee that language features can’t be removed until most websites stop using them. Even among browsers, the consistency of good implementation of JS features is at an all time high.

Any instability in Node.js specifically has been largely mitigated with the new release process (Stable and Current distributions). The only “instability” to speak of is the massive volume of updates that V8 goes through to keep up with ECMAScript features, and those only matter to the native library maintainers not using node-gyp (which most use afaik). And even then, Google and Microsoft now work closely with Node.js maintainers to help with API changes in their JS engines.

5. Not OOP

Everything in JS is an object. It just doesn’t use Classical OO. Your argument sounds more like you mean Classical OO vs. Prototypal OO. JS is the latter, and it is just as Object-oriented as Classical; but fundamentally different because Prototypes are objects as well and can be changed at runtime.  To help people wrap their heads around prototypes, ES6 even introduced the keyword class (although I’m not a big fan of it).  In some ways, prototypes are a more true and powerful kind of OOP.  Classes were introduced after OOP landed and primarily to help with static-type checking, not to enable better OOP design.

In the end, JavaScript is multi-paradigm just like Python with a mix of Object-oriented, Functional, and Imperative paradigms.

6. No Unit Testing

Patently false. You will undoubtedly find many testing libraries of very high quality in JS.  And if you want to talk culture of testing in a community; in my experience, in a room with a Rubyist, Pythonista, and JavaScripter, the Python guy is the least likely to be writing tests.

Conclusion

JavaScript as a language, with all the warts and weirdness, is easily one of the fastest evolving languages in the world.

10 years ago, who would have thought this about JS:

  1. Most widely used programming language on earth
  2. One of the fastest scripting languages ever
  3. Largest package ecosystem ever (npm)
  4. Popular as a server backend language

I once shared your disdain of JavaScript, but with the recent incredible work being done on the language itself, it has become one of my favorites.

I’ll close with this slide by Brendan Eich, the creator of JavaScript:

Screenshot 2016-09-01 17.53.16

Defending JavaScript

Deploying Your WebApp the Right Way

Recently, I gave a talk at Brigham Young University to the Association of Information Systems (AIS) club. The talk was well received so I thought I should publish the slides and notes.  Here ya go!

Slides

https://docs.google.com/presentation/d/1qArHkcZt8I-YQxaNW-VhFVN4hznRkwrM59oLkURRmV0/edit?usp=sharing

Executive Summary

The infrastructure and deployment strategies you use for your websites depend heavily on the problems you are trying to solve with them.  You can break down a website into two broad camps:

  1. Static Websites
  2. Web Applications

The characteristics of these kinds of websites mean you will distribute them to end-users very differently and opens up very different avenues of distribution and deployment.

Static websites can be hosted for free through services such as Github Pages or for relatively cheap through AWS S3.  They can even be distributed through Content-Delivery Networks such as AWS CloudFront or CloudFlare which make your site downloads blazing fast.

Web applications are another beast entirely.  They can leverage some of the same tools and services as static websites but in truth they different infrastructure.  Often, this means managing Virtual Private Servers through a cloud provider.  And then, because applications involve custom code, consideration should be given to processes and behaviors such as testing, continuous integration, configuration management, etc.

There is no silver bullet for one, the other, or both.  But knowing the differences between websites and their use cases is the first step to choosing infrastructure and deployment strategies.

Deploying Your WebApp the Right Way