Code Style Guide

Good code samples are the core of a great Kite Answer. This document will show you how to write a good code sample -- one that demonstrates how to use a function, class, or API in an easy and quick to understand way.

Goals

With every code sample we write, we aim for:

  • Readability -- How much mental energy does it take for a reader to understand the sample?
  • Concision -- How long does it take to read the sample?
  • Simplicity -- How difficult is it to interpolate this sample with the reader's current code?
  • Consistency -- how difficult is it to find the similarities and differences between this code sample and the other code samples in the article?

Fortunately, these goals usually overlap with each other. But do not follow these guidelines when they do not make sense. Instead, use your best judgment about when to bend or break these rules.

In this document, good code samples are shown like this:

print("This is a positive example of how to write good code samples.")

And negative samples, showing what not to do, are shown like this:

print 'This is a negative example showing how NOT to write code samples.'

Examples of good code samples

How to write a simple object as JSON

KITE.start_prelude()
import json
KITE.stop_prelude()

print(json.dumps({"a":1}))

# OUTPUT
{"a": 1}

This code sample is excellent because:

  • the main code section is short and quick to understand
  • it shows one concept and does not try to show other concepts in the same sample
  • the import statement is in the prelude, because it is necessary to run the code sample but is not the most important part of the sample

How to reverse a deque object

KITE.start_prelude()
import collections
KITE.stop_prelude()

d = collections.deque([1, 2, 3])
d.reverse()
print(d)

# OUTPUT
deque([3, 2, 1])

This code sample is excellent because:

  • it is short and can be understood very quickly
  • it is easy to match the input [1, 2, 3] with the output [3, 2, 1], which makes the effect of reverse() clear
  • it shows one concept and does not try to show other concepts in the same sample
  • the import statement is in the prelude, because it is necessary to run the code sample but is not the most important part of the sample
  • the print function call is in the main code section, so the user can match the print function call with the output

How to inspect the arguments of a function

KITE.start_prelude()
import inspect
KITE.stop_prelude()

def f(a, b=2, *args, **kwargs):
    return a

print(getargspec(f))

# OUTPUT
ArgSpec(args=['a', 'b'], varargs='args', keywords='kwargs', defaults=(2,))
This code sample is excellent because:

  • it is short and can be understood easily
  • it shows one concept and does not try to show other concepts in the same sample
  • it uses simple placeholders for the function and argument names
  • it demonstrates all of the features of the function

How to extract the query string from a request on a Werkzeug server

KITE.start_prelude()
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run-simple
KITE.stop_prelude()

def application(environ, start_response):
    request = Request(environ)
    query = request.args.get("query")

    response = Response("You searched " + query)
    return response(environ, start_response)

This code sample is excellent because:

  • the concept is demonstrated in the context of a minimal Werkzeug application
  • the incidental code is limited to only what is necessary, while still showing the context of the sample
  • the main code section contains only server-related code; imports and running the server are outside of it

Guidelines

The guidelines here are probably different from traditional coding style guidelines. Our guidelines focus on our goals of readability, concision, simplicity, and consistency. For example, many coding style guidelines recommend modularity and reusability, which are important in software engineering but not in our explanatory code samples.

Fundamental Concepts

Show only one concept per code sample

Examples

This sample shows two independent concepts, which is bad:

data = [1, 2, 3]
print(map(lambda x: x*2, data))
print(filter(lambda x: x<3, data))

Instead, split this into two separate samples:

data = [1, 2, 3]
print(map(lambda x: x*2, data))

data = [1, 2, 3]
print(filter(lambda x: x<3, data))

However, use a single sample to demonstrate the multiple ways to use a particular function.

# ANSWER: How to retrieve the timezone from a string

print(gettz())
print(gettz("UTC"))
print(gettz("America/Los Angeles"))

Duplicate code instead of using loops or extra variables

It is usually better to copy a line of code two or three times with small modifications than introduce a loop. It takes less time for a human to understand three duplicated lines with small changes than to understand a loop.

Examples

d = defaultdict(list)

d["a"].append(1)
d["b"].append(2)
d["c"].append(3)

print(d)

The same sample using a loop takes longer to understand, even though there are fewer lines of code:

d = defaultdict(list)

for i, v in enumerate(["a", "b", "c"]):
    d[v].append(i)

print(d)

Minimize look-back distance

Try to keep variables close to the line where they are used. If you need to use a variable multiple times, consider replacing the variables with their literal values. Variables that are used too often get too far from their definition, and a user has to search for the value.

Examples

document = "document_a.txt"
print(fnmatch(document, "*.txt"))
print(fnmatch(document, "document_?.txt"))
print(fnmatch(document, "document_[abc].txt"))
print(fnmatch(document, "document_[!xyz].txt"))

print(fnmatch("document_a.txt", "*.txt"))
print(fnmatch("document_a.txt", "document_?.txt"))
print(fnmatch("document_a.txt", "document_[abc].txt"))
print(fnmatch("document_a.txt", "document_[!xyz].txt"))

a = f.open("a.txt")
b = f.open("b.txt")

a.write("A")
b.write("B")

a.close()
b.close()

a = f.open("a.txt")
a.write("A")
a.close()

b = f.open("b.txt")
b.write("B")
b.close()

Use newlines only to separate functionality, and do not separate outputs

Aside from class and function definitions, newlines should only be used to separate multiple sections of functionality to make the code sample more readable. Do not add new lines before or after print calls, since they are naturally separated by inline outputs.

Examples

q = Queue.Queue()

q.put("a")

q.put("b")

q.put("c")

print(q.get())

print(q.get())

print(q.get())

q = Queue.Queue()
q.put("a")
q.put("b")
q.put("c")

print(q.get())
print(q.get())
print(q.get())

f = open("sample.json")

print(json.load(f))

f = open("sample.json")
print(json.load(f))
Examples

For example, these two samples show how to express different recurrence rules using dateutil.rrule:

# ANSWER: How to list the dates of the 100th day of every year

for date in dateutil.rrule(YEARLY, byyearday=100, count=3):
    print(date)

# ANSWER: How to list the dates of the next 10th week of the year

for date in dateutil.rrule(DAILY, byweekno=10, count=3):
    print(date)

If the second sample was written as follows, it would be more difficult to understand the differences:

# ANSWER: How to list the dates of the next 10th week of the year

dates = dateutil.rrule(DAILY, byweekno=10, count=3)
print(list(dates))

Follow PEP8 as a basic coding style guideline

The standard Python coding conventions used by almost all Python developers are described in a document called PEP8. The most important of these conventions are listed below:

  • use 4 spaces per indentation
  • never use wildcard imports (e.g. from x import *)
  • surround binary operators (+, -, =, etc.) with a space on each side
  • do not surround an assignment (=) with spaces when used for keyword or default arguments
  • do not put spaces immediately inside parenthesis and brackets (e.g. spam( ham[ 1 ] ))
  • always pair a specific error with an except clause; never use the base Exception or leave it empty
  • use isinstance for type comparison
  • use the fact that empty sequences evaluate to False to check emptiness, instead of checking length

We diverge from PEP8 as follows:

  • no two-line spaces around classes and top-level functions
  • when splitting long function calls across lines, use a single extra indent level instead of using extra whitespace to align with the opening delimiter
  • we have our own set of rules for imports, as described in the prelude section

Setup Code

Setup code consists of preludes and nondisplayed code. These sections are executed in the preview engine, but are not displayed to the user.

Preludes are used for imports and other optionally helpful setup code. These segments are initially hidden but may be toggled by the user. Since imports are easily assumed by most python programmers, they clutter a solution without adding much value. However, to aid beginners, they are optionally available to clarify the solution.

Nondisplayed code will never be shown, but can be used to set up the question for a solution. For example, in a question asking how to read a file from the harddrive, the setup code may be used to write a file which will then be read in the solution. The code for writing a file to disk is not relevant for a reader since it can be assumed that they already have a target file on their machine.

Preludes

Code samples can include preludes. Code inside of preludes is executed at runtime along with main code, but will be initially hidden from the reader. The prelude is used for imports and other optional setup. The prelude includes code that can be easily implied by the reader, such as imports. However, it is available via toggle for less advanced programmers. Code that is helpful in understanding the function of the code, such as the definition of a class which is later instantaiated, should be included in the main code section.

Use the prelude to hide code that isn't directly relevant to the demonstrated concept

In the Kite app, only the main code section is visible in search results; preludes are not visible to a user. Use preludes for code that is needed for the sample to run, but is not part of the core concept of the sample.

Examples

# ANSWER: How to parse command line arguments to the CLI

KITE.start_prelude()
import argparse
KITE.stop_prelude()

parser = argparse.ArgumentParser()
parser.add_argument("-a", action="store_true")
parser.add_argument("-b")

print(parser.parse_args(["-a", "-b", "val"]))

Put import statements in the prelude

Examples

KITE.start_prelude()
import yaml
KITE.stop_prelude()

print(yaml.dump("abc"))

Use import x syntax by default

We want samples to be as easy to understand as possible, so for most packages, we want to import at the package level and access its functions from the package, rather than using from x import y to import functions directly.

Examples

KITE.start_prelude()
from json import dumps
KITE.stop_prelude()

print(dumps({"a": 1}))

KITE.start_prelude()
import json
KITE.stop_prelude()

print(json.dumps({"a": 1}))

Use from a.b.c import d when there are multiple subpackages

If a package contains subpackages, accessing a subpackage through the top-level package can make the sample messy and hard to read. In these cases, it makes more sense to use from.

Examples

# ANSWER: How to map a URL to a function using `getattr`

KITE.start_prelude()
from werkzeug.wrappers import Response, Request
from werkzeug.routing import Map, Rule
from werkzeug.exceptions import HTTPException
KITE.stop_prelude()

class HelloWorld(object):

url-map = Map([
    Rule("/home", endpoint="home"),
])

def dispatch_request(self, request):
    url_adapter = self.url_map.bind_to_environ(request.environ)
    try:
        endpoint, values = url_adapter.match()

        # Call the corresponding function by prepending "on\_"
        return getattr(self, "on\_" + endpoint)(request, **values)
    except HTTPException, e:
        return e

def on_home(self, request):
    return Response("Hello, World!")

def wsgi_app(self, environ, start_response):
    request = Request(environ)
    response = self.dispatch_request(request)
    return response(environ, start_response)

def __call__(self, environ, start_response):
    return self.wsgi_app(environ, start_response)

Use import conventions for common libraries

For libraries such as numpy, pandas, and matplotlib there are standard import names that are widely used.

Examples

KITE.start_prelude()
import numpy as np
KITE.stop_prelude()

an_array = np.ndarray([1, 2, 3])
Examples

KITE.start_prelude()
import pandas as pd
KITE.stop_prelude()

df = pd.DataFrame([1, 2, 3])
Examples

KITE.start_prelude()
from matplotlib import pyplot as plt
KITE.stop_prelude()

x = [1, 2, 3]
y = [1, 2, 3]

plt.plot(x,y)

In general, prefer to put code in the main code section

If your sample involves helper classes or methods that are central to the sample then you should still include those in the main code section.

Examples

KITE.start_prelude()
import yaml
KITE.stop_prelude()

class Dice(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __repr__(self):
        return 'Dice(%d, %d)' % (self.a, self.b)

def dice_constructor(loader, node):
    value = yaml.loader.construct_scalar(node)
    a, b = map(int, value.split('d'))
    return Dice(a, b)

add_constructor('!dice', dice_constructor)

print(yaml.load("gold: !dice 10d6"))

Setup Code

Setup code is never displayed. Use this section when intial setup is necessary in the KITE Engine for the code to run, but does not clarify the solution and is irrelevant to the user's specific use-case.

For example, to demonstrate reading a file from disk, we need to first construct a file. While the code is necessary for the sample to run, the specific set up steps are not part of the demonstrated concept, so we should not display the code.

KITE.set_display_code(False)
text = "line1\nline2\n"
KITE.write_file('test.txt',text)
KITE.set_display_code(True)

file = open('test.txt')
for line in file:
    print(line)

Variables

Quickstart to variable naming

See below for more detailed examples. Use the following hierarchy for naming:

  1. Purposeful name, eg: start_time, ...

  2. (Collections) describe contents, eg: numbers, items, elements. Use full words, not abbreviations (num, char, elem)

  3. Class names

  4. For multiple, use [class name][numeral] eg: list1, list2
  5. For one, use a_[class name]

  6. Make an exception. If this hierarchy does not fit a specific situation, make exceptions to maximize clarity and conciseness. For example:

Examples

Demonstrating multiple assignment

(a,b) = (1,2)
Using a longer name such as number1, number2 would reduce the clarity of the solution.

Use concise and purposeful variable names

Use variable names that are short and describe what a variable is going to be used for.

Examples

This example is good because you can see what the purpose of each variable is:

xdata = np.arange(10)
ydata = np.zeros(10)
plot(xdata, ydata)

This example is bad because it's not clear what the variables do:

a = np.arange(10)
b = np.zeros(10)
plot(a, b)

Avoid 'foo' 'bar' etc. regardless of how/where you are considering using it.

Avoid variables like name or file that could be confused with part of the API

Examples

Consider the following sample using Jinja2:

template = Template("<div>{{name}}</div>")
print(template.render(name="abc"))  # unclear - is "name" somehow special?

For somebody not familiar with Jinja, it unclear whether name has some special meaning in the Jinja2 API, or whether it's used as an arbitrary placeholder. To make it clear, use a word that could not be confused for part of the API:

template = Template("<div>{{person}}</div>")
print(template.render(person="abc"))

Follow language conventions for separating words in a variable name

Examples

# Python
my_variable = 1

# Java
int myVariable = 1

Don't create variables that are only referenced once (with exceptions)

Examples

This is unnecessarily verbose:

pattern = r"abc .* def"
regex = re.compile(pattern)

Instead, put it all on one line:

pattern = re.compile(r"abc .* def")

But do introduce temporary variables rather than split expressions across lines

Examples

This is difficult to understand:

yaml.dump({"name": "abc", "age": 7},
    open("myfile.txt", "w"),
    default_flow_style=False)

Instead, it would be better to introduce two temporary variables:

data = {"name": "abc", "age": 7}
f = open("myfile.txt", "w")
yaml.dump(data, f, default_flow_style=False)

And use single-use variables when printing

Examples

print(np.asarray((1, 2)))

Instead, add a one-use variable to make the print call simple.

arr = np.asarray((1, 2))
print(arr)

Use variable names to explain parameters

Examples

This is difficult to understand:

print(np.where([False, True, True], [1, 2, 3], [100, 200, 300]))

Instead, introduce temporary variables to indicate what the variables mean:

condition = [False, True, True]
when_true = [1, 2, 3]
when_false = [100, 200, 300]
print(np.where(condition, when_true, when_false))

This will sometimes conflict with the rule about not creating variables that are only referenced once. Use your best judgment.

Single letter variable names

In general, avoid using single variable letter names except in specific cases.

Indexes

Use i (then j, then k) as index variables.

x, y, and z

Avoid using x, y, or z except when:

• You're writing a numerics code sample where someone would naturally use x or y.

• You're using it as an iteration variable in a list comprehension. ([for x.upper() in items])

• You're using it in a lambda expression. (items.sort(key=lambda x: x[0]))

• You're using it in an inline code span (list.remove(x)) that won't be executed by the sandbox.

Do not use x as an iteration variable. Instead, use the singular form of the plural you're iterating over

Examples

for x in items:
print(x)

for item in items:
print(item)
Do not use k orv for keys and values

Use the full names instead.

Examples

for k, v in d.items():
print(v)

for key, value in d.items():
print(d)
When no purposeful name is available, use the first letter of the type name, other than l and i

When creating a variable that doesn't serve a specific purpose, use a single letter name that still preserves as much meaning as possible. For example:

s if it is a string

d if it is a dict

Avoid using l for list, though, because it could be confused with the number 1 . Instead, use a_list

Avoid using i for int because i is for indices. Use n instead.

As a last resort, use a, b, and c
Examples

For example:

a = [1, 2, 3]
del a[0]
print(a)

Values and Placeholders

Use simple placeholders

Examples

This is unnecessarily long:

print(json.dump({"first_name": "Graham", "last_name": "Johnson", "born_in": "Antarctica"}))

Instead, use more concise data:

print(json.dump({"a": 1, "b": 2}))

Avoid 'foo' 'bar' etc. regardless of how/where you are considering using it.

When appropriate, use placeholders that are relevant to the package

Examples

This is simple, but makes no sense in the context of the Python module shlex:

print(shlex.split("a b"))

Instead, since shlex is used for parsing Unix shell commands, use a sample command:

print(shlex.split("ls -a path/to/file"))

Similarly, since HMAC is used to hash messages using a key, express those semantics in the placeholders:

h = hmac.new("key")
h.update("Hello, World!")

Minimize placeholders to only what is necessary

Use the smallest amount of placeholder content that still clearly demonstrates the concept. You should rarely ever need more than 3.

When choosing between 1, 2, or 3 placeholders, consider incremental cost:

Examples
  • For example, in "abc".upper(), the last c, while not strictly necessary, is low cost
  • But map(upper, ["abc", "def"]) is better than map(upper, ["abc", "def", "ghi"]) because each incremental item element adds seven characters to the code, gets us to a less familiar part of the alphabet, and adds considerable length to the output
  • In the case of {"a": 1}.pop("a"), one entry is sufficient because pop for dictionaries does not care about order

Be careful when using only one placeholder, as the sample may become ambiguous.

Examples
  • if we show "a".upper(), it is unclear if it works for multiple characters
  • if we show [1].pop(), it is unclear if pop is getting the first or last item, or even the whole list

Sometimes there are additional reasons to consider using two vs three items. For example, when multiplying two matrices it's required to use non-square dimensions to illustrate how the dimensions need to line up.

Use the alphabet (a, b, c, ...) for string placeholders

Examples

my_string = "abc"

Use natural numbers (1, 2, 3, ...) for integer placeholders

Examples

numpy.array([1, 2, 3])

Use natural numbers with a ".0" suffix for float placeholders

Examples

my_list = [1.0, 2.0, 3.0]

Don't start numbers with a .

If a number is between 1 and -1 (exclusive), include a leading 0.

Examples

my_number = 0.5

my_number = .5

Continue these sequences for hierarchies, sequences, or groups of placeholder content.

Examples

map(upper, ['abc', 'def'])
numpy.array([[1, 2, 3], [4, 5, 6]])

Use "path/to/file" for directory names

Again, only for non-purposeful placeholder directory names.

Examples

os.path.split("/home/user/docs/sample.txt")

os.path.split("path/to/file")

Don't use the same value twice unless for the same purpose each time

Examples

The following sample creates an HMAC hash using a key, then updates it with a value:

h = hmac.new("abc")
h.update("abc")

This is confusing since it leaves the user wondering whether there is an important reason to use "abc" in both places. Instead, you should use different values so that there is no confusion:

h = hmac.new("key")
h.update("Hello, World!")

On the other hand, sometimes the same value is being used for the same purpose in two different places. In this case you should use the same value in both cases, for example:

data1 = numpy.zeros(8)
data2 = numpy.zeros(8)

For placeholder functions and classes, balance "simple" with "natural"

Examples

This sample has a bunch of incidental complexity:

# ANSWER: How to add test cases to a suite

class MyTest(TestCase):
    def setUp(self):
        self.name = "abc"
        self.num = 123

    def test_name_equals(self):
        self.assertEqual(self.name, "abc")

    def test_num_equals(self):
        self.assertEqual(self.num, 123)

suite = TestSuite()
suite.addTest(MyTest("test_name_equals"))
suite.addTest(MyTest("test_num_equals"))

Here is a much simpler version, that forms a better sample:

# ANSWER: How to add test cases to a suite

class MyTest(TestCase):
    def test_a(self):
        self.assertTrue(0 < 1)

suite = TestSuite()
suite.addTest(MyTest("test_a"))

First, we don't need to use setUp or instance variables. We do have a decision between assertTrue(True) or assertTrue(0 < 1). Here we decided in favor of the second option, though not strongly.

Use double quotes for string literals by default

Reason: it's important to have a consistent standard, and double quotes are more consistent with string representations in other languages.

Examples

print("use double quotes by default")

Switch to single quotes if you need to include double-quotes inside a string

Examples

This is ugly:

s = "Greg said \"hello\" to Phil"

Instead, switch to single quotes:

s = 'Greg said "hello" to Phil'

Use triple-double-quotes for multi-line strings

Examples

document = """
{
"a": 20,
"b": \[1,2,3,"a"\],
"c": {
    "d": \[1,2,3\],
    "e": 40
}
}
"""
data = json.loads(document)

Put a new line at the start and end of multi-line strings, if possible

Examples

data = """This is a
little hard to read"""

data = """
This is a
lot easier to read
"""

Use strings for dictionary keys

If the key-value pairs are purposeful, use key names that correspond to the meaning of the value. Otherwise, use "a", "b"... as placeholder keys, and 1, 2... as placeholder values.

Examples

json.dumps({1: "a", 2: "b"})

json.dumps({"a": 1, "b": 2})

Use C[n] for placeholder classes and f[n] for placeholder functions

Note that this only applies to placeholder classes and functions, i.e. classes and functions that have no functionality or purpose, such as those used in demonstrating sys and inspect functionality.

Additionally, for class and instance attributes, use a[n].

Examples

class Dog:
    def bark(self):
        return "Bark bark!"

class Cat:
    def meow(self):
        return "meow"

class C:
    pass

class C:
    def f(self):
        pass

class C1:
    def f1(self):
        return 1

class C2:
    def f2(self):
        return 2

Use mock.kite.com for samples that demonstrate communication with a server

Examples

print(requests.get("http://google.com").text)

print(requests.get("http://mock.kite.com/text").text)

A list of endpoints for mock.kite.com can be found here.


Files

Open file with a straightforward open

Unless absolutely necessary, do not use a with statement for opening files (rationale: this is a difficult one to decide on but open works fine for short samples, and with is a language-level feature that some users may not be familiar with).

Examples

f = open("input.txt")

Output

Generate the minimal output needed to clearly demonstrate the concept

Output must be read and understood by the user, to, so the more output there is, the more time it takes users to understand the sample.

Examples

This code generates 24 lines of output, which is too much:

for x in itertools.permutations([1, 2, 3, 4]):
    print(x)

# OUTPUT
(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)

Instead, do the following, which only generates six lines of output:

for x in itertools.permutations([1, 2, 3]):
    print(x)

# OUTPUT
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

However, the following generates too little output and does not show the concept clearly:

for x in itertools.permutations([1, 2]):
    print(x)

# OUTPUT
(1, 2)
(2, 1)

Avoid unnecessary output formatting or explanations

If you feel the need to add expository, you probably need to simplify your sample so that it does not create complex outputs.

Examples

print("This is the value for a: " + a)

print("Person {name}: {sex}, age {age}".format(
    name = name,
    sex = sex,
    age = str(age)
))

def print_dict(d):
output = ""
for k, v in d.items():
    output += "Key: " + key + " Value: " + value + "\\n"

print_dict(some_dict)

Whenever possible, produce the same output every time

Examples

When demonstrating functions such as random number generators, set a deterministic seed in the prelude if it is available:

KITE.start_prelude()
import random
random.seed(0)
KITE.stop_prelude()

print(random.randint(0, 10))

This is good because the user will only see the main code section, which will not be cluttered with the call to random.seed.

When using numpy.random, there is a similar seed function:

KITE.start_prelude()
from numpy.random import randn, seed
seed(0)
KITE.stop_prelude()

print(randn(2, 5))

For samples that involve time stamps, HTTP requests, and random number generators with no seed, this is not possible, which is okay.

Keep print calls as simple as possible

Always use a simple print call to output values. Note that we use Python 3-style print(value), not print value.

Examples

Don't use statements like these:

[print(item) for item in some_list]

print value1, value2, value3

print(value1, value2, value3)

from pprint import pprint
pprint(some_dict)

Prefer to print lists with a for statement

Examples

This sample requires a more advanced understanding of Python iterators and should be avoided:

print(list(itertools.permutations([1, 2, 3])))

Instead, use this syntax:

for x in itertools.permutations([1, 2, 3]):
    print(x)

Output binary data as raw strings

Even though this can cause broken characters to appear, we still want to keep print calls as simple as possible.

Examples

print(binary_data)

If binary data will not output as a raw string (e.g. when the binary contains null bytes or is too small to be interpreted as a string), use binascii.hexlify

Examples

print(binascii.hexlify(binary_data))

When printing a return value and a side effect, start by printing the return value

Examples

a = [1, 2, 3]
val = a.pop(0)
print(a)
# output: [2, 3]
print(val)
# output: 1

Instead, start by printing the return value, then the side effect.

a = [1, 2, 3]
val = a.pop(0)
print(val)
# output: 1
print(a)
# output: [2, 3]

Miscellaneous

Don't use advanced concepts unless necessary

Examples

This sample works, but may be difficult for beginners who are not familiar with Python's dictionary unpacking syntax:

data = {"person": "abc", "age": 5}
print("{person} is age {age}".format(**data))

Instead, this sample is easy for everyone to understand:

print("{person} is age {age}".format(person="abc", age=5))

Don't write samples that demonstrate what not to do

Examples

try:
    print(pickle.loads("pickle"))
except IndexError:
    print("String does not contain pickle data")

However, it is sometimes good to include a demonstration of common failure modes as part of a larger sample.

dictionary = {"a": 1}

print(dictionary.pop("a"))
print(dictionary)

try:
    print(dictionary.pop("a"))
except KeyError as e:
    print("KeyError: " + e.message)

print(dictionary.pop("a", None))

Demonstrate the purpose, not simply the functionality

Code samples should demonstrate the purpose of its functions, not merely their functionality. Use functions in a way that mirrors their intended usage, and clearly show the purpose that the function serves.

Examples

print(secure_filename("a b"))
# OUTPUT: 'a_b'

print(secure_filename("../../../etc/passwd"))
# OUTPUT: 'etc_passwd'

Only use comments when a sample cannot be written in a self-explanatory way

Strive to write samples that do not need comments to explain what they do. If an explanation is absolutely necessary, include a brief comment above the section that requires explanation; do not use inline comments.

Examples

This is obvious and does not need a comment:

# Dump to string
output_string = csv.dumps([1, 2, 3])

This is obvious and is also using an inline comment:

csv.loads(string) # load from string

This comment is helpful to include because the line is confusing on its own, but cannot be written more clearly because has_header cannot be called with a keyword argument:

# Sample the first 256 bytes of the file
print(sniffer.has_header(f.read(256)))

Bundle together simple demonstrations

Code samples that call the same function with different parameters can generally be bundled together into a "cheat sheet" sample that provides users with a quick reference to the usages of the function, if the function calls all demonstrate the same concept.

Examples

# ANSWER: How to construct a dictionary

print(dict(a=1, b=2))
print({"a": 1, "b": 2})
print(dict([("a", 1), ("b", 2)]))
print(dict({"a": 1, "b": 2}))
print(dict(zip(["a", "b"], [1, 2])))

Functions like dateutil.rrule are exceptions because they provide conceptually different outputs based on the arguments provided.

Don't write samples that simply construct an object

Object construction on its own is not informative; it is much more helpful to see how an object is used.

Examples

pattern = re.compile("\[a-z\]+\[0-9\]+")
print(pattern)

pattern = re.compile("\[a-z\]+\[0-9\]+")
print(pattern.match("test123"))

Don't reimplement default behavior

Examples

Here is a bad sample showing a class with an explicit pickling function:

import cPickle

class Foo(object):
    def __init__(self, value):
        self.value = value
    def __getstate__(self):
        return {'the\_value': value}

f = Foo(123)
s = cPickle.dumps(f)

The problem with the code sample above is that, by default, cPickle uses the __dict__ attribute whenever there is no getstate function. So the code in the sample above would have produced the exact same output even if the getstate function had been omitted. This is bad because it's not clear to the user why the getstate function is important, since the result is exactly what would have happened anyway if getstate had been omitted. Instead, a better sample would implement getstate in a way that is different to the default behavior.

Use explicit keyword arguments when there are many arguments to a function

Examples

xdata = np.arange(10)
ydata = np.zeros(10)
plot(xdata, ydata, style='r-', label='my data')

Use keyword arguments when it is standard practice to do so

Examples

This works but is non-standard:

a = array([1, 2, 3], float)

Whereas this is standard practice for numpy code:

a = array([1, 2, 3], dtype=float)

When using multi-variable assignment with long tuples, print the tuple first

This allows users to more easily match up the variables with their values and helps users who are not familiar with the syntax understand what is going on.

Examples

st = os.stat(open("sample.txt"))
print(st)
mode, ino, dev, nlink, uid, gid, size, accessed, modified, created = st

Use the isoformat method to format datetime objects, instead of strftime

strftime tends to be long and unwieldy, and is not completely standardized. isoformat has a standard output that is decently readable and makes the code sample much more concise. Of course, when you can, you should print out the datetime object directly, so you can take advantage of the default repr method that outputs a nicely-formatted representation of the date and time.

When making comparisons, make your code samples as similar as possible

This will make it easy for the reader to compare them.

Examples

For example, when comparing list.pop() and list.pop(i), make all surrounding parts of each code sample the same.

a = [1, 2, 3]
val = a.pop(0)
print(val)
# output: 1
print(a)
# output: [2, 3]
a = [1, 2, 3]
val = a.pop()
print(val)
# output: 3
print(a)
# output: [1, 2]

Reminder: Do not copy-and-paste from Stack Overflow

Our relationship with StackOverflow is that we are referring to them to know what topics need better answers. If the answers on StackOverflow were sufficient, our site would not be needed.

Be especially mindful of not replicating variable names, and other arbitrary elements of code samples from StackOverflow.

Also, do not copy text or code from StackOverflow, either directly or with minor changes.

Advanced Features

I/O Interleaving

# KITE.set_auto_io(val: bool = True), KITE.display_io()
# disables automatic I/O interleaving
KITE.set_auto_io(False)
print('abc')
print('xyz')
KITE.display_io()
# output is flushed automatically at KITE.set_auto_io(True) or at end of the code block
print('def')
KITE.set_auto_io(True)

Filestystem

Writing Files

# KITE.write_file(path: str, data: AnyStr, encoding: str = 'ascii', display: bool = False)
# write file to disk with the given contents.
# If isinstance(data, bytes), encoding is ignored.
# Otherwise, encoding can be any valid Python str encoding or 'base64'.
# If display is true, the file is also displayed.
KITE.write_file('test_file.txt', 'test contents\n'

Sample Files

# KITE.write_sample_file(name: str, dst: str = None, display: bool = False)
# writes sample file/directory `name` to the given `dst` path (defaults to dst = name).
# See below for a list of currently available samples.
KITE.write_sample_file("sample.html", dst="my_sample.html", display=True)

List Directory

# KITE.list_directory(path: str = ".", *, cols: Tuple[str, ...] = ('permissions', 'size', 'name'), depth: int = 1)
# displays a directory listing formatted similar to `ls`.
# Valid `cols` also include 'user', 'group'. The ordering is taken into account.
KITE.list_directory()

Display

File Display

# KITE.display_file(path: str, limit: int = 10000)
# displays file contents
KITE.display_file('test_file.txt')

Image Display

# KITE.display_image(path: str)
KITE.display_image('red_image.jpg')

Arbitrary Data Display

# KITE.display(title: str, data: str)
# displays arbitrary data in an output block.
# Furthermore, all KITE.display* commands support a `title` keyword argument
# to manually set a title for the output block.
KITE.display("My Custom Title", "custom output data")

Capture I/O

Warning: Currently unused

# KITE.set_capture_io(val: bool = True)
# disables capturing & displaying I/O
KITE.set_capture_io(False)
print('this is not printed')
KITE.set_capture_io(True

Interactive mode

Warning: Currently unused

# KITE.set_interactive_mode(val: bool = True)
# auotmatically prints expressions that don't evaluate to None
KITE.set_interactive_mode()
"this is printed automatically"
KITE.set_interactive_mode(False)

Networking

Warning: Currently unused

# KITE.do_async_http(method: str, url: str, *, display_request: bool = True, **kwargs)
# instructs the runtime to execute all following code asynchronously.
# At the end of execution, an HTTP request will be made using the provided arguments
# to requests.request(): see https://2.python-requests.org/en/master/api/#requests.request
# The `display_request` parameter allows control over whether the request text is displayed.
# I/O capture will be disabled until manually re-enabled via KITE.set_capture_io(True).
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

KITE.do_async_http('GET', 'http://localhost:8080')
app.run(host="0.0.0.0", port=8080)

HTTP Requests

To demonstrate code that needs to make a REST call to a webserver, use httpbin.

The sandbox can make HTTP requests, or example using requests.request(). This includes GET, POST, etc... and customized request bodies and headers. However, the sandbox cannot dur multiple successions of HTTP requests, for example in OAuth.