Skip to content
Khalid Alkhaldi edited this page Apr 27, 2026 · 1 revision

Kencode: Accessible Programming Through Natural Language

Try it online: khalidalkhaldi.pythonanywhere.com


Table of Contents

  1. What is Kencode?
  2. Why Kencode?
  3. How It Works
  4. Installation
  5. Usage
  6. Kencode Classification (Four Token Types)
  7. Base-Word Reference Table
  8. Operator Reference Table
  9. Escape Sequence Reference
  10. The Kencode Sequence & General Rule
  11. Reading a Kencode Instruction
  12. Complete Examples by Category
  13. For Technical Users
  14. Token classification rules
  15. Advantages of Kencode
  16. Citation and Reference
  17. License

What is Kencode?

Kencode is a bidirectional mapping method between Python programming code and natural spoken or written language instructions. It was designed to make programming accessible to people who face difficulties with the punctuation and special characters that conventional programming requires, such as people using voice input, alternative keyboards, or those learning to code for the first time.

With Kencode, instead of typing:

student = 'James'

You write or speak:

student equals string James

And instead of:

for i in range(5):

You write or speak:

for variable i in call range pass digit five

Kencode is fully bidirectional: you can convert Python → Kencode, or Kencode → Python.


Why Kencode?

Programming languages rely heavily on punctuation, (), [], {}, ', ", #, :, =, +=, and special characters that are difficult for many people to type or dictate. This creates a significant barrier:

  • People using voice-to-text input struggle with special characters
  • People with motor disabilities find special-character keyboard shortcuts difficult
  • Beginner programmers often confuse punctuation rules and syntax symbols
  • People using alternative input devices may not have easy access to symbol keys
  • Non-native speakers learning programming face both language and syntax barriers simultaneously

Kencode solves this by providing a clean, word-based alternative that maps one-to-one with real Python code. No information is lost, and any valid Kencode instruction can be converted back to exactly the Python it represents.


How It Works

Kencode works by breaking every Python statement into a sequence of classified tokens. Each token falls into one of four categories, and the sequence of categories is called the Kencode Sequence (KS). Alongside the KS, each token also has a verbal form, a plain English word or phrase, which together form the Kencode Verbal Instruction (KVI).

Python:   x = 10
KS:       [W] [O] [B] [W]
KVI:      x   equals digit ten

The KS tells you what kind of thing each token is. The KVI tells you what it says. Together, they give a complete, unambiguous description of the Python code in natural language.


Installation

pip install Kencode

Requires Python 3.9 or higher. No external dependencies.


Usage

Python Library

from kencode import python_to_kencode, decode_kvi

# Python → Kencode
ks, kvi = python_to_kencode("x = 10")
print(ks)    # [W][O][B][W]
print(kvi)   # x equals digit ten

# Kencode → Python
ks, py = decode_kvi("x equals digit ten")
print(py)    # x = 10

Process a full Python file line by line

from kencode import python_to_kencode

with open("my_script.py", "r") as f:
    lines = f.readlines()

for i, line in enumerate(lines, 1):
    ks, kvi = python_to_kencode(line.rstrip())
    if ks:
        print(f"Line {i:>3}: {line.rstrip()}")
        print(f"         KS : {ks}")
        print(f"         KVI: {kvi}")
        print()

Process a full Python file and save to CSV

from kencode import python_to_kencode
import csv

input_file  = "my_script.py"
output_file = "my_script_kencode.csv"

with open(input_file, "r") as f:
    lines = f.readlines()

with open(output_file, "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["line_no", "python_code", "KS", "KVI"])
    for i, line in enumerate(lines, 1):
        ks, kvi = python_to_kencode(line.rstrip())
        writer.writerow([i, line.rstrip(), ks, kvi])

print(f"Saved to {output_file}")

Decode a full KVI file line by line

from kencode import decode_kvi

with open("my_instructions.txt", "r") as f:
    lines = f.readlines()

for i, line in enumerate(lines, 1):
    line = line.strip()
    if line:
        ks, py = decode_kvi(line)
        print(f"Line {i:>3}: {line}")
        print(f"         KS : {ks}")
        print(f"         PY : {py}")
        print()

Round-trip example (Python → KVI → Python)

from kencode import python_to_kencode, decode_kvi

original = "for i in range(5):"
ks, kvi  = python_to_kencode(original)
ks2, py  = decode_kvi(kvi)

print(f"KS  : {ks}")    # [K][B][W][K][B][W][B][B][W]
print(f"KVI : {kvi}")   # for variable i in call range pass digit five
print(f"PY  : {py}")    # for i in range(5):

Full file processing with built-in function

from kencode.kencode_converter import process_file

process_file("my_script.py")
# Prints KS + KVI for every line to terminal
# Saves my_script_kencode.csv automatically

Command Line (CLI)

Kencode installs two CLI commands: kencode for encoding and kencode-decode for decoding.

Encode a Python file → Kencode

kencode my_script.py

Prints KS and KVI for every line to the terminal and saves my_script_kencode.csv automatically.

Decode a single KVI instruction

kencode-decode "x equals digit ten"

Output:

KS  : [W][O][B][W]
PY  : x = 10

Decode a KVI file (batch mode)

kencode-decode -f my_instructions.txt

Each line in the file is decoded and printed with its KS and Python code.

Interactive REPL

kencode-decode
Kencode KVI -> Python  (type 'quit' to exit)

KVI> name equals string Alice
KS  : [W][O][B][W]
PY  : name = "Alice"

KVI> for variable i in call range pass digit five
KS  : [K][B][W][K][B][W][B][B][W]
PY  : for i in range(5):

KVI> quit

Quick Reference

Task Method Command / Code
Encode one line Library python_to_kencode("x = 10")
Decode one KVI Library decode_kvi("x equals digit ten")
Encode a file Library process_file("script.py")
Encode a file CLI kencode script.py
Decode one KVI CLI kencode-decode "x equals digit ten"
Decode a file CLI kencode-decode -f instructions.txt
Interactive mode CLI kencode-decode

Kencode Classification (Four Token Types)

Every token in a programming statement is classified by Kencode into four types:

Symbol Name Meaning Examples
[K] Keyword A Python reserved word that controls program flow or structure if, for, while, def, class, return, True, False, print
[O] Operator A mathematical, logical, or assignment operation =, +, -, *, /, ==, >=, and, or
[W] Word A user-defined name, variable, number verbal, or string content student, ten, Alice, my, list
[B] Base-word A Kencode structural word that classifies or bridges tokens variable, digit, string, call, pass, list, key, value

Key Rules

  • [K] tokens come from Python's built-in reserved words. They appear in the KVI exactly as they are in Python (lowercased).
  • [O] tokens are translated to their verbal equivalents: == becomes is equal, >= becomes greater or equal, ** becomes power.
  • [W] tokens are plain words, variable names (split on underscores), string content, or verbalized numbers.
  • [B] tokens are the glue of Kencode. They are added to indicate the type of value or structure that follows.

Note: Programming statements provide [K], [O], and [W]. We need to add only [B] to construct a valid Kencode instruction.


Base-Word Reference Table

Base-Word KS Tag Associated Type Description
variable [B] Data / names A named reference to a stored value
digit [B] Numbers A numeric literal (integer or float)
point [B] Numbers The decimal point in a float (3.5digit three point 5)
string [B] Text An immutable sequence of characters
special [B] Escape sequences Introduces an escape character within a string
list [B] Collections An ordered, mutable collection [...]
tuple [B] Collections An ordered, immutable collection (...)
set [B] Collections An unordered, unique-value collection {...}
dict [B] Collections A dictionary comprehension marker
key [B] Dictionaries The key in a key-value pair or subscript ["key"]
value [B] Dictionaries The value in a key-value pair
index [B] Lists / strings A positional subscript [0], [-1]
call [B] Functions Marks the start of a function call
pass [B] Functions Marks the start of arguments passed to a call
object [B] OOP An object being accessed via dot notation
attribute [B] OOP A property accessed with a dot (non-callable)
method [B] OOP A callable property accessed with a dot
hook [B] OOP A dunder method like __init__
tab [B] Structure Represents one indentation level (preceded by a count [W])
comment [B] Structure Marks a comment line (replaces #)
f-string [B] Formatting An f-string literal f"..."
formatting [B] Formatting A {...} expression inside an f-string
precision [B] Formatting A .Nf format specifier
left-align [B] Formatting The :<N alignment specifier
right-align [B] Formatting The :>N alignment specifier
center-align [B] Formatting The :^N alignment specifier
expression [B] Lambda Marks the body of a lambda expression
type [B] Exceptions Introduces an exception class name
ignore [B] Placeholder Represents _ (the throwaway variable)
keyword-only [B] Functions The * separator in function parameters
dictionary [B] Functions A **kwargs-style parameter or argument
list unpack [B][B] Functions A *args unpacking in a function call
dictionary unpack [B][B] Functions A **kwargs unpacking in a function call

Operator Reference Table

Python Symbol KVI Verbal Category
= equals Assignment
+= plus equal Compound assignment
-= minus equal Compound assignment
*= times equal Compound assignment
/= divided equal Compound assignment
%= modulo equal Compound assignment
**= power equal Compound assignment
//= floor divided equal Compound assignment
+ plus Arithmetic
- minus Arithmetic
* times Arithmetic
/ divided by Arithmetic
// floor divided by Arithmetic
% modulo Arithmetic
** power Arithmetic
== is equal Comparison
!= not equal Comparison
< less than Comparison
> greater than Comparison
<= less or equal Comparison
>= greater or equal Comparison
in in Membership
not not Logical
and and Logical
or or Logical
is is Identity

Escape Sequence Reference

Escape KVI Verbal Meaning
\n new line Newline character
\t horizontal tab Horizontal tab
\\ backslash Literal backslash
\' single quote Literal single quote
\" double quote Literal double quote
\r carriage return Carriage return
\b backspace Backspace
\f form feed Form feed
\a bell Bell / alert
\v vertical tab Vertical tab
\ooo octal ooo Octal value
\xhh hex hh Hexadecimal value
\uXXXX unicode XXXX Unicode code point

Example

lines = ["line one\n", "line two\n"]
KS:  [W][O][B][B][W][W][B][W][W][B][W][W][B][W][W]
KVI: lines equals list string line one special new line string line two special new line

The Kencode Sequence, General Rule

The Kencode Sequence (KS) captures the structural pattern of a Python statement using only the four token symbols. This is the single general regex rule that validates any KS:

^(?:\d+\s+)?(\[(?:K|O|W|B)\])+$
Part Meaning
^ Start of the sequence
(?:\d+\s+)? Optional indent prefix, a digit followed by a space (e.g. 1 for one indent level)
(\[(?:K|O|W|B)\])+ One or more tags, each exactly [K], [O], [W], or [B]
$ End of the sequence

Reading a Kencode Instruction

A Kencode instruction reads left to right. Base-words [B] act as type classifiers, they always appear immediately before the token they describe:

[W]my [W]list [O]equals [B]list [B]digit [W]one [B]digit [W]two [B]digit [W]three

Corresponds to:

my_list = [1, 2, 3]

Structural Patterns to Recognise

Pattern Meaning Python example
[W][O][B][W] Simple assignment x = 10
[W][O][B][W][B][W] Float assignment y = 3.5
[K][B][W][K][B][W][B][B][W] For loop with call for i in range(5):
[B][W][B][B][args...] Function call greet("Alice")
[W][B][W] Method call (no args) my_list.sort()
[W][B][W][B][B][W] Method call (with args) my_list.append(4)
[W][B][K][B][W][B][B][W][B][W] __init__ with indent def __init__(self, name):

Complete Examples by Category

Variables and Data Types

Python KS KVI
x = 10 [W][O][B][W] x equals digit ten
y = 3.5 [W][O][B][W][B][W] y equals digit three point 5
name = "Alice" [W][O][B][W] name equals string Alice
is_valid = True [W][W][O][K] is valid equals true
my_list = [1, 2, 3] [W][W][O][B][B][W][B][W][B][W] my list equals list digit one digit two digit three
my_tuple = (1, 2, 3) [W][W][O][B][B][W][B][W][B][W] my tuple equals tuple digit one digit two digit three
my_set = {1, 2, 3} [W][W][O][B][B][W][B][W][B][W] my set equals set digit one digit two digit three

Operators and Expressions

Python KS KVI
print(x + y) [K][B][W][O][B][W] print variable x plus variable y
print(a ** b) [K][B][W][O][B][W] print variable a power variable b
x += 5 [W][O][B][W] x plus equal digit five
result = "Pass" if score >= 50 else "Fail" [W][O][B][W][K][B][W][O][B][W][K][B][W] result equals string Pass if variable score greater or equal digit fifty else string Fail

Control Flow

Python KS KVI
if result: [K][B][W] if variable result
if True: [K][K] if true
if num == 0: [K][B][W][O][B][W] if variable num is equal digit zero
elif num > 0: [K][B][W][O][B][W] elif variable num greater than digit zero
else: [K] else
while count < 5: [K][B][W][O][B][W] while variable count less than digit five
for i in range(5): [K][B][W][K][B][W][B][B][W] for variable i in call range pass digit five
for i in range(1, 10, 2): [K][B][W][K][B][W][B][B][W][B][W][B][W] for variable i in call range pass digit one digit ten digit two
for _ in range(3): [K][B][K][B][W][B][B][W] for ignore in call range pass digit three
for key, value in my_dict.items(): [K][B][W][B][W][K][B][W][W][B][W] for variable key variable value in variable my dict method items

Functions

Python KS KVI
def greet(): [K][W] def greet
def add(a, b): [K][W][B][B][W][B][W] def add pass variable a variable b
def power(base, exp=2): [K][W][B][B][W][B][W][O][B][W] def power pass variable base variable exp equals digit two
def variable_args(*args): [K][W][W][B][B][W] def variable args pass tuple args
def keyword_args(**kwargs): [K][W][W][B][B][W] def keyword args pass dictionary kwargs
greet() [B][W] call greet
int(num_str) [B][W][B][B][W][W] call int pass variable num str
result = f(*args) [W][O][B][W][B][B][B][W] result equals call f pass list unpack args
result = f(**kwargs) [W][O][B][W][B][B][B][W] result equals call f pass dictionary unpack kwargs

Classes and Objects

Python KS KVI
class Person: [K][W] class Person
class Dog(Animal): [K][W][B][B][W] class Dog pass variable Animal
def __init__(self, name): [W][B][K][B][W][B][B][W][B][W] 1 tab def hook init pass variable self variable name
def greet(self): [W][B][K][W][B][B][W] 1 tab def greet pass variable self
self.name = name [B][W][B][W][O][B][W] variable self attribute name equals variable name
name = person.name [W][O][B][W][B][W] name equals variable person attribute name
cat.make_sound() [W][B][W][W] cat method make sound

Dictionaries

Python KS KVI
customer = {'name': 'Alice', 'age': 30} [W][O][B][B][W][B][B][W][B][B][W][B][B][W] customer equals key string name value string Alice key string age value digit thirty
my_dict["c"] = 3 [B][W][W][B][B][W][O][B][W] variable my dict key string c equals digit three
customer['age'] [W][B][B][W] customer key string age

F-strings and Formatting

Python KS KVI
message = f"My name is {name}" [W][O][B][B][W][W][W][B][B][W] message equals f-string string My name is formatting variable name
return f"Hello {self.name}" [K][B][B][W][B][B][W][B][W] return f-string string Hello formatting variable self attribute name
f"{price:.2f}" [B][B][W][B][B][W][W] formatting variable price precision point 2

Indentation

Python KS KVI
x = 10 (1 indent) [W][B][W][O][B][W] 1 tab x equals digit ten
print(x) (2 indents) [W][B][K][B][W] 2 tab print variable x

Exception Handling

Python KS KVI
try: [K] try
except ZeroDivisionError: [K][B][W][W][W] except type zero division error
except ValueError as e: [K][B][W][W][K][B][W] except type value error as variable e

File Operations

Python KS KVI
with open("test.txt", "w") as f: [K][B][W][B][B][W][W][W][B][W][K][B][W] with call open pass string test dot txt string w as variable f

Lambda and Higher-Order Functions

Python KS KVI
square = lambda x: x**2 [W][O][K][B][W][B][B][W][O][B][W] square equals lambda variable x expression variable x power digit two
even_numbers = list(filter(lambda x: x % 2 == 0, numbers)) [W][W][O][B][B][B][B][W][B][K][B][W][B][B][W][O][B][W][O][B][W][B][B][W] even numbers equals call list pass call filter pass lambda variable x expression variable x modulo digit two is equal digit zero pass variable numbers

Comprehensions

Python KS KVI
[x * 2 for x in range(5)] [B][B][W][O][B][W][K][B][W][K][B][W][B][B][W] list variable x times digit two for variable x in call range pass digit five
{x for x in range(5)} [B][B][W][K][B][W][K][B][W][B][B][W] set variable x for variable x in call range pass digit five
[Person(n, a) for n, a in zip(names, ages)] [B][B][W][B][B][W][B][W][K][B][W][B][W][K][B][W][B][B][W][B][W] list call Person pass variable n variable a for variable n variable a in call zip pass variable names variable ages

Multi-Target Assignment and Ignore

Python KS KVI
num, _, last = (1, 2, 3) [B][W][B][B][W][O][B][B][W][B][W][B][W] variable num ignore variable last equals tuple digit one digit two digit three
for _ in range(3): [K][B][K][B][W][B][B][W] for ignore in call range pass digit three


Token classification rules

LHS vs RHS distinction: Left-hand side names always emit plain [W] tokens, never prefixed with [B]variable. The [B]variable prefix is used only on the right-hand side or inside expressions.

x = y   # x → [W]  (LHS, no prefix)
         # y → [B]variable [W]y  (RHS, typed)

Snake_case splitting: Variable names with underscores split into separate [W] tokens. my_list[W]my [W]list. Note: is in is_valid is [W], not [K], because it is part of a variable name.

Number verbalization: Numbers up to 100 are verbalized; larger numbers pass through as digits. 10ten, 50fifty, 993993.

Multi-word operators: Some operators produce one [O] tag but multiple KVI words:

Python KS tag KVI phrase
== [O] is equal (2 words)
/= [O] divided equal (2 words)
>= [O] greater or equal (3 words)
// [O] floor divided by (3 words)

Inter-argument pass rule: Plain typed args share the opening [B]pass. A fresh [B]pass is emitted only after a lambda argument:

filter(lambda x: x > 0, numbers)
→ call filter pass lambda variable x expression variable x greater than digit zero pass variable numbers

Handling ambiguity

Word As [K] As [W]
is Standalone operator between two values Part of a variable name (is_valid)
list Collection base-word in RHS context Part of a variable name (my_list) on LHS
True/False/None Always [K], Python keywords Never [W]
print Always [K] in Kencode Never [W]

Advantages of Kencode

Accessibility, Removes all special characters and punctuation from programming. Fully compatible with voice dictation, text-to-speech, and alternative input devices. Reduces cognitive load by separating what a token is from what it means.

Clarity and Learnability, Every statement becomes a readable English sentence. The [B] base-word system makes data types and structure explicit. KS patterns provide a visual grammar, learners can see structural patterns before mastering syntax.

Completeness, Full coverage of Python including variables, operators, control flow, functions, classes, OOP, dictionaries, collections, comprehensions, lambdas, f-strings, exception handling, file I/O, imports, and more. Bidirectional with no information lost in either direction.

Flexibility, Works as a standalone command-line tool, a web API, or an importable library. The KS regex rule is language-agnostic, the same four-token system could extend to other programming languages.


Citation and Reference

Kencode is introduced and formally described in the following peer-reviewed research paper. If you use Kencode in your research, teaching, software, or any published work, please cite the original paper.

BibTeX

@article{Alkhaldi2025Kencode,
  author  = {Khalid Alkhaldi and Asrar Qassem and Stephanie Ludi},
  title   = {Kencode: Advancing Voice-Based Programming Through an Innovative,
             Standardized, and Taxonomic Structuring Approach},
  journal = {Journal of Visual Language and Computing},
  year    = {2025},
  pages   = {8--17},
  doi     = {10.18293/JVLC2025-N3-079},
  url     = {http://ksiresearch.org/jvlc/journal/JVLC2025N3/JVLC079.pdf}
}

Note: If you publish work that builds upon, extends, or evaluates Kencode, the authors welcome notification. The tool is provided freely for educational, research, and accessibility purposes in the spirit of the original paper's mission to advance voice-based and accessible programming.

License

Kencode © 2025-present by Khalid Alkhaldi is licensed under CC BY-NC-SA 4.0

Clone this wiki locally