On this page:
A Data-Centric Introduction to Computing
Sunday, September 12th, 2021 6:08:38pm

A Data-Centric Introduction to Computing

Kathi Fisler, Shriram Krishnamurthi, Benjamin S. Lerner, Joe Gibbs Politz

    I Introduction

      1 Overview

        1.1 What This Book is About

        1.2 The Values That Drive This Book

        1.3 Our Perspective on Data

        1.4 What Makes This Book Unique

        1.5 Who This Book is For

        1.6 The Structure of This Book

        1.7 Organization of the Material

        1.8 Our Programming Language Choice

      2 Acknowledgments

    II Foundations

      3 Getting Started

        3.1 Motivating Example: Flags

        3.2 Numbers

        3.3 Expressions

        3.4 Terminology

        3.5 Strings

        3.6 Images

          3.6.1 Combining Images

          3.6.2 Making a Flag

        3.7 Stepping Back: Types, Errors, and Documentation

          3.7.1 Types and Contracts

          3.7.2 Format and Notation Errors

          3.7.3 Finding Other Functions: Documentation

      4 Naming Values

        4.1 The Definitions Window

        4.2 Naming Values

          4.2.1 Names Versus Strings

          4.2.2 Expressions versus Statements

        4.3 The Program Directory

          4.3.1 Understanding the Run Button

        4.4 Using Names to Streamline Building Images

      5 From Repeated Expressions to Functions

        5.1 Example: Similar Flags

        5.2 Defining Functions

          5.2.1 How Functions Evaluate

          5.2.2 Type Annotations

          5.2.3 Documentation

        5.3 Functions Practice: Moon Weight

        5.4 Documenting Functions with Examples

        5.5 Functions Practice: Cost of pens

        5.6 Recap: Defining Functions

      6 Conditionals and Booleans

        6.1 Motivating Example: Shipping Costs

        6.2 Conditionals: Computations with Decisions

        6.3 Booleans

          6.3.1 Other Boolean Operations

          6.3.2 Combining Booleans

        6.4 Asking Multiple Questions

        6.5 Evaluating by Reducing Expressions

        6.6 Composing Functions

          6.6.1 How Function Compositions Evaluate

          6.6.2 Function Composition and the Directory

        6.7 Nested Conditionals

        6.8 Recap: Booleans and Conditionals

      7 Introduction to Tabular Data

        7.1 Creating Tabular Data

        7.2 Extracting Rows and Cell Values

        7.3 Functions over Rows

        7.4 Processing Rows

          7.4.1 Finding Rows

          7.4.2 Ordering Rows

          7.4.3 Adding New Columns

          7.4.4 Calculating New Column Values

        7.5 Examples for Table-Producing Functions

      8 Processing Tables

        8.1 Cleaning Data Tables

          8.1.1 Loading Data Tables

          8.1.2 Dealing with Missing Entries

          8.1.3 Normalizing Data

          8.1.4 Normalization, Systematically

            8.1.4.1 Using Programs to Detect Data Errors

        8.2 Task Plans

        8.3 Preparing Data Tables

          8.3.1 Creating bins

          8.3.2 Splitting Columns

        8.4 Managing and Naming Data Tables

        8.5 Visualizations and Plots

        8.6 Summary: Managing a Data Analysis

      9 From Tables to Lists

        9.1 Basic Statistical Questions

        9.2 Extracting a Column from a Table

        9.3 Understanding Lists

          9.3.1 Lists as Anonymous Data

          9.3.2 Creating Literal Lists

        9.4 Operating on Lists

          9.4.1 Built-In Operations on Lists of Numbers

          9.4.2 Built-In Operations on Lists in General

          9.4.3 An Aside on Naming Conventions

          9.4.4 Getting Elements By Position

          9.4.5 Transforming Lists

          9.4.6 Recap: Summary of List Operations

        9.5 Lambda: Anonymous Functions

        9.6 Combining Lists and Tables

      10 Processing Lists

        10.1 Making Lists and Taking Them Apart

        10.2 Some Example Exercises

        10.3 Structural Problems with Scalar Answers

          10.3.1 my-len: Examples

          10.3.2 my-sum: Examples

          10.3.3 From Examples to Code

        10.4 Structural Problems that Transform Lists

          10.4.1 my-doubles: Examples and Code

          10.4.2 my-str-len: Examples and Code

        10.5 Structural Problems that Select from Lists

          10.5.1 my-pos-nums: Examples and Code

          10.5.2 my-alternating: Examples and Code

        10.6 Structural Problems with Sub-Domains

          10.6.1 my-max: Examples

          10.6.2 my-max: From Examples to Code

        10.7 More Structural Problems with Scalar Answers

          10.7.1 my-avg: Examples

        10.8 Structural Problems with Accumulators

          10.8.1 my-running-sum: First Attempt

          10.8.2 my-running-sum: Examples and Code

          10.8.3 my-alternating: Examples and Code

        10.9 Dealing with Multiple Answers

          10.9.1 uniq: Problem Setup

          10.9.2 uniq: Examples

          10.9.3 uniq: Code

          10.9.4 uniq: Reducing Computation

          10.9.5 uniq: Example and Code Variations

          10.9.6 uniq: Why Produce a List?

        10.10 Monomorphic Lists and Polymorphic Types

      11 Introduction to Structured Data

        11.1 Understanding the Kinds of Compound Data

          11.1.1 A First Peek at Structured Data

          11.1.2 A First Peek at Conditional Data

        11.2 Defining and Creating Structured and Conditional Data

          11.2.1 Defining and Creating Structured Data

          11.2.2 Annotations for Structured Data

          11.2.3 Defining and Creating Conditional Data

        11.3 Programming with Structured and Conditional Data

          11.3.1 Extracting Fields from Structured Data

          11.3.2 Telling Apart Variants of Conditional Data

          11.3.3 Processing Fields of Variants

      12 Collections of Structured Data

        12.1 Lists as Collective Data

        12.2 Sets as Collective Data

          12.2.1 Picking Elements from Sets

          12.2.2 Computing with Sets

        12.3 Combining Structured and Collective Data

        12.4 Data Design Problem: Representing Quizzes

      13 Recursive Data

        13.1 Functions to Process Recursive Data

        13.2 A Template for Processing Recursive Data

      14 Trees

        14.1 Data Design Problem – Ancestry Data

          14.1.1 Computing Genetic Parents from an Ancestry Table

          14.1.2 Computing Grandparents from an Ancestry Table

          14.1.3 Creating a Datatype for Ancestor Trees

        14.2 Programs to Process Ancestor Trees

        14.3 Summarizing How to Approach Tree Problems

        14.4 Study Questions

      15 Interactive Games as Reactive Systems

        15.1 About Reactive Animations

        15.2 Preliminaries

        15.3 Version: Airplane Moving Across the Screen

          15.3.1 Updating the World State

          15.3.2 Displaying the World State

          15.3.3 Observing Time (and Combining the Pieces)

        15.4 Version: Wrapping Around

        15.5 Version: Descending

          15.5.1 Moving the Airplane

          15.5.2 Drawing the Scene

          15.5.3 Finishing Touches

        15.6 Version: Responding to Keystrokes

        15.7 Version: Landing

        15.8 Version: A Fixed Balloon

        15.9 Version: Keep Your Eye on the Tank

        15.10 Version: The Balloon Moves, Too

        15.11 Version: One, Two, ..., Ninety-Nine Luftballons!

      16 Examples, Testing, and Program Checking

        16.1 From Examples to Tests

        16.2 More Refined Comparisons

        16.3 When Tests Fail

        16.4 Oracles for Testing

    III Algorithms

      17 Functions as Data

        17.1 A Little Calculus

        17.2 A Helpful Shorthand for Anonymous Functions

        17.3 Streams From Functions

        17.4 Combining Forces: Streams of Derivatives

      18 Predicting Growth

        18.1 A Little (True) Story

        18.2 The Analytical Idea

        18.3 A Cost Model for Pyret Running Time

        18.4 The Size of the Input

        18.5 The Tabular Method for Singly-Structurally-Recursive Functions

        18.6 Creating Recurrences

        18.7 A Notation for Functions

        18.8 Comparing Functions

        18.9 Combining Big-Oh Without Woe

        18.10 Solving Recurrences

      19 Sets Appeal

        19.1 Representing Sets by Lists

          19.1.1 Representation Choices

          19.1.2 Time Complexity

          19.1.3 Choosing Between Representations

          19.1.4 Other Operations

        19.2 Making Sets Grow on Trees

          19.2.1 Converting Values to Ordered Values

          19.2.2 Using Binary Trees

          19.2.3 A Fine Balance: Tree Surgery

            19.2.3.1 Left-Left Case

            19.2.3.2 Left-Right Case

            19.2.3.3 Any Other Cases?

      20 Halloween Analysis

        20.1 A First Example

        20.2 The New Form of Analysis

        20.3 An Example: Queues from Lists

          20.3.1 List Representations

          20.3.2 A First Analysis

          20.3.3 More Liberal Sequences of Operations

          20.3.4 A Second Analysis

          20.3.5 Amortization Versus Individual Operations

        20.4 Reading More

      21 Sharing and Equality

        21.1 Re-Examining Equality

        21.2 The Cost of Evaluating References

        21.3 On the Internet, Nobody Knows You’re a DAG

        21.4 From Acyclicity to Cycles

      22 Graphs

        22.1 Understanding Graphs

        22.2 Representations

          22.2.1 Links by Name

          22.2.2 Links by Indices

          22.2.3 A List of Edges

          22.2.4 Abstracting Representations

        22.3 Measuring Complexity for Graphs

        22.4 Reachability

          22.4.1 Simple Recursion

          22.4.2 Cleaning up the Loop

          22.4.3 Traversal with Memory

          22.4.4 A Better Interface

        22.5 Depth- and Breadth-First Traversals

        22.6 Graphs With Weighted Edges

        22.7 Shortest (or Lightest) Paths

        22.8 Moravian Spanning Trees

          22.8.1 The Problem

          22.8.2 A Greedy Solution

          22.8.3 Another Greedy Solution

          22.8.4 A Third Solution

          22.8.5 Checking Component Connectedness

    IV Programming with State

      23 From Pyret to Python

        23.1 Expessions, Functions, and Types

        23.2 Returning Values from Functions

        23.3 Examples and Test Cases

        23.4 An Aside on Numbers

        23.5 Conditionals

        23.6 Creating and Processing Lists

          23.6.1 Filters, Maps, and Friends

        23.7 Data with Components

          23.7.1 Accessing Fields within Dataclasses

        23.8 Traversing Lists

          23.8.1 Introducing For Loops

            23.8.1.1 An Aside on Order of Processing List Elements

          23.8.2 Using For Loops in Functions that Produce Lists

          23.8.3 Summary: The List-Processing Template for Python

      24 Modifying Variables

        24.1 Modifying Variables in Memory

        24.2 Modifying Variables Associated with Lists

        24.3 Writing Functions that Modify Variables

          24.3.1 The global annotation

        24.4 Testing Functions that Modify global Variables

          24.4.1 The Internal Structure of a Test Function

          24.4.2 Takeaways on Testing Modifications

      25 Modifying Structured Data

        25.1 Modifying Fields of Structured Data

        25.2 Modifications to Shared Data

        25.3 Understanding Memory

        25.4 Modifications to Structured Data, Revisited

        25.5 Basic Data in Memory

        25.6 Variables and Equality

        25.7 Takeaways on Modifying Variables

      26 Revisiting Lists and Variables

        26.1 Sharing List Updates

          26.1.1 Operations that Mutate Lists

        26.2 Lists in Memory

        26.3 Practice: Data for Shared Bank Accounts

        26.4 Circular References

          26.4.1 Testing Circular Data

          26.4.2 Revisiting Variables: A Function to Create Accounts for New Customers

        26.5 The Many Roles of Variables

        26.6 Managing All Accounts

      27 Hashtables and Dictionaries

        27.1 Searching by Criteria Other than Keys

        27.2 Dictionaries with More Complex Values

        27.3 Using Structured Data as Keys

    V Advanced Topics

      28 Algorithms That Exploit State

        28.1 Disjoint Sets Redux

          28.1.1 Optimizations

          28.1.2 Analysis

        28.2 Set Membership by Hashing Redux

          28.2.1 Improving Access Time

          28.2.2 Better Hashing

          28.2.3 Bloom Filters

        28.3 Avoiding Recomputation by Remembering Answers

          28.3.1 An Interesting Numeric Sequence

            28.3.1.1 Using State to Remember Past Answers

            28.3.1.2 From a Tree of Computation to a DAG

            28.3.1.3 The Complexity of Numbers

            28.3.1.4 Abstracting Memoization

          28.3.2 Edit-Distance for Spelling Correction

          28.3.3 Nature as a Fat-Fingered Typist

          28.3.4 Dynamic Programming

            28.3.4.1 Catalan Numbers with Dynamic Programming

            28.3.4.2 Levenshtein Distance and Dynamic Programming

          28.3.5 Contrasting Memoization and Dynamic Programming

    VI Appendices

      29 Pyret for Racketeers and Schemers

        29.1 Numbers, Strings, and Booleans

        29.2 Infix Expressions

        29.3 Function Definition and Application

        29.4 Tests

        29.5 Variable Names

        29.6 Data Definitions

        29.7 Conditionals

        29.8 Lists

        29.9 First-Class Functions

        29.10 Annotations

        29.11 What Else?

      30 Pyret vs. Python

      31 Glossary