• No results found

Chapter 3 : Initiating Programming

3.1 Programming Worlds

3.1.2 Learning to Think

In addition to languages and programmatic tools, students learn algorithmic problem solving. Frequently, the significance of learning how to write algorithms to solve problems is emphasized over the particular technical skills – the particular languages or platforms – that students learn in computer science. Students are admonished, particularly at the beginning of their studies, to understand and think about a problem and create a plan for solving it before typing a single character. “Programming is not just about

moving on to say that students need to spend time thinking about the algorithm first. “Jumping into code first is sometimes anti-productive.” A few weeks later, he told students that their Practical Exams (midterms done through coding at a computer) are designed so that students have a great deal of time to think, even if they only need to write a couple of lines of code. The basic practices of defining an algorithm and learning to write one in pseudocode (a description of an algorithm in near plain-English) are also covered in students’ first week of learning programming, before introducing the basic syntactic symbols for students to write their first working program.

I saw and heard repeated evidence of how students took the significance of algorithmic problem solving to heart. Even students in the second semester of their first year emphasized how they had learned to think algorithmically, to analyze a problem, to break down a problem to smaller steps, and to devise a solution with step-by-step

instructions for a computer to follow. Susan, who discussed her struggles to learn programming above, was emphatic about how she had learned to think differently by programming, and in ways that she transferred to other aspects of her life:

I feel that programming, it has changed the way I look at things because I don’t just jump straight to conclusions. Because programming has, it allows me to look at the problem and then solve it systematically and then, yeah, step-by-step approach… I’m not so hasty. Yeah. I don’t take that hasty decision anymore. I learn how to analyze the problem properly and then think up a solution that works. It’s just like how you look at a programming problem and then you think of the pseudocode and then from the pseudocode you can type out the code and all that (Susan 2014).

Another first-year student commented on understanding the thought processes entailed in writing a program:

You want a computer to say take 23 out of 1000, and you need to know that a computer can only do things step by step, they can’t be like us and look at the entire thing and take it out. Actually I think we do the same thing as what computers do – it’s just being able to think of what you do and translate it into computer (Naomi 2014).

Students in later years echoed these statements. A second-year student, in discussing what she liked about computer science, commented: “Another side is about the thinking process, it’s more [than] about programming, like algorithms and data structures, how you come up with smart ways to solve a problem. So it’s more about problem solving and thinking strategies” (Alicia 2013). While not all students emphasized changes in their thinking, some also suggested that they already thought over problems carefully and in detail before learning computer science.

Both students and professors, however, emphasize the systematic, step by step, abstract process of problem solving as key to programming and, more generally, to doing computer science. Students are told when they start to learn that “it’s all about logic. Every step must be clear to you.” Unlike syntax errors, compilers generally do not catch logic errors, often leading programs to produce unexpected results. Compilers are

programs that translate “high-level” languages (languages more or less understandable to humans) into machine language (binary). In doing so, a compiler checks that the syntax of the program is correct, because otherwise it would not be able to translate the program. Alongside programming, many students also learn discrete mathematics whereby

students learn to produce proofs of particular mathematical theorems, similarly

discussed above. Yet, students must pay attention to the minute details of programming syntax and logical reasoning in order to build these worlds.

There is also a significant focus on problem solving as a key facet of computer science, as seen in Susan’s and Alicia’s discussions. Students were told in their first class that an algorithm is “a set of instructions to solve a problem.” Early programming courses usually entail several forms of assessment, including weekly labs where students do multiple exercises, midterm exams (both practical and paper based), participation marks, and final exams. Labs or practical assignments are a key component of learning to program. Everything can make sense conceptually, but the experience of programming often makes students wrestle with the meaning of concepts, as well as the details of actually writing out the algorithm and making the program work. Most assignments are problem-based. Students are given a set of specifications and a problem that they have to solve with their program. Ideally, students must think about the key components of the problem and develop an algorithm to solve it and then implement that solution using code, while also testing the program to see if it gives the desired result in all cases.

Of course, not all students follow the ideal thought process and method. Often students will delve into writing out a solution in code before having developed a conceptual algorithm first. Regardless of which process students follow, however, the focus is on solving a particular problem. One of students’ first assignments, for example, is to write a program that calculates an investment growth given a certain principal and interest rate. As seen in Figure 3-2, students are given precise instructions, including the name of the file and the name of the variables they should create, as well as the format of

the output such as “two decimal places,” which is meant to make the number appear as a monetary amount. While assignment instructions are not nearly so detailed in later years, the clear focus in learning programming is on following a set of rules and procedures to solve a particular problem, mobilizing computers’ computational abilities, mathematical formulas, and various libraries and capacities that have been created and accumulated for computers such as text input and output, among others. These task statements thereby frame programming as a means for finding solutions to problems.

Figure 3-2: First-year problem statement

Progressively, students also learn about various forms of abstraction and encapsulation. These are presented as practical solutions to programming challenges, such as repeatedly rewriting the same code, which is generally seen as a waste of time and as producing code that is messy and hard to understand. Instead students learn to write functions, which are independent pieces of code that can be called on repeatedly to do something. The point is to abstract and factor out the commonalities between repeated pieces of code and write a function that is flexible and versatile in order to achieve that

1.2 Task Statement

If you invest principal amount of money (in dollars) at rate percent interest rate compounded annually, in numYears years, your investment will grow to

𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝 × (1 − (𝑝𝑝𝑝𝑝𝑟𝑟𝑟𝑟100 )𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛𝑛+1) 1 − 𝑝𝑝𝑝𝑝𝑟𝑟𝑟𝑟100

dollars.

Write a program invest.c that accepts positive integers principal, rate and numYears and computes the amount of money (of type float) earned after numYears years, presented in two decimal places.

have to write out one line of code that calls their new function multiple times, rather than repeating the many lines of code that make up the function. In later years students learn different “patterns” they can use in larger software development projects (Gamma et al. 1994). “The key is to recognize when things are the same” one professor explained. Students learn different ways of encapsulating pieces of code and creating particular relationships between them so that each piece can operate more or less independent of the other and pieces. For example, the graphical user interface, can then be changed or

replaced without having to rewrite the whole program, at least in theory.

Entire programming languages, such as Java, are designed around these concepts of abstraction and encapsulation. Java is known as an Object Oriented Programming Language, where everything is an Object based on Classes with particular properties and functions, some of which are public and can be accessed by other objects, and some of which are private, hidden within the internal functioning of the object and inaccessible to others. Most students learn Java beginning in their second programming course and are thereby taught this mode of thought whereby code should be abstracted and encapsulated so that a program becomes a series of ever larger and encompassing black boxes with particular public functionality accessible to those outside the black box. Information can be piped or passed from black box to black box to produce the ultimate desired results. Each black box works as a tool to produce a particular end.

This concept of encapsulation – creating black boxes – extends to other facets of students’ studies in computer science. In discussing how students should write a

available to them to answer the assignment questions. In particular, students can “use a theorem even if you don’t know how to prove it” saying it was like most students do not know how to build a TV, but they use one all the time. The TV and the theorems are black boxes that can be used to particular ends. Similarly, the programs – the worlds students have learned – themselves can be seen as black boxes with only public functionality that is accessible while the internal operation, the code, is hidden. The hidden functionality is partially why Open and Free Source Software is so significant to many programmers, because they can look inside the “black boxes” of particular

programs, see how they work, identify their limitations and the possibilities they afford, and even change them (Coleman 2013; Kelty 2008).

In 2006, Jeannette M. Wing introduced the term “computational thinking” as a kind of manifesto for an “analytical ability” that should be added to children’s learning alongside “reading, writing, and arithmetic” (Wing 2006, 33). There have, however, been previous calls for programming or computing to become an ubiquitous part of education; Turing Award winner Alan Perlis, for example, called in 1962 for all students on campus to learn to program (Guzdial 2008, 25). Wing and Perlis both argued that thought

processes associated with computing and computation could and should be applied to understanding a wide variety of disciplines and subjects, and there are other and earlier examples of proponents making similar arguments (Denning 2009, 28–29). The

arguments about the thought processes involved in computer science and the application of these thought processes to other facets of life by students and professors, discussed

Peter J. Denning argues that computer scientists are valued for their “computational doing” more than a process of thinking (that is not necessarily unique to the discipline) (Denning 2009, 30), the promotion of computational thinking as underlying the thought processes of multiple (if not all) disciplines and practices supports and encourages the value of rendering technical and related practices.

The thinking processes that students learn in studying computer science thus may not be unique to computer science (Denning 2009), but they are performative. Through discussing, learning, and practising these particular modes of thought, students learn to understand and build within the computational universe. They learn to create algorithms, focusing on creating step by step instructions that solve particular problems.

Concomitantly, what they learn to do with their programs or algorithms is just that, to solve problems. This approach necessitates a frame of reference as formed of problems and solutions. Students also learn about abstraction and encapsulation, creating programs such that they are formed as a series of black boxes that interact in only particular pre- defined ways, with internal workings hidden from view.