Fundamentals of Programming - Lesson 2: Notes
Data Items and Basic Data Types
The course introduces data items as text, numbers, and other material processed by a computer.
Data items used by a program are stored in memory where they can be processed to produce information.
Programs work with data in two broad forms: numeric and string.
Data items can be in three forms: literals (unnamed constants), variables, and named constants.
Literals/constants do not have identifiers like variables do.
Watch video: declaring variables and constants (link provided in transcript).
Understanding Data Types
A data item’s data type classifies:
What values can be held by the item
How the item is stored in memory
What operations can be performed on the item
Two broad data types supported by all languages:
Numeric: holds numbers; can be used in arithmetic operations
String: nonnumeric data; cannot be used in arithmetic operations
Many languages distinguish among numeric subtypes (e.g., integer vs floating-point/real numbers).
Some languages differentiate between integer (whole numbers) and floating-point (numbers with decimals).
Example distinction: 4 (integer) vs 4.3 (floating-point) may be stored in different numeric types.
The book focuses on two broad types: numeric and string.
Unnamed, Literal Constants
When using a fixed value in code, it is one of two constants:
Numeric constant (literal numeric constant): e.g., 43
String constant (literal string constant): appears within quotation marks, e.g., "Amanda"
Numeric constants do not include extraneous characters like dollar signs or commas in memory (they may be added for output readability but aren’t part of the number).
Strings can contain letters, digits, and other characters; they are enclosed in quotation marks.
Examples:
Numeric constant: 43
String constant: "Amanda"; also "51" or "$3,215.99 U.S." as strings.
Unnamed constants do not have identifiers like variables.
Watch video on data declaring and constants (link provided in transcript).
Working with Variables
Variables are named memory locations whose contents can change over time.
Example: myNumber and myAnswer in a number-doubling program.
A variable holds one value at a time; values can change during execution.
The ability of variables to change value enables writing reusable instructions for many inputs (e.g., payroll, electric bills).
Flowchart and pseudocode illustrate number-doubling program with myNumber and myAnswer.
Declarations
In most languages, you must declare a variable before you can use it.
A declaration provides:
A data type
An identifier
Optionally, an initial value
Why declare? It informs the compiler/interpreter about how to allocate memory and how to treat the variable.
Understanding a Declaration’s Data Type
A numeric variable holds digits and supports arithmetic operations.
A string variable holds text and other characters; can store digits as text (e.g., a zip code) but cannot participate in arithmetic.
Type-safety: some languages prevent assigning a value of the wrong type to a variable (strongly typed).
Examples of valid assignments with types:
taxRate = 2.5 // numeric
inventoryItem = "monitor" // string
Invalid examples illustrate type mismatch:
taxRate = "2.5" // numeric vs string
inventoryItem = 2.5 // numeric vs string
Note: Some languages allow mixing types via implicit conversion, but others (strongly typed) do not.
Understanding a Declaration’s Identifier
An identifier is the programmer-chosen name of a program component (variable, function/module, etc.).
Examples of identifiers: myNumber, myAnswer, inputValue, twiceTheValue.
Rules (language-dependent):
Identifiers may include letters and digits; may allow underscores, hyphens, or other characters depending on language.
Identifiers may be case sensitive (HoUrLyWage, hourlywage, HourlyWage are distinct).
Reserved keywords cannot be used as identifiers.
Length restrictions vary by language; identifiers are generally case sensitive in modern languages.
Quick Reference 2-1 (naming conventions) is introduced later in the chapter.
Convention for Naming Variables (and Quick Reference 2-1)
Common naming conventions:
Pascal casing: First letter of each word uppercase (also called upper camel casing).
Hungarian notation: Type information embedded in the name (e.g., nCount, sName).
Snake casing: Words separated by underscores (e.g., last_name).
Mixed case with underscores: Capitalizing new words after underscores (e.g., Last_Name).
Kebob case: Words separated by hyphens (e.g., last-name).
Examples and language associations:
HourlyWage, LastName, numHourly-Wage (visual Basic usage), lastname, hourly-wage, LastName, hourly-wage (language observations).
Adopting a naming convention helps readability and consistency.
The flowchart in Figure 2-2 follows rules: myNumber and myAnswer are single words with meaningful names.
Avoid using personal/colloquial names for identifiers in professional code.
Understanding a Declaration’s Identifier (continued) – Naming Rules in This Book
Three book rules for variable names:
1) Names must be one word (letters, digits, underscores allowed; no embedded spaces).
2) Names must start with a letter.
3) Names should be meaningfully descriptive (e.g., interestEarned over f or i).Rationale: clear, descriptive names ease long-term maintenance and collaboration.
The book’s naming guidelines emphasize readability, not locking you into language-specific syntax.
Notice: Flow of Variable Naming (Examples)
Flowchart 2-2 demonstrates two valid single-word identifiers: myNumber, myAnswer.
Avoid using personal names or puns in identifiers (considered unprofessional).
Assigning Values to Variables
Assignment statement example: myAnswer = myNumber * 2
Two actions in an assignment:
Compute the arithmetic value on the right-hand side.
Store the result in the memory location named on the left-hand side.
The equal sign is the assignment operator (binary operator with two operands).
Right-to-left associativity: the expression on the right is evaluated first, then assigned to the left.
Left-hand side (lvalue) must be a memory address identifier; right-hand side must be a value or expression.
Examples of valid assignments with two numeric variables:
someNumber = 2
someNumber = 3 + 7
someOtherNumber = someNumber
someOtherNumber = someNumber * 5
If the left side is not a memory address (e.g., a constant), the statement is invalid.
Initializing a Variable
Declaration can include an initialization (declare with a starting value).
If you declare a variable without initializing, the initial value is typically unknown (garbage).
Using garbage in arithmetic or output is generally illegal or erroneous.
Some languages provide default values, but the book assumes uninitialized variables hold garbage.
Where to Declare Variables
Variables must be declared before first use.
Some languages require all declarations at the beginning; others allow declarations anytime before first use.
This book follows the convention of declaring all variables together.
Declaring Named Constants
Named constants are like variables but can be assigned only once.
They are used to replace magic numbers with meaningful names (e.g., SALESTAXRATE).
Named constants improve maintainability: changing a constant value in one place updates all references when retranslated.
The book uses all uppercase identifiers with underscores for readability (e.g., SALESTAXRATE).
In some languages, constants must be initialized when declared; in others, they can be assigned later, but cannot change after first assignment.
Declaring named constants improves maintainability and reduces errors when values change.
Performing Arithmetic Operators
Standard operators in most languages: (the transcript lists +, -, *, /)
Additional operators exist for remainder, exponentiation, bit manipulation, etc.
All arithmetic operators are binary; require an expression on both sides.
Example: totalScore = score1 + score2; then, adding to totalScore: totalScore = totalScore + 10.
Operator Precedence and Associativity
Precedence rules:
Expressions in parentheses evaluate first (innermost parentheses first).
Multiplication and division are evaluated before addition and subtraction, from left to right.
Addition and subtraction are evaluated from left to right.
Assignment operator has very low precedence and is right-associative: the right-hand side is evaluated first.
Example: d = e * f + g
Multiplication and addition evaluated first, then assignment to d.
All arithmetic operators have left-to-right associativity for same-precedence operators.
The Integer Data Type
Some languages distinguish integers and floating-point numbers.
You can assign an integer to a floating-point variable (it becomes a float, e.g., 3 -> 3.0).
You cannot always assign a floating-point value to an integer variable (decimal part may be discarded).
Examples:
2.3 + 5 = 7.3
4.2
2 = 8.49.3 / 3 = 3.1
7 / 2 = 3 (in many languages for integer division)
When mixing types, division behavior depends on language rules.
Remainder/Modulo Operator
Remainder operator returns the remainder after division:
Example: 24 mod 10 = 4
In Visual Basic, the operator is Mod; in Java/C++/C#, it is %.
Useful for determining even/odd: remainder when divided by 2.
Note: Remainder semantics differ with negative operands; book avoids using remainder in language-independent sections.
Understanding Modularization
Modularization: break down problems into smaller units called modules, subroutines, procedures, functions, or methods.
A main program calls modules; control returns after module completes.
Reasons to modularize:
Abstraction: hide details and focus on high-level design
Collaboration: enables multiple programmers to work on different modules
Reuse: modules can be used in multiple programs
Examples of module roles:
A module computeFederalWithholdingTax() encapsulates withholding tax logic.
A displayAddressInfo() module encapsulates address display logic.
Providing Abstraction with Modularization
Abstraction helps see the big picture and ignore nonessential details.
High-level language features allow you to express complex tasks succinctly (e.g., output message) and rely on the OS to handle details.
Modules provide another layer of abstraction: you can replace module internals without changing main program calls.
Modularization Helps Multiple Programmers to Work on a Problem
Large programs are seldom written by a single programmer.
Division of work accelerates development and can improve reliability when modules are well-designed.
Reusing Work via Modularization
If a module is useful and well-written, it can be reused in multiple programs.
Example: a date-validation module can be used in payroll, user records, etc.
Reusability is a key advantage of modularization.
Modularizing a Program
A typical program structure comprises:
Main program (the driver) and one or more modules
When you create a module, you include:
A header: the module identifier and any necessary metadata
A body: the module statements
A return statement: marks end of module and returns control to caller
If a return statement is omitted, some languages implicitly return; book emphasizes explicit returns.
Naming and Calling Modules
Module naming: similar rules to variable names; typically followed by parentheses to distinguish modules from variables (e.g., computeTax())
A module can call other modules; there is no fixed limit to the number of chained calls (memory limits apply).
Flowchart symbol for calling a module is a rectangle with a bar across the top; the module name is placed inside.
Advantages of Modularization (Flow and Structure)
Encapsulation: modules contain their own instructions and can be reused.
Main program remains concise when it delegates work to modules (e.g., a single call to displayAddressInfo() instead of three separate outputs).
Encourages reuse and easier maintenance across programs.
When to Modularize
No fixed rules; guidelines emphasize functional cohesion: a module should perform one cohesive task.
A highly cohesive module checks date validity or displays warranty information; a module that performs many unrelated tasks is less cohesive.
Declaring Variables and Constants within Modules
You can place statements inside modules, including input, processing, and output statements.
Declarations (variables and constants) can also appear inside modules.
Scope rules:
Local variables/constants are visible only inside the module where declared.
Global variables/constants are visible to the entire program and all modules (as assumed for teaching examples).
Example: LINE1, LINE2, LINE3 constants declared inside a module to hold address lines.
Why local vs global matters: portability and reusability of modules; module data should travel with the module when used elsewhere.
The book’s approach: use global variables for main program and keep module data portable by declaring constants within modules where used.
Global vs Local Variables and Constants
Global: known to entire program; usable in all modules.
Local: visible only within the module where declared.
The book simplifies by treating main program variables (name, balance) as global for early chapters.
This layout facilitates focus on main logic without delving into inter-module data sharing techniques.
Most Common Configuration for Mainline Logic
A procedural program typically follows three parts:
1) Housekeeping tasks: initialization, declarations, prompts, opening files, etc. (executed once)
2) Detail loop tasks: the core work; repeated for each data item using a loop until end-of-file (eof) or sentinel conditions.
3) End-of-job tasks: finalization, totals, closing files.The figure 2-6 relationship demonstrates how housekeeping and end-of-job are executed once, while detailLoop repeats.
Pseudocode uses while/endwhile to express loops; true programming languages may use while loops or for loops.
Mainline Logic: Three-Part Structure in Practice
Example: payroll report program
Input employee names until sentinel (e.g., XXX)
For each employee: collect gross pay, compute deductions, net pay, and output lines
The three-module approach (housekeeping, detailLoop, endOfJob) helps manage workflow and readability.
Hierarchy Charts and Structure Charts
A program hierarchy chart (structure chart) shows which modules exist and how they call each other.
It does not specify internal module logic, sequencing, or why modules are called—only relationships.
Example: a program where main module calls housekeeping, detailLoop, and endOfJob.
Reuse of a module from multiple locations is shown with a corner-blackened box to indicate shared usage.
Structure charts help planning and documentation; they reveal dependencies and potential ripple effects when a module changes.
Good Program Design Features
Desk-checking: walking through logic on paper before coding to improve correctness.
Program comments: provide explanations that are not executed but help readers understand code.
Choosing identifiers: aim for meaningful, pronounceable names; avoid cryptic abbreviations; consider cultural readability.
Designing clear statements: avoid confusing line breaks and use temporary variables to clarify long expressions.
Clear prompts and echoing input: prompts should guide user input; echoing input helps prevent entry errors.
Writing clear prompts and echoing input:
Separate prompts for each input item
Echo input in subsequent prompts to reduce mistakes
Maintaining good programming habits: plan before coding; flowcharts or pseudocode aid future projects.
Program Comments
Comments are non-executing explanations used for documentation.
Pseudocode uses // to start comments in this text.
Annotation symbols in flowcharts provide extra information without cluttering symbols.
Benefits: easier to modify, easier to understand when revisiting code years later.
Flowcharts, Annotations, and Documentation
Annotations: three-sided boxes connected to a step via dashed lines to provide extra information or long statements.
Flowcharts and pseudocode can include comments to explain variable purposes or complex calculations.
Choosing Identifiers (Identifying Good Names)
Identifiers should be one word (no embedded spaces); may include letters, digits, underscores; starting with a letter.
Use nouns for variables/constants and verbs for modules (e.g., computePayRate()).
Prioritize meaningful names over cryptic ones; self-documenting code is easier to understand without extra documentation.
Pronounceable names: avoid pronounceability issues; avoid confusing abbreviations; consider cultural differences in interpretation.
Avoid digits in names when possible (e.g., 0-9 lookalikes can be confused with letters).
Consider long multi-word names readable using underscores (snake_case) or camelCase conventions depending on language.
Do not mix case inconsistently within a program; avoid having empName, EmpName, and Empname in the same program.
For booleans, consider including is/are in the name (e.g., isFinished).
Many organizations enforce naming conventions; always align with organization standards.
A data dictionary can be created to document all variable names with types, sizes, and descriptions.
Refactoring and Tools for Identifiers
To save typing, you can start with short names and later refactor to longer, meaningful names (e.g., employeeFirstName).
IDEs often support auto-completion and find/replace features to rename identifiers across a program.
Be mindful of language case-sensitivity when renaming identifiers.
Avoiding Ambiguity in Long Names
Use readable separators for multiword names: underscores, hyphens, or camelCase depending on the language.
Avoid changing case for variables that could cause confusion in languages that are case-sensitive.
Use a form of the verb to be in Boolean variable names (e.g., isFinished).
Maintain organization-wide conventions for consistent naming.
Practical Guidelines for Readability and Maintenance
Self-documenting code: choose meaningful, descriptive names that convey intent without needing extra comments.
Use conventions consistently to improve readability across teams.
Include a data dictionary as part of program documentation to describe all variables and constants.
Summary of Key Formulas and Constants (LaTeX)
Assignment with arithmetic:
Right-hand side evaluated first; result stored in left-hand side variable.
Left-hand side is an lvalue (memory address reference).
Arithmetic precedence:
Parentheses first
Then multiplication/division left to right
Then addition/subtraction left to right
Assignment has very low precedence and is right-associative
Example for precedence:
Integer vs floating-point division (language-dependent):
Remainder/Modulo example:
24 mod 10 = 4Tax example (named constant RATE):
Volume conversion (cubic inches to cubic feet):
Unit conversions for BMI (as given in the text):
Height:
Weight:
BMI:
Dimensional constants in remodeling program example: 1 inch = 2.54 cm; 1 m = 100 cm; 1 lb = 453.59 g; 1 kg = 1000 g.
Named constants example for payroll: RATE = 0.25, QUIT = "XXX", REPORT_HEADING = "Payroll Report".
Percent/tax example for price with tax:
Assessment Tasks (Contextual reference)
The summary includes references to tasks that explore naming quality, valid assignments, expressions, hierarchy charts, and modular design problems. These tasks reinforce the concepts of naming, data types, constants, modularization, and mainline logic structure.
Real-World and Practical Implications
Clear data typing and variable naming reduce maintenance cost and onboarding time for new developers.
Modularity supports teamwork and reuse, enabling large-scale software systems to be built from well-defined, swap-in components.
Abstraction through modules allows teams to separate concerns and define interfaces between components.
Proper prompts and echoing input improve user experience and reduce data-entry errors in interactive programs.
Quick Reference: Key Terms
Data item, data type, numeric, string, literals, variables, named constants, constants, declarations, identifiers, type-safety, lvalue, rvalue, assignment operator, precedence, associativity, modularization, module/header/body/return, encapsulation, global vs local scope, cohesion, desk-checking, comments, structure chart, hierarchy chart, prompts, echoing input, data dictionary.