Conference ICL2006
September 27 -29, 2006 Villach, Austria
.NET-Programming-Curriculum Inside-Out – It’s working now! Jörg Schulze, Jean Hallewell, Clemens Derndorfer, Matthias Längrich, Antje Meyer University of Applied Sciences Zittau/Görlitz (Germany), University of Applied Sciences Wels (Austria)
Key words: Tele-learning, Curriculum, Testing Abstract: Teaching the programming fundamentals using a modern, framework-based language is an important step in computer science education. In teaching students from other degree programmes, problems related to the structure of the programming languages and organizational constraints have been encountered. Based on these experiences, we recommend a solution adapted to the situation at universities of applied sciences that allows a high-degree of proficiency to be obtained.
1 Goals of teaching programming fundamentals The goal of teaching programming fundamentals is to provide non-computer-scientists with sufficient competence to be able to implement and test a functioning program independently to solve a problem. This approach used follows the imperative first model ([1], p. 29), whereby objects are taught later, and matches the approaches of a number of well-known textbooks. The students should be taught in a modern, object oriented, framework-based language like those used in industry.
Algorithms
We split the goals into four competencies, three of which are solely computer science competencies that are required to develop an application (see Figure 1).
Application
Te st s
Data Structures
Figure 1 Application Cube: the skills required
1. Data structure skills: The ability to select or create an appropriate data structure for a given problem specification. 2. Algorithmic skills: The ability to develop an algorithm to solve the problem using the data structures as well as a programming environment. 1(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
3. Test skills: The ability to test each step of the development to ensure the specification has been fulfilled. This includes the ability to use a modern IDE (integrated development environment) and debugger. 4. Meta-skills: The soft skills (social competence) should also be strengthened, although this aspect is not generally mentioned explicitly in relation to computer-science. Based on this goal to develop an application (testing code which implements an algorithm), we developed an imperative-first curriculum for C#. Didactically this is difficult, since a complete application is needed for practicing. The developed curriculum, however, does not require the use of concepts that have not yet been taught. In the following sections we describe the situation and problems at two universities of applied sciences in Germanspeaking countries, but which are likely to be typical to this environment. In the last section, we show how these problems could be overcome with a bespoke tool to apply the didactically more efficient inside-out approach for the first time, building up one concept at a time.
2 .NET-Curriculum Inside-Out Based on [10], we have modularized an application into the following parts: 1. 2. 3. 4. 5. 6. 7.
Expressions Statements Functions (Methods) Types Assemblies Components Application
These steps or modules are reflected in the data structures and algorithms. The first three steps are repeated when teaching each new data structure (or class) from the framework. The concept of types, assemblies and components are less of an issue for the presented, and come into play only with more advanced levels of computer science instruction. In order to reach the goal of developing an application, the students have to learn about the first steps, as well as about testing. This sets the basis for the presented curriculum. As a first step, the students develop a simple console application. From the point of view of a programmer, the simplest application consists of implementing a function (or method) applying an algorithm and a function to test it. Both of these functions can then be called from the main program. However, this is not as simple as it may at first appear, as the following analysis shows. In order to see the test results of something as simple as the “Hello World” program, the students need to be able to apply the functionality of the Console. Alternatively the TextReader in C# can be used directly for input values and the TextWriter for the output values. In order to explain the TextReader and TextWriter, the concept of the data structure Queue is helpful. In addition, the student needs to understand the concept of the data type String. The input must be done over Strings and then converted to the correct type. In order to deal with the problems that arise with incorrect input, the student must understand Exceptions.
2(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
When dealing with processing output, the students may be confronted with the fact that some variables cannot be changed while others can (value types or reference types). This quickly leads to the related reference type StringBuilder. If you view the String as a constant array of char and the StringBuilder as an ArrayList of char or as List, the necessity for arrays and aspects from the System.Collection arise, including the ArrayList (List) and Queue. Because of recursion, the concept of the stack should be introduced with the concept of the Queue. These data types can be introduced through abstract data types. Arrays form the basis not only for understanding Strings, but are the simplest reference type and play an important role in the whole framework. Thus for arrays, it is useful to demonstrate how the Array-implementation is used for the implementation of ArrayList, Queue and Stack in the .Net framework. In order to implement algorithms, the students need to understand statements (single lines in functions). Expressions (e.g. x > 3) form the basis for statements, but also require simple data types. With data types, first bool, then integral types and floating point types are required. These types are the simplest value types and need to be introduced with algorithms to allow the students to understand the difference between whole numbers (in the mathematical sense) and int, and between real numbers and double. From this, the following order of topics is required to build up without applying topics before they have been taught (for the terms of the C#-grammer see [6]): Expressions with single types, starting with bool, then integral types (byte, short int, long and char) and finally floating point types (double) Statements, including declarations, selection (e.g. if), iteration (e.g. for) and jump Array System.Collections (ArrayList, Queue, Stack) and /or the corresponding Generics String, StringBuilder TextReader, TextWriter Console Methods Applications These steps are common to any introduction to programming. The expressions are always the first step, i.e. what functions can I apply to the data types learned so far. Based on this, it is possible to create algorithms (prior to recursion, simply a sequence of statements), to show how a data type can be applied in a certain situation. The introduction of recursion as an alternative to iterative algorithms requires the discussion of stacks which are introduced through the System.Collections Similar but not so thoroughly curricula can be found in the textbooks [2] C#, [3] Java and [4] C++.
3 Preconditions and Problems At the University of Applied Sciences in Zittau/Görlitz (FH) in Germany, students of the department of mechanical engineering and mathematics provide a practical introduction to the fundamentals of programming in their first year. At the University of Applied Sciences in Wels in Austria, the same is done for students of mechatronics (automation engineering).
3(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
The courses are organized in “frontal” lectures and exercises at computers. While the lectures focus on presenting concepts and examples applying them, the labs or exercises provide the opportunity for students to gain practice through solving exercises. The workload for students can be calculated as 4 hours of lessons (lectures or labs) per week (=15 weeks x 4 hours), plus preparation and practice (+ 15 x 4), making a total of approximately 120 hours per semester. At the end of the semester, a small project may be given. The progress in the exercises is verified before the final written exam for the course. Lectures L1 Exercises Tests
L2 E1
L3 E2
E3 T1
Figure 2 Structure of the course, from [9], p. 1
The labs consist of groups of 15-25 students and are supervised by the professor holding the lectures or other teachers. In contrast to traditional universities, there are no graduate students available as a university of applied sciences and the financial scope for assistants is very limited, so that further support is not usually available. Ideally, if the lectures and exercises are not held on the same day, there is a risk, e.g. due to public holidays, that the synchronicity of the lectures and lab are broken. Since the students already have such a large workload, it is necessary to make compromises as to which contents are covered in the labs, which can also compromise the course goals. Collections of exercises have been analysed to classify typical types of problems (specification task, test task, (forward) calculate task, reverse calculate task, fault diagnosis task or implementation addition task and (construction of a) function prototype task) as described in [9]. In the following, the specification task is of central importance. The specification task is characterized by input- and output-variables (short input/output), a specification of what is required and a contract (see [7]) that must fulfil the input. The task is: Write a function fragment that fulfils the specification and check it with appropriate tests. The test task is character characterized by input- and output-variables, a specification and a contract. The task is: Provide initializations of the input variables and the expected values of the output variables. At the (forward) calculate task input/output, the reference solution-code and the contract are provided. The task is: Calculate the values of the output variables for the given initializations of the input variables. The roles of input and output are reversed up in the reverse calculate task. At the fault diagnosis task or implementation addition task input/output, specification, contract, example initialization for input-variables and a faulty or incomplete code are given. The task is: The given coding contains errors. Identify the errors and indicate a correction. At the (construction of a) function prototype task input/output, specification, contract and sample function call are given. The task is: Indicate a valid function prototype for the given code. 4(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
Although the curriculum bases on the imperative-first model from [1], problems were still encountered in the computer labs: 1. At the beginning of the course, the students are not yet able to write a complete application and test it, as they have not yet developed the necessary skills or learned the concepts they are applying and so do not understand what they are doing. 2. The only software available for solving these types of problems is normal development environments (e.g. Visual Studio). However, the students encountered further difficulties in using these complex development environments. 3. In order to provide feedback, the choice of exercise types must also consider the effort required of the tutors. This means that the full spectrum of possibilities cannot be used. 4. The use of an academic programming language (such as Pascal, see [8]) and interpretable languages (such as Python) was rejected as the commercial importance of these languages is small and not adequate for a practice-oriented bachelor or engineering degree. Thus, it was not possible to use a language specifically developed for beginners. Due to the environment at universities of applied sciences and the fact that students still need to develop their own test skills, a development environment was developed to support the tutors in the labs.
4 The Function-Fragment-Checker Many of the problems described can be overcome with interactive computer aided learning that allows students to practice fragments of functions (methods) in a language used in industry without using a heavy IDE. A (simple) application consists of data structures and algorithms, in addition to a function-call (for test purposes). One possible approach of teaching the skills needed as shown with figure 1, is to teach algorithms (see [1], p. 32) and to provide the needed data structures and tests. This means that in the labs the students practice the correct implementation of algorithms. Since a manually semantically check of these types of solutions is very time intensive, the tutor would not be able to check the correctness of each single student through a code inspection. For this reason, this approach is rejected. A more detailed analysis shows that there are 3 different possibilities for specification tasks: 1. A complete application is developed. 2. A function is developed and inserted into a pre-existing project to complete the application. 3. A part of a function is developed (functions-fragment). This fragment consists of statements and expressions that complete the application. The first approach is not possible at the beginning of the course, as the students don’t understand a complete console application, for example the namespaces, framework libraries, classes, (public static) methods, input/output (and don’t really need to know this yet). In addition, they do not yet posses test skills to develop appropriate test cases. Furthermore, the students generally don’t like to separate the solution and the tests and frequently integrate their tests in the main program. 5(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
In addition, since the structure of the application (with the using and main program) is always the same, the students are forced to use a portion of their time for these (known) aspects rather than the problem to be solved (and the new concepts). Through this they lose valuable time and are distracted from the current problem. It has, however, the advantage that the students can create their own solution and debug it. That is, once that they have the skills for using the development environment, which they do not have at the beginning of the course. The trade-off for the more freedom students have in their solutions, is the difficulty (and time required) for the tutors to automate the tests. The second approach is very promising. The tutor can provide a pre-prepared project (including test cases) and the student simply integrates his solution. This however, requires that the students understand functions, so that this approach, like the first, is only applicable to later in the curriculum. The tests can be hidden in an assembly, thus reducing the distraction of the extra code, while still allowing the student to debug his/her own code. This could be supported by automated tools with a “Console-checker”. The third approach is possible even before the students have an active knowledge about functions as the students only write expressions and statements. This is the smallest possible unit and does not require prior knowledge. Using an appropriate environment (e.g. Assemblies and partial functions), it is again possible to create an executable application, which already contains the test cases. However, the students would still be confronted with portions of source code that they do not understand, as well as having to work with an overly complex development environment. The third solution has been enabled through the development of the FFC (function-fragmentchecker, see also [9]). The disadvantages just described (visibility of code, etc.) are solved by a separate development environment with integrated editor and test that was developed using the C# compiler of the .Net framework. As the name indicates, it checks just a portion of a function. In this environment, debugging is no longer possible. However, this is compensated by the display of the input- and output values and by the limited number of lines of code the students need to examine.
Figure 3 FFC for a specification task (sum of digits of an non negative int-variable „number“)
6(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
In addition to the discussed advantages and disadvantages, it is still possible to inspect the code manually or to provide a sample solution to allow students to check their own implementation. However, this is generally only done in individual cases, when a student is having difficulties. The FFC development environment hides the syntactic complexity of the programming language, and allows the students to work without understanding the underlying framework (also outside of the labs). The result allows the compiled language C# to be taught like an interpreted language. Applying the environment in different environments (two different universities of applied sciences), allowed for the development of valuable didactical understandings related to the FFC that are presented here. More information about the FFC itself is presented in [5]. The new curriculum was being taught for the first time in the last summer-semester 2005 (at the department of Mathematics and Natural Sciences) and turned out to be promising, although, a qualitative evaluation will follow. The new curriculum will also be introduced to the students of the Computer Science department from the University of Applied Sciences Zittau/Görlitz in the coming winter-semester (2006).
References: [1] CORPORATE The Joint Task Force on Computing Curricula: Computing Curricula 2001; Journal on Educational Resources in Computing (JERIC); Volume 1, Issue 3 (Fall 2001), Article No. 1; 2001, New York; ACM Press [2] Mössenböck, H.: Softwareentwicklung mit C# 2.0; 2006, Heidelberg, dpunkt [3] Mössenböck, H.: Sprechen Sie Java; 2005, Heidelberg, dpunkt [4] Gill, T.G.: Introduction to Programming Using VISUAL C++ .Net; 2004, Boston, John Wiley [5] Längrich, M.; Meyer, A.; Schulze, J.: Der Funktions-Fragment-Checker: eine effektive Übungsumgebung für C#-Programmieranfänger; Leipziger Informatik-Tage; 2005; 297-302 [6] Hejlsberg, A.; Wiltamuth, S.; Golde, P.: The C# Programmimng Language; 2006, Boston, Pearson Eductaion [7] Meyer, B.: Object-oriented Software Construction; 1997; New Jersey, Prentice Hall [8] Wirth, N.: Algorithmen und Datenstrukturen. Pascal-Version.; 2000; Stuttgart, Teubner [9] Längrich, M.; Schulze, J.: A Systematic Approach to Immediate Verifiable Exercises in Undergraduate Programming Courses; 2006; San Diego; Proceedings of the ASEE/IEEE Frontiers in Education 2006 Conference [10] Westphal, R.: Software Cells #9: Applications as Holons - Becoming a little more systematic; http://weblogs.asp.net/ralfw/archive/2005/05/27/409299.aspx; 09/2006
Author(s): Derndorfer, Clemens, Prof. (FH) Dr. rer. nat. University of Applied Sciences Wels (Austria), Department of Computer Science Stelzhammerstrasse 23, 4600 Wels, Austria
[email protected] Hallewell Haslwanter, Jean, Prof. (FH) MSc. BSc. University of Applied Sciences Wels (Austria), Department of Computer Science Stelzhammerstrasse 23, 4600 Wels, Austria
[email protected] Längrich, Matthias, Dipl. Inf. (FH) University of Applied Sciences Zittau/Görlitz (Germany), Department of Computer Science 7(8)
Conference ICL2006
September 27 -29, 2006 Villach, Austria
Brückenstrasse 1, 02826 Görlitz, Germany
[email protected] Meyer, Antje, Cand. Dipl. Komm. Psych. (FH) University of Applied Sciences Zittau/Görlitz (Germany), Department of Social Sciences Brückenstrasse 1, 02826 Görlitz, Germany
[email protected] Schulze, Jörg, Prof. Dr. rer. nat. University of Applied Sciences Zittau/Görlitz (Germany), Department of Computer Science Brückenstrasse 1, 02826 Görlitz, Germany
[email protected]
8(8)