Question Authors' Forum

Java method with state

 
Picture of Peter Sander
Java method with state
by Peter Sander - Wednesday, 7 September 2016, 6:17 AM
 

This is a prototype prototype (!) template for Java method questions, sort of like BUILT_IN_PROTOTYPE_java_method but with some differences:

  • the major difference is that the method can depend on an object state by referencing instance attributes
  • the method can refer to stuff in supporting classes
  • the class can be in a Java package (see another discussion in this forum)
As an example, let's say you want the students to write their getHello method for the following class:

public class Toto {
    private String hello = "Yo!";
    public String getHello() {
        return hello;
    }
}

Replace the method with the string PLACEHOLDER so that the class looks like:

public class Toto {
    private String hello = "Yo!";
    PLACEHOLDER
}

The template uses convention over configuration, so the above class must be in a support file called placeholder. The template replaces PLACEHOLDER by the student answer and runs the resulting class against your tests.

Here's the template:

import sys, os, shutil, subprocess
__student_answer__ = """{{ STUDENT_ANSWER | e('py') }}"""
# First replace the placeholder with the student answer
placeholder = '{{QUESTION.parameters.placeholder}}' or 'placeholder'
ncoding = '{{QUESTION.parameters.encoding}}' or 'utf-8'
with open(placeholder, mode='r', encoding=ncoding) as fd:
    __student_answer__ = fd.read().replace('PLACEHOLDER', __student_answer__)
    fd.close()
with open('{{ QUESTION.parameters.class}}.java', mode='w', encoding=ncoding) as fd:
    print(__student_answer__, file=fd)
    fd.close()
# Make package directory, put support files into it
package_dir = '{{ QUESTION.parameters.package }}'.replace('.', '/')
os.makedirs(package_dir)
[shutil.move(f, package_dir) for f in os.listdir() if f.endswith('.java')]
    
# Build test class in package directory too
tester = '''package {{ QUESTION.parameters.package }};
public class __Tester__ {
    public static void main(String[] args) {
        {{TEST.testcode}}
    }
}
'''
with open(package_dir + '/__Tester__.java', mode='w', encoding='utf-8') as fd:
    print(tester, file=fd)
    fd.close()
# Compile and run
if (subprocess.call(['javac', '-encoding', ncoding, package_dir + '/__Tester__.java']) != 0 or
   subprocess.call(['java', package_dir + '/__Tester__']) != 0):
    print('** Further testing aborted **', file=sys.stderr)