Skip to main content

Generates questions about given Python program

Project description

QLCpy

Generates questions about concrete constructs and patterns in a given Python program. These questions (including answering options) can be posed to a learner to practice introductory programming. These questions include elements to develop program comprehension and program tracing.

Automatic generation enables systems to pose the generated questions to leaners about their own programs that they previously programmed. Such Questions About Learners' Code (QLCs) may have self-reflection and self-explanation effects that are of interest in computing education research.

References

The concept of Questions About Learners' Code (QLCs) is first introduced by Lehtinen et al. in Let's Ask Students About Their Programs, Automatically.


Example result

For the file test/sample_code.py:

from typing import List

def find_first(words_list: List[str], initial: str) -> int:
  f = False
  for i in range(len(words_list)):
    if words_list[i].startswith(initial):
    return i

def count_average() -> None:
  s = 0
  n = 0
  word = None
  while word is None or word != '':
    word = input('Enter number or empty line to count average')
    try:
      s += int(word)
      n += 1
    except ValueError:
      print('Not a number')
  if n > 0:
    print('Average', s / n)
  print('No numbers')

We use the CLI to create one question of each available type:

 % qlcpy test/sample_code.py --call 'find_first(["lorem", "ipsum", "dolor", "sit", "amet"], "s")' -n 9 --unique
Which of the following are variable names in the program? [VariableNames]
  if: A reserved word in programming language [reserved_word]
  input: A function that is built in to programming language [builtin_function]
* n: A variable in the program [variable]
  other: This word was not used in the program [unused_word]
* word: A variable in the program [variable]

Which of the following are parameter names of the function declared on line 3? [ParameterNames]
  f: A variable in the program [variable]
  find_first: A name of the function [function]
  i: A variable in the program [variable]
* initial: A parameter of the function [parameter]
* words_list: A parameter of the function [parameter]

A program loop starts on line 5. Which is the last line inside it? [LoopEnd]
  4: The loop starts after this line [line_before_block]
  6: This line is inside the loop BUT it is not the last one [line_inside_block]
* 7: Correct, this is the last line inside the loop [last_line_inside_block]
  8: The loop ends before this line [line_after_block]

A value is accessed from variable <em>i</em> on line 6. On which line is <em>i</em> created? [VariableDeclaration]
  4: This is a random line that does not handle the given variable [random_line]
* 5: Correct, this is the line where the variable is created. [declaration_line]
  6: This line references (reads or assigns) the given variable BUT it is created before [reference_line]
  7: This line references (reads or assigns) the given variable BUT it is created before [reference_line]

From which line program execution may continue to line 18? [ExceptSource]
  13: Except-block cannot be entered from outside the corresponding try-block. [before_try_block]
  15: At least the first line inside try-block starts executing. [try_line]
* 16: Correct, this line can raise an error of the expected type. [source_line]
  17: This line does NOT raise an error of the expected type. [not_source_line]

Which of the following best describes the purpose of line 13? [LinePurpose]
  Accepts new data: Incorrect. [read_input]
  Guards against division by zero: Incorrect. [zero_div_guard]
  Ignores unwanted input: Incorrect. [ignores_input]
* Is a condition for ending program: Correct. [end_condition]

Which of the following best describes the role of variable <em>s</em>that is created on line 10? [VariableRole]
  A <em>fixed value</em> that is not changed after created: Incorrect. [fixed]
* A <em>gatherer</em> that combines new values to itself: Correct. [gatherer]
  A <em>stepper</em> that systematically goes through evenly spaced values: Incorrect. [stepper]
  The variable is never accessed and could be removed: Incorrect. [dead]

Line 5 has a loop structure. How many times does the loop execute when running <em>find_first(["lorem", "ipsum", "dolor", "sit", "amet"], "s")</em>? [LoopCount]
* 4: Correct, this is the number of times the loop executed. [correct_count]
  5: This number is off by one. [one_off_count]
  6: This is an incorrect, random number. [random_count]
  7: This is an incorrect, random number. [random_count]

Line 5 declares a variable named <em>i</em>. Which values and in which order are assigned to the variable when running <em>find_first(["lorem", "ipsum", "dolor", "sit", "amet"], "s")</em>? [VariableTrace]
  0, 1, 2: This sequence is missing a value that was assigned to the variable. [miss_value]
* 0, 1, 2, 3: Correct, these values were assigned in this order to the variable. [correct_trace]
  3, 1, 0, 2: This is an incorrect, random sequence of values. [random_values]
  3, 1, 2: This is an incorrect, random sequence of values. [random_values]

Installation

pip install qlcpy

Usage

The package offers a CLI for test prints as well as JSON output. See the example section above for example output. Below is the usage instruction from the command.

 % qlcpy --help
usage: __main__.py [-h] [-m] [-c CALL] [-sc SILENT_CALL] [-i INPUT] [-n N]
                   [-t TYPES [TYPES ...]] [-u] [-l LANG] [--json]
                   [--list-types]
                   [program]

QLCpy generates questions that target analysed facts about the given program

positional arguments:
  program               A python program file

optional arguments:
  -h, --help            show this help message and exit
  -m, --main            Run with "__name__" = "__main__"
  -c CALL, --call CALL  A python call to execute
  -sc SILENT_CALL, --silent-call SILENT_CALL
                        A python call to execute silently without including it
                        in the question prompts
  -i INPUT, --input INPUT
                        A text file to use as stdin
  -n N                  Number of questions (at maximum)
  -t TYPES [TYPES ...], --types TYPES [TYPES ...]
                        Only these question types
  -u, --unique          Only unique question types
  -l LANG, --lang LANG  Language code for the text (en, fi)
  --json                Print question data as JSON
  --list-types          List available question types

For programmatic integration the library offers a generate function that offers the same generation options as the CLI command. Type hints are included and models.py describes the input and output data. Below is an example python program using the library.

import qlcpy

with open('test/sample_code.py', 'r') as f:
  src = f.read()

qlcs = qlcpy.generate(
    src,
    [
        qlcpy.QLCRequest(1, types=['LoopCount', 'VariableTrace']),
        qlcpy.QLCRequest(10, fill=True, unique_types=True),
    ],
    call='find_first(["lorem", "ipsum", "dolor", "sit", "amet"], "s")',
)

for qlc in qlcs:
    print(f'{qlc.question} = {", ".join(str(o.answer) for o in qlc.options if o.correct)}')

import json
print(json.dumps(list(qlc.to_dict() for qlc in qlcs)))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qlcpy-1.0.11.tar.gz (26.4 kB view details)

Uploaded Source

Built Distribution

qlcpy-1.0.11-py3-none-any.whl (30.5 kB view details)

Uploaded Python 3

File details

Details for the file qlcpy-1.0.11.tar.gz.

File metadata

  • Download URL: qlcpy-1.0.11.tar.gz
  • Upload date:
  • Size: 26.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.63.1 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.10

File hashes

Hashes for qlcpy-1.0.11.tar.gz
Algorithm Hash digest
SHA256 ea91c2b9ef65d6eece1062b5cda48c6bc3bd7549ad8057425b385a64a3893853
MD5 8aece7759acb1baac085d653ccb5b612
BLAKE2b-256 709fcbb9433d8f486e5517647d6e5c1653ed7868485aeacccf5f4ff4d9a5b84b

See more details on using hashes here.

Provenance

File details

Details for the file qlcpy-1.0.11-py3-none-any.whl.

File metadata

  • Download URL: qlcpy-1.0.11-py3-none-any.whl
  • Upload date:
  • Size: 30.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.63.1 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.10

File hashes

Hashes for qlcpy-1.0.11-py3-none-any.whl
Algorithm Hash digest
SHA256 f6ee92eb80794d1af1750edf6e28170d98b62df7e9392e6323d34066cf2670ce
MD5 c9a20d87125852ea331a3eb276f64449
BLAKE2b-256 9612d39a2e89cccf9fb12e66a0f79907f9d1ace93ad7e849f342ce13e3347ff8

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page