Class 1

Introduction, algorithms, variables

Course Administration: Part 1

  1. The course webpage go/cs146 is the official resource (syllabus, etc.) the course. Each day has a page with my notes, designed for you to follow along in class.
  2. Remember to bring your computer to class each day (or obtain a loaner laptop as described in the syllabus). At a minimum you will need to access our in-class web application go/cs146-inclass. We will use this site for in-class polling, for asking questions and anonymous emoji responses.

Objectives for today

  1. Define algorithm, semantics, and syntax
  2. Introduce Picobot
  3. Implement a Picobot algorithm
  4. Describe the purpose of a variable and perform variable assignment
  5. Evaluate arithmetic expressions over integers and floats
  6. Describe the concept of Type

Why are we here?

Presumably you are taking this class for a variety of (non-exclusive) reasons:

  1. Interest in the CS major
  2. Develop computational skills for use in another (possibly scientific) domain

These are not in opposition. As a CS major you are likely to apply your computational skills to problems in other domains (sometimes called “CS+X”). For example, most of my research is focused on human genomics. The opportunity to have an impact in other domains, such as improving human health, is what draws me to CS!

What is the difference between CSCI145 and CSCI146

The short answer: pace and approximately 1-2 weeks of content. The longer answer: CS4All emphasizes six concepts at the heart of CS: data, problem solving, algorithms, programming, abstraction, and creativity (Alvarado et al. 2019). You will get experience with all 6 in either class. This course does not assume any prior programming experience, Python or otherwise. But we do leverage your prior quantitative experience to create space to learn more about tools and techniques, like plotting libraries, used for scientific computing and data analysis.

Why Computer Science?

What do we use computers for, especially in the sciences? Why pursue CS at all? It is hard to answer those questions without defining “What is Computer Science?” (but also hard to define “Computer Science”).

There is no single definition of “Computer Science”. Some describe it as the study of complexity, others as the study of automating tasks (Alvarado et al. 2019). While the latter seems like it might trivialize the discipline, I think it is just the opposite. A computer is the right tool when you need to do something more than once (and perhaps many, many, times). And doing something more than once, and doing so efficiently, depends on a range of innovations and knowledge from applied math to psychology!

Alvarado, Christine, Ran Libeskind-Hadas, Geoffrey H. Kuenning, and Zachary Dodds. 2019. CS for All: An Introduction to Computer Science Using Python. Franklin, Beedle & Associates Incorporated.

It may be easier to describe what Computer Science is not. It is not study of how computers work (in the way that the natural sciences are the study of how the natural world works). And it is not just about programming, i.e., programming is to CS as telescopes are to astronomy. A means to an end (not the end itself).

Attributed in various forms to famous computer scientist Edgar Dijkstra.

A definition for CS I like is “Algorithmic thinking/problem solving usually (but not always) involving computers.”

Again the implementation (the part involving the computer) is just one component of solving a computational problem. We need to be able to answer a number of questions on our way to solving a computational problem, only one of which is about programming :

Adapted from Zach Dodds
  1. Can you solve this problem with a computer at all? If not, can you prove the problem is solvable (or not)? (Spoiler alert: Not always…)
  2. Can you create a process (algorithm and implementation) to solve such problems?
  3. What resource do you need to find a solution (e.g., how long does it take)?
  4. Do you have the “best” solution?

By the end of the semester we will be able to answer all of these questions for many computational problems!

Algorithms

What is an algorithm? What might be an analogy for an algorithm that we encounter outside computation? As a hint, think about the kitchen…

A recipe is a ready, if informal, analogy for an algorithm.

More formally, an algorithm:

  1. Has a finite number of instructions or steps
  2. Each instruction (step) is well-defined (i.e., not ambiguous) and computable
  3. Eventually halts (i.e., executes in a finite amount of time)
  4. Solves a general class of problems

Another similar definition is:

An algorithm is a well-ordered collection of unambiguous and effectively computable operations that when executed produces a result and halts in a finite amount of time.(Schneider and Gersting 1995)

Schneider, M, and J Gersting. 1995. An Invitation to Computer Science. New York, NY: West Publishing Company.

Problem solving (with Picobot as an example)

Our general approach to problem solving:

  1. Explicitly define problem to be solved (inputs, outputs, etc.)
  2. Develop an algorithm to solve the problem
  3. Implement that algorithm as a program

We will first try out these steps in the context of Picobot, a 2-D programmable “robot” that is similar to the Roomba vacuum. Picobot has limited capabilities, it can only move in cardinal directions (North, East, South and West) and only sense (and act on) information (the presence or absence of a wall) immediately adjacent to it in a cardinal direction - termed local sensing. The goal is to cover (i.e., vacuum) the entire room, from a random starting position.

Check out the Picobot simulator. Picobot’s capabilities are described more here.

How could we explicitly define the problem?

  • Input: Empty room, with the Picobot at a random starting position, but always in state 0.
  • Output: Traverse all spaces without getting “stuck” (traversing a space multiple times is OK).
  • Picobot can only move in cardinal directions and only sense the presence/absence of walls immediately adjacent in a cardinal direction.

One of the trickier aspects of Picobot can be the “state”. State is Picobot’s “memory”, how it knows, for example, that it is supposed to be going “north”. Recall that Picobot can only sense its local surroundings and doesn’t have any overarching sense of direction (other than those local observations). The state can provide that context. More generally, the state of the computer is its current condition or alternately its current internal configuration. For Picobot the state is a number from 0 - 99. That number doesn’t have any intrinsic or built-in meaning. The meaning comes from you. For example, you could effectively define state 0 as the “going north till it hits a wall” and staste 1 as the “going south until it can’t anymore” state (or whatever numbers you choose). That is I recommended associating a goal with each state, e.g., “go all the way to the east”. And when you want Picobot to switch to a new goal, you probably want to switch to a different state.

Having learned about Picobot works, let’s consider the initial example algorithm provided on the Picobot page. Without testing it in the simulator, will the following algorithm traverse all the open squares of the “empty room” from a random starting position?

# 
# Hashtag lines are optional comments that are ignored by Picobot
#

# State 0 with nothing N: Go one step N
0 x*** -> N 0   

# State 0 with a wall to the N: Go W and into state 1 
# ** This will crash if picobot has a wall to the W! **
0 N*** -> W 1 

# State 1 with nothing to the S: Go one step S
1 ***x -> S 1   

# State 1 with a wall to to the S: Stay put and go into state 0
1 ***S -> X 0  

Don’t be afraid to use a piece of paper to help you keep track of Picobot’s behavior. The “Computer” in Computer Science doesn’t mean we don’t ever use pencil/paper to help us! Also don’t be afraid to “act out” what Picobot is doing. What we are practicing here is building a mental model of the current state of the computation, i.e., Picobot’s location and the current rule state, and then projecting the “next” state of the computation based on the algorithm, i.e., Picobot’s rules.

Peer Instruction (PI) questions are a validated technique for active learning(Porter et al. 2016). Each PI question will have 4 steps:

  1. Solo answer: Think for yourself and select answer
  2. Discuss: Analyze the problem in teams
    • The goal is to practice analyzing and talking about new and challenging concepts
    • Reach a single consensus answer
    • If you have questions, raise your hand and I will visit
  3. Group answer: Everyone in your group selects the shared consensus answer
  4. Reveal and class-wide discussion: Led by YOU (students)
    • Tell us what you talked about in your discussion that everyone should know!
    • I want to hear the way your group thought about the problem. This way you are exposed to your classmates’ though processes, not just mine.
    • I am particularly interested in your ability to explain why the WRONG answers are WRONG.
Porter, Leo, Dennis Bouvier, Quintin Cutts, Scott Grissom, Cynthia Lee, Robert McCartney, Daniel Zingaro, and Beth Simon. 2016. “A Multi-Institutional Study of Peer Instruction in Introductory Computing.” In, 358–63. New York, New York, USA: ACM Press. https://doi.org/10.1145/2839509.2844642.

As we predicted, with the initial rules, Picobot will get stuck in the “northwest” corner of the maze. How could you change the algorithm to prevent Picobot from getting stuck? (Note that there are multiple potential solutions). What would you want Picobot to do differently when it gets to that upper left corner? And then how could you implement that algorithm in terms of Picobot’s rules? The order of those questions was purposeful, I suggest you articulate your approach in natural language first (e.g., “After Picobot gets stuck in the NW corner, it should …”) and then start figuring out to implement that plan in Picobot rules. As a hint, you already have effective rules for traversing the space from east to west. How could you take advantage of those existing rules to cover the entire room?

Picobot challenge

Optionally with a partner, develop an algorithm to traverse the entire empty room and implement that algorithm as a set of Picobot rules (steps 2 and 3 above). I have provided a empty_room.txt starter file with the rules above that you can download and modify (right click and download the linked file). Test your rules with the Picobot simulator.

Once you have a working set of rules, save your rules as a text file (using Notepad on Windows or TextEdit on Mac) named empty_room.txt. If you are using TextEdit make sure to select “Format→Make Plain Text” so that you can save a plain “.txt” file that Gradescope understands (instead of a Rich Text File). You will then submit your solution to https://gradescope.com following these instructions. We will use Gradescope to submit all of our programming assignments, so this is a chance to activate your account and try out the site. Gradescope will automatically test your submission to make sure it works correctly. Note that the file name and format matters, you must name your file exactly as specified. If you are not yet registered for the class in Banner, notify me (the instructor) so I can add you to Gradescope. You can submit multiple times, only the last submission will be retained. If you do work with a partner, whoever submits to Gradescope should make sure to add their group mate as described here.

For this problem, Gradescope will test your Picobot program for correctness and record the number of steps needed to traverse the room and the number of rules used. This is not a graded assignment (ignore the points, they are needed for Gradescope to display tests properly), but those two values are used to populate a leaderboard. The team(s) with the best submission, i.e., the fewest steps (using the smaller number of rules to break ties), will win a small prize! Your solution has to pass the tests, i.e., be correct, to be eligible (think correctness first, then efficiency then conciseness…).

Course Administration: Part 2

The online syllabus has information on office hours, books, schedule, grading, etc. The website is the “official” source for the syllabus, course policies, etc.

Please note:

  1. How to get help: My office hours, the online discussion board at go/cs146-ed, and peer drop-in help sessions go/cshelp
  2. The Honor Code, and specifically that online search and generative AI (e.g., ChatGPT, GitHub Copilot) are not permitted resources. Our goal is build our fundamental understanding of CS and Python; those tools don’t help us do so.

We will typically have class like this on Monday and Wednesday, then a quiz and collaborative problem solving during the “lab period” on Friday. At the beginning of most Friday labs we will have a regular short quiz on the material we covered during the week. The quizzes are intended to provide a low-stakes opportunity to check whether you understand the material.

To prepare for the quizzes (and the exams) there are ungraded practice problems (and solutions) available via the course webpage (“Practice problems”) links. Many are randomized, that is you can request new variants of the problem to get more practice. We are experimenting with a new system for this, and so there will likely be hiccups. Your patience and feedback is greatly appreciated!

I encourage you to attempt those problem on paper first. Computer Science (and even programming, specifically) is not all about the computer. As we observed already, our success depends on us building an accurate mental model of what the computer is doing; paper-based problems will help us do so!

Syntax vs. Semantics…

  • Syntax is the structure of a (valid) statement(s), while the semantics are the meaning of the statement.
  • Syntax is often very specific to a particular programming language, while the semantics are generally not.

For example the Python programming language has undergone substantial syntactic evolution: print 4 became print(4). Those statements are syntactically different but semantically identical.

When implementing an algorithm, it is always tempting to jump right into the implementation, that is jump right to the syntax. I advocate you resist that impulse, and really think through your algorithm and the semantics of its implementation first (i.e., what building blocks will you use to construct your solution).

Python 3

We will be using Python 3, a widely-used, widely-available, general-purpose programming language. Note that I said Python 3 (not 2), Python 3 is not backward compatible. Lets get started!

We will primarily interact with Python via the Thonny integrated development environment (IDE). Thonny has a number of features that will learn about in turn, today we will be working in the bottom (or right) box, the “Shell”. This gives us access to Python’s REPL (read-eval-print-loop), also called an interpreter.

The >>> is the prompt for us to enter Python code.

Let’s try some basic expressions, hitting enter after each:

>>> 1
1
>>> 5
5

These are termed “literal” expressions, because the resulting value is the same as the expression itself.

Now some more complex expressions that include “operators”:

>>> 2 + 2
4
>>> 15 * 20
300
>>> 20 / 4
5.0
>>> 10 - 20
-10

When we hit “enter”, Python is evaluating the expression (the “eval” in REPL) and printing the results.

Important

Going forward the examples in the notes will elide the >>> because we actually execute each snippet to create the notes. Unlike the “REPL”, the output is printed after the block instead of between each line, but otherwise execution is identical.

What about errors?

2 asdf 2
  Cell In[2], line 1
    2 asdf 2
      ^
SyntaxError: invalid syntax

We didn’t follow the syntactic rules of the language and so Python reported an error. Python has no idea what “asdf” means, it is not an operator built-in to the language.

Helpfully, Python does tell us where it encountered the error (which may or may not be the same as location of the cause of the error), but it doesn’t tell us how to fix it (because it can’t read our minds to know what we wanted it to do). Often the error messages will seem a little opaque, one of the skills you will develop over time is the mapping of error messages to the likely root cause of the error.

Python Types

Earlier we saw 5 and 5.0. What is the difference between those? They have different types. 5.0 is a floating point value or float, 5 is an integer value or int.

A type consists of two things:

  1. A set of values, and
  2. A set of operations that can be applied to those values.

Integers are exactly what they sound like, while floating point numbers are a subset of the Real numbers. Both are necessarily finite subsets of their domains, that is the computer can’t represent all integers or all real numbers at infinite precision.

We will learn much more about numerical precision at the end of the semester.

We can apply a variety of arithmetic and other operations to those values. Let’s investigate an example of “set of operations” by figuring out the difference between / and //. Both are valid Python operators.

8 / 3
8 // 3
2.6666666666666665
2

What do you notice? The latter appears to round to an integer. How does it round? It doesn’t appear to be “normal” rounding rules (since 2.66 ≥ 2.5 it should have rounded to 3), but is it rounding “down” or rounding towards zero? How could we figure out?

-8 // 3
-3

The above shows us it always rounds “down” (towards negative infinity). And in fact this is called the “floor division” operator. What are the type rules for these operators and how are they different? We can already see integer division and integer floor division produce different types. How could we figure out the type rules? Much as we did above we could experiment…

8 / 3.0
8 // 3.0
8.0 // 3
2.6666666666666665
2.0
2.0

What we observe is that division of integers produces a float, while floor division of integers produces an integer. For both operators, if either operand is a float, the other is converted to a float (if not already) and the result is a float. Note that // applied to floats still rounds “down”.

This experimentation is not to the exclusion of reviewing the documentation. In general, we should start by consulting the relevant Python documentation (which in this case confirms and expands upon our observations). However, we want to develop both skills: 1) using the documentation and 2) inferring and verifying behavior via experimentation

What about more complex expressions involving multiple operators, e.g., 2 + 3 * 4? In general, Python follows PEMDAS. So this expression would be interpreted as 2 + (3 * 4) and evaluate to 14, i.e.,

2 + 3 * 4
14

Non-numeric types

"hello"
'hello'

We term "hello" a string literal because it is a string (sequence) of characters whose value is the characters themselves, i.e., we are literally and exactly specifying the value. We indicate strings by characters between either double or single quotes (you can’t mix double and single quotes). Thus "hello" and 'hello' are equivalent.

We can apply certain operators to strings, for example

 "hello" + "goodbye"
 "hello" * 2
'hellogoodbye'
'hellohello'

but what about?

"hello" + 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[9], line 1
----> 1 "hello" + 2

TypeError: can only concatenate str (not "int") to str

Python is telling us that adding an integer to a string isn’t a supported operation of the string types. Concatenation of strings with + is supported (we just saw that) and Python does know how to convert integers to strings. But Python won’t do so implicitly as it can’t be sure that is what you intended (recall what we learned previously about ambiguity). You need to explicitly convert the integer to a string with the str function (As you might expect, there are corresponding int and float functions that convert the input to the corresponding types - including strings. Try int("10") in the shell).

"hello" + str(2)
'hello2'