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.18.tar.gz (27.3 kB view details)

Uploaded Source

Built Distribution

qlcpy-1.0.18-py3-none-any.whl (31.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: qlcpy-1.0.18.tar.gz
  • Upload date:
  • Size: 27.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.12

File hashes

Hashes for qlcpy-1.0.18.tar.gz
Algorithm Hash digest
SHA256 3dfeddac2465d1223e5529e0401b12e591d487aefce06c355e3dcd5cd8831937
MD5 d280154fb67d9821b92eb3897fe9f924
BLAKE2b-256 69ad162ef22550badcac09b445bdf5f6c33bcc619fe7170ef049e210635290eb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: qlcpy-1.0.18-py3-none-any.whl
  • Upload date:
  • Size: 31.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.12

File hashes

Hashes for qlcpy-1.0.18-py3-none-any.whl
Algorithm Hash digest
SHA256 b790fc0382212a8fb250ede2fa8b6bcf17eabe9f9b3f43c19fa6a60c697efaf3
MD5 562453ba4ab332ee86261ef06f4484ee
BLAKE2b-256 d35dd9cf33f86d993d9b2cdff5cd7ca16f3d35979b13de452ff321872f64d2b5

See more details on using hashes here.

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