Skip to content

Commit 7870103

Browse files
committed
New create active code exercises page
1 parent 7aa459c commit 7870103

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed
58.2 KB
Loading
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
<?xml version="1.0"?>
2+
<section xml:id="writing-exercises_active-code-exercises">
3+
<title>Writing your own Active Code Exercises</title>
4+
5+
<subsection xml:id="writing-exercises_activecode">
6+
<title>Active Code Exercises</title>
7+
<p>Active Code exercises are coding exercises that allow students to write and run code directly within the ebook. These exercises provide an interactive way for students to practice coding skills, receive immediate feedback, and enhance their understanding of programming concepts. Active Code exercises can be created in various programming languages, including Python, JavaScript, Java, C++, and others supported by the Runestone platform.</p>
8+
9+
<p>Here is an example of a simple Active Code exercise in Python:</p>
10+
<exercise label="ac_ex1">
11+
<statement>
12+
<p>Write a Python function that takes two numbers as input and returns their sum.</p>
13+
</statement>
14+
<program interactive="activecode" language="python">
15+
<code>
16+
def add(a, b):
17+
# complete this function to add a and b and return the sum
18+
</code>
19+
<tests>
20+
from unittest.gui import TestCaseGui
21+
22+
class myTests(TestCaseGui):
23+
24+
def testOne(self):
25+
self.assertEqual(add(2,2),4,"Call to add(2,2) should return 4")
26+
self.assertAlmostEqual(add(2.0,3.0), 5.0, 1, "Call to add(2.0,3.0) should return 5.0")
27+
28+
myTests().main()
29+
</tests>
30+
</program>
31+
</exercise>
32+
33+
<p>To write your own Active Code exercises, start or go to any assignment in the Instructor Dashboard "Assignment Builder". In the Exercises section of the assignment, click on "Add Exercise" and select "+ Create New Exercise" and then select "Active Code". </p>
34+
<ol>
35+
<li> <p>In step 1 Language, select the coding language for the exercise. </p>
36+
</li>
37+
<li> <p>In Step 2 Instructions, write the instructions for the students using Markup or enter / for formatting options. </p>
38+
</li>
39+
<li> <p>In Step 3 Hidden Prefix, you can optionally provide hidden code that is run before the students code. This is usually left blank.</p>
40+
</li>
41+
<li> <p>In Step 4 Starter Code, write the code that you want the students to complete in the code editor. You can provide starter code or just comments or leave it blank for students to fill in.
42+
<figure align="center" xml:id="activecode_edit_fig">
43+
<caption>Create an Active Code Exercise</caption>
44+
<image source="Figures/createActiveCode.png" width="100%" alt="Create an Active Code Exercise"/>
45+
</figure>
46+
</p>
47+
</li>
48+
<li> <p>In Step 5 Hidden Prefix, you can optionally add unit tests to automatically grade the students' code. These tests will run when the student clicks the "Submit" button, and they will receive feedback based on the results of the tests. The next section will explain how to write unit tests.</p>
49+
</li>
50+
<li>
51+
<p>In Step 6, you can optionally provide standard input that the student's code can read from if needed. This is usually left blank.</p>
52+
</li>
53+
<li>
54+
<p>In Step 7, you can change the settings to set the chapter and section where you want the exercise stored in the assignment builder (where it will show when browsing chapters in the assignment builder), the author, the topic, the number of points for the question, and add tags to help you find the question later. If you change the name of the exercise, make sure it is unique! You can also choose to make the exercise private or contribute it to the question bank for other teachers to use. Please make experimental questions private. </p>
55+
</li>
56+
<li><p>Then, you can preview and test the problem before saving the problem.</p>
57+
</li>
58+
</ol>
59+
60+
</subsection>
61+
62+
<subsection xml:id="writing-exercises_unit-testing-exercises">
63+
<title>Python Unit Tests for Autograding</title>
64+
<p>The real killer feature of these exercises is to be able to create your own unit tests and have the exercise be autograded.</p>
65+
<p>Let's expand our example to include some simple unittests. We can do this by adding a hidden block of code to our previous example in step 5 Hidden Prefix that uses the standard Python unittest framework. Be careful with using the correct indentation when typing in Python.</p>
66+
<program language="python">
67+
<code>
68+
from unittest.gui import TestCaseGui
69+
70+
class myTests(TestCaseGui):
71+
72+
def testOne(self):
73+
self.assertEqual(add(2,2),4,"Call to add(2,2) should return 4")
74+
self.assertAlmostEqual(add(2.0,3.0), 5.0, 1, "Call to add(2.0,3.0) should return 5.0")
75+
76+
myTests().main()
77+
</code>
78+
</program>
79+
80+
<p>If you are not familiar with Python unittests they are pretty easy to write. You create your own class that is a subclass of TestCase, or in our work TestCaseGui so we get some graphical output. Your tests are all methods of the class and must start with the word <q>test</q>. There are a host of assertXXXX functions that you can use. Check out the <url href="https://docs.python.org/2/library/unittest.html#assert-methods" visual="https://docs.python.org/2/library/unittest.html#assert-methods">unittest documentation here</url>.
81+
</p>
82+
</subsection>
83+
84+
<subsection xml:id="writing-java-unit-tests">
85+
<title>Java Unit Tests for Autograding</title>
86+
<p>You can create Active Code exercises in other languages supported by Runestone and use their unit testing libraries. For Java, there is the JUnit library as well as a custom library developed by Kate McDonnell for CSAwesome that makes it easy to write autograding unit tests. Here is an example:</p>
87+
<exercise label="java_ac_ex1">
88+
<statement>
89+
<p>
90+
Complete the method called square that takes an integer as input and returns its square. Then, call the square method in the main method to print out the square of 6.
91+
</p>
92+
</statement>
93+
94+
<program interactive="activecode" language="java">
95+
<code>
96+
public class SquareMethod
97+
{
98+
public static int square(int number)
99+
{
100+
// TO DO: complete this method to return the square of number
101+
102+
}
103+
104+
public static void main(String[] args)
105+
{
106+
System.out.println("5 squared is " + square(5));
107+
// TO DO: Call the square method to print out the square of 6
108+
109+
}
110+
}
111+
</code>
112+
<tests>
113+
import static org.junit.Assert.*;
114+
import org.junit.*;
115+
import java.io.*;
116+
117+
public class RunestoneTests extends CodeTestHelper
118+
{
119+
@Test
120+
public void containsCall()
121+
{
122+
boolean passed = checkCodeContains("square(6)", "square(6)");
123+
assertTrue(passed);
124+
}
125+
@Test
126+
public void testMain() throws IOException
127+
{
128+
String output = getMethodOutput("main");
129+
String expect = "36";
130+
boolean passed =
131+
getResults(expect, output, "Expected output from main");
132+
assertTrue(passed);
133+
}
134+
@Test
135+
public void testSquare()
136+
{
137+
Object[] args = {9};
138+
String output = getMethodOutput("square", args);
139+
String expect = "81";
140+
141+
boolean passed = getResults(expect, output, "square(9)");
142+
assertTrue(passed);
143+
}
144+
}
145+
</tests>
146+
</program>
147+
</exercise>
148+
149+
<p>The unit test code which would be put in the hidden suffix section in step 4 is as follows:</p>
150+
<program language="java">
151+
<code>
152+
import static org.junit.Assert.*;
153+
import org.junit.*;
154+
import java.io.*;
155+
156+
public class RunestoneTests extends CodeTestHelper
157+
{
158+
@Test
159+
public void containsCall()
160+
{
161+
boolean passed = checkCodeContains("square(6)", "square(6)");
162+
assertTrue(passed);
163+
}
164+
@Test
165+
public void testMain() throws IOException
166+
{
167+
String output = getMethodOutput("main");
168+
String expect = "36";
169+
boolean passed =
170+
getResults(expect, output, "Expected output from main");
171+
assertTrue(passed);
172+
}
173+
@Test
174+
public void testSquare()
175+
{
176+
Object[] args = {9};
177+
String output = getMethodOutput("square", args);
178+
String expect = "81";
179+
180+
boolean passed = getResults(expect, output, "square(9)");
181+
assertTrue(passed);
182+
}
183+
}
184+
</code>
185+
</program>
186+
187+
<p>In this example, we have three tests. The first test checks that the student's code contains a call to square(6). The second test runs the main method and checks that the output contains 36 (the square of 6). The third test calls the square method with an argument of 9 and checks that the return value is 81.</p>
188+
189+
<p>This <url href="https://docs.google.com/document/d/1p4I_9iOc-2_70t37grR_0nTMukcpXHk9nAxxxr-0pl8/edit?usp=sharing">document</url> provides more details on writing Java unit tests for Active Code exercises using the CodeTestHelper library.</p>
190+
</subsection>
191+
</section>

0 commit comments

Comments
 (0)