Skip to content

Instantly share code, notes, and snippets.

@JesseAldridge
Last active September 21, 2018 02:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JesseAldridge/17c1bcd7ecd17ed5ce98fef0132c5c98 to your computer and use it in GitHub Desktop.
Save JesseAldridge/17c1bcd7ecd17ed5ce98fef0132c5c98 to your computer and use it in GitHub Desktop.

I have a highly simplistic proof of concept: https://github.com/JesseAldridge/critter

Right now it's just -- I have these six hardcoded functions: https://github.com/JesseAldridge/critter/blob/master/python_version/blocks.py

One of which is just:

class IsLetter(Block):
  def call_(self, ch):
    return ch.isalpha()

Now I can run the following test against all six of the functions and return the one that makes the tests pass: https://github.com/JesseAldridge/critter/blob/master/python_version/test_is_letter.py

block.call('a') == True
block.call('8') == False
block.call('#') == False

One obvious problem is different functions take different parameters. The solution of course is to only call functions that have an appropriate signature:

https://github.com/JesseAldridge/critter/blob/master/python_version/blocks.py#L11

class Block
  ...

  def call(self, *a):
    # If the passed arguments match the child class's call signature
    #   Call the child class's call method
    # Otherwise do nothing
    ...

What if a function requires initialization before it can be used? Well instead of calling them functions, let's call them "blocks", where block basically means "code module" or "collection of functionality".

https://github.com/JesseAldridge/critter/blob/master/python_version/blocks.py#L19

class FindAllFiles(Block):
  def init_(self, dir_path):
    # read all the files in the passed directory into an index
    ...

  def call_(self, query_string):
    # search the index for the passed `query_string` and return the results
    ...

And let's add an initialization step to our test.

https://github.com/JesseAldridge/critter/blob/master/python_version/test_find_all_files.py

def init(block):
  # Create test directory with a couple test files.
  #
  # filename: "test_dir/1.txt"
  # content:  "some text"
  #
  # filename: "test_dir/2.txt"
  # content:  "other text"

  ...

  # now do any initialization the block needs to do before being used
  block.init('test_dir')

def test(block):
  return (
    block.call('some') == ['test_dir/1.txt'] and
    block.call('other') == ['test_dir/2.txt'] and
    block.call('text') == ['test_dir/1.txt', 'test_dir/2.txt'] and
    block.call('nothing') == []
  )

Ok, cool, so that works. What else can we do with this thing? Can we build a web app? Let's start with "hello world":

function test(block, done) {
  block.call();
  request('localhost:5000', function (error, response, body) {
    if (!error && response.statusCode == 200) {
      done(body == 'hello world');
    }
    done(false);
  });
}

https://github.com/JesseAldridge/tacovote/blob/master/xtests/main_test.js

This test could be satisfied by this code:

var Hapi = require('hapi');

var server = new Hapi.Server();
server.connection({
    host: 'localhost',
    port: 5000
});

server.route({
    method: 'GET',
    path:'/',
    handler: function (request, reply) {
        reply('hello world');
    }
});

server.start();

Interestingly, this exact code snippet can be found on StackOverflow: https://stackoverflow.com/questions/29374927/getting-started-with-hapi-js (I wrote the test without knowing that.)

Even more interestingly, StackExchange produces regular dumps of their entire database for use by the public: https://archive.org/details/stackexchange

The vast majority of the code snippets are even conveniently wrapped in <code>...</code> tags, which makes them easy to extract: https://github.com/JesseAldridge/Stackoverflow-Posts

If you're still with me, I think you will agree that while there are a ton of obvious problems here, there are also a lot of very exciting possibilities. The most important of which I think is allowing people to obtain functioning software not by explaining in detail how to do something but by describing what the end result should be. Few people have the skills necessary to do the former, but I think just about anyone should be able to do the latter.

So that's where I'm at right now.

The obvious problems I'm thinking about today, as we speak:

How can I install every well known software package in an accessible way?

Actually I lied earlier, the hello world snippet does not exactly match the StackOverflow result. The port number is different and the path is /hello instead of /. So somehow I would need to identify meta-variables in code snippets or something.

How far can I take this approach? I've demonstrated that it can work in trivial cases. But real world code is vastly more complicated than the cases I've described here. I'll have to get back to you on that one...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment