Software Construction

Course Resources

Administrivia: Course Outline | Course Timetable | COMP2041 Handbook | COMP9044 Handbook
Platforms: Lectures | Tutorials and Laboratories | Course Forum
Labs/Tests/Assignments: Autotests/Submissions/Marks | Give Web Portal | View Online Sturec
Assignment Specifications: Assignment 1 | Assignment 2

Course Content Week-by-Week

Tutorial
Laboratory
Tuesday February 16 2021 Lecture Topics
Thursday February 18 2021 Lecture Topics
Tutorial
Laboratory
Tuesday February 23 2021 Lecture Topics
Thursday February 25 2021 Lecture Topics
Tutorial
Laboratory
Weekly Test
Tuesday March 02 2021 Lecture Topics
Thursday March 04 2021 Lecture Topics
Tutorial
Laboratory
Weekly Test
Tuesday March 09 2021 Lecture Topics
Thursday March 11 2021 Lecture Topics
Tutorial
Laboratory
Weekly Test
Tuesday March 16 2021 Lecture Topics
Thursday March 18 2021 Lecture Topics
Weekly Test
Tutorial
Laboratory
Weekly Test
Tuesday March 30 2021 Lecture Topics
Thursday April 01 2021 Lecture Topics
Tutorial
Laboratory
Weekly Test
Tuesday April 06 2021 Lecture Topics
Thursday April 08 2021 Lecture Topics
Tutorial
Laboratory
Weekly Test
Tuesday April 13 2021 Lecture Topics
Thursday April 15 2021 Lecture Topics
Tutorial
Laboratory
Weekly Test
Tuesday April 20 2021 Lecture Topics
Thursday April 22 2021 Lecture Topics

Course Content Topic-by-Topic

Course Intro
Filters
regex101: online regex tester RegExr: online regex tester

#include <stdio.h>
#include <stdlib.h>

// write bytes of stream to stdout
void process_stream(FILE *stream) {
    int byte;
    while ((byte = fgetc(stream)) != EOF) {
        if (fputc(byte, stdout) == EOF) {
            perror("cat:");
            exit(1);
        }
    }
}

// process files given as arguments
// if no arguments process stdin
int main(int argc, char *argv[]) {

    if (argc == 1) {
        process_stream(stdin);
    } else {
        for (int i = 1; i < argc; i++) {
            FILE *in = fopen(argv[i], "r");
            if (in == NULL) {
                fprintf(stderr, "%s: %s: ", argv[0], argv[i]);
                perror("");
                return 1;
            }
            process_stream(in);
            fclose(in);
        }
    }

    return 0;
}

Download cat.c



import sys


def process_stream(stream):
    """
    copy bytes of f to stdout
    """
    for line in stream:
        print(line, end='')


def main():
    """
    process files given as arguments
    if no arguments process stdin
    """
    if not sys.argv[1:]:
        process_stream(sys.stdin)
    else:
        for pathname in sys.argv[1:]:
            with open(pathname, 'r') as f:
                process_stream(f)


if __name__ == '__main__':
    main()

Download cat.py



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// print lines containing the specified substring
void process_stream(FILE *stream, char *name, char *substring) {
    char *line = NULL;
    size_t line_size = 0;
    int line_number = 1;
    
    while (getline(&line, &line_size, stream) > 0) {
        if (strstr(line, substring) != NULL) {
            printf("%s:%d:%s", name, line_number, line);
        }
        line_number++;
    }
    
    free(line);
}

// process files given as arguments
// if no arguments process stdin
int main(int argc, char *argv[]) {

    if (argc == 2) {
        process_stream(stdin, "<stdin>", argv[1]);
    } else {
        for (int i = 2; i < argc; i++) {
            FILE *in = fopen(argv[i], "r");
            if (in == NULL) {
                fprintf(stderr, "%s: %s: ", argv[0], argv[i]);
                perror("");
                return 1;
            }
            process_stream(in, argv[i], argv[1]);
            fclose(in);
        }
    }
    
    return 0;
}

Download fgrep.c



import sys


def process_stream(f, name, substring):
    """
    print lines containing substring
    """
    for (line_number, line) in enumerate(f, start=1):
        if substring in line:
            print(f'{name}:{line_number}:{line}', end='')


def main():
    """
    process files given as arguments, if no arguments process stdin
    """
    if len(sys.argv) == 2:
        process_stream(sys.stdin, "<stdin>", sys.argv[1])
    elif len(sys.argv) > 2:
        for pathname in sys.argv[2:]:
            with open(pathname, 'r') as f:
                process_stream(f, pathname, sys.argv[1])


if __name__ == '__main__':
    main()

Download fgrep.py


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

// count lines, words, chars in stream
// assumes Unix-like line separator '\n'
// breaks on other platforms, see https://en.wikipedia.org/wiki/Newline

void process_stream(FILE *in, char *name) {
    int n_lines = 0;
    int n_words = 0;
    int n_chars = 0;
    int in_word = 0;
    int c;

    while ((c = fgetc(in)) != EOF) {
        n_chars++;

        if (c == '\n') {
            n_lines++;
        }

        if (isspace(c)) {
            in_word = 0;
        } else if (!in_word) {
            in_word = 1;
            n_words++;
        }
    }

    printf("%d %d %d %s\n", n_lines, n_words, n_chars, name);
}

// process files given as arguments
// if no arguments process stdin
int main(int argc, char *argv[]) {
    if (argc == 1) {
        process_stream(stdin, "stdin");
    } else {
        for (int i = 1; i < argc; i++) {
            FILE *in = fopen(argv[i], "r");
            if (in == NULL) {
                fprintf(stderr, "%s: %s: ", argv[0], argv[i]);
                perror("");
                return 1;
            }
            process_stream(in, argv[i]);
            fclose(in);
        }
    }
    return 0;
}

Download wc.c



import sys
import re


def process_stream(stream):
    """
    count lines, words, chars in stream
    """
    lines = 0
    words = 0
    characters = 0
    for line in stream:
        if line[-1] in "\r\n":
            lines += 1
        words += len(re.findall(r'\S+', line))
        characters += len(line)
    print(f"{lines:>6} {words:>6} {characters:>6}", end='')


def main():
    """
    process files given as arguments, if no arguments process stdin
    """
    if not sys.argv[1:]:
        process_stream(sys.stdin)
    else:
        for pathname in sys.argv[1:]:
            with open(pathname, 'r') as f:
                process_stream(f)
                print(f" {pathname}")


if __name__ == '__main__':
    main()

Download wc.py


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

// cope stream to stdout except for repeated lines
void process_stream(FILE *stream) {
    char *line = NULL;
    size_t line_size = 0;
    char *last_line = NULL;
    size_t last_line_size = 0;

    while (getline(&line, &line_size, stream) > 0) {
        if (last_line == NULL || strcmp(line, last_line) != 0) {
            fputs(line, stdout);
        }

        // grow last_line if line has grown
        if (last_line_size != line_size) {
            last_line = realloc(last_line, line_size);
            assert(last_line != NULL);
            last_line_size = line_size;
        }

        strncpy(last_line, line, line_size);
    }

    free(line);
    free(last_line);
}

// process files given as arguments
// if no arguments process stdin
int main(int argc, char *argv[]) {
    if (argc == 1) {
        process_stream(stdin);
    } else {
        FILE *in = fopen(argv[1], "r");
        if (in == NULL) {
            fprintf(stderr, "%s: %s: ", argv[0], argv[1]);
            perror("");
            return 1;
        }
        process_stream(in);
        fclose(in);
    }

    return 0;
}

Download uniq.c



import sys


def process_stream(stream):
    """
    copy stream to stdout except for repeated lines
    """
    last_line = None
    for index, line in enumerate(stream):
        if index == 0 or line != last_line:
            print(line, end='')
        last_line = line


def main():
    """
    process files given as arguments, if no arguments process stdin
    """
    if not sys.argv[1:]:
        process_stream(sys.stdin)
    else:
        for pathname in sys.argv[1:]:
            with open(pathname, 'r') as f:
                process_stream(f)


if __name__ == '__main__':
    main()

Download uniq.py



import sys


def process_stream(f):
    """
    print lines of stream in sorted order
    """
    print("".join(sorted(f)), end="")


def main():
    """
    process files given as arguments, if no arguments process stdin
    """
    if len(sys.argv) == 1:
        process_stream(sys.stdin)
    else:
        with open(sys.argv[1], 'r') as f:
            process_stream(f)


if __name__ == '__main__':
    main()

Download sort.py



import subprocess
import sys

# the real xargs runs the command multiple times if input is large
# the real xargs terats quotes specially


def main():
    input_words = [w for line in sys.stdin for w in line.split()]
    command = sys.argv[1:]
    subprocess.run(command + input_words)


if __name__ == '__main__':
    main()

Download xargs.py

This file contains examples of the use of the most common Unix filter programs (grep, wc, head, etc.) It also contains solutions to the exercises discussed in lectures.
  1. Consider a a file course_codes containing UNSW course codes and names.
    ls -l course_codes
    -rw-r--r-- 1 cs2041 cs2041 603446 Feb 19  2021 course_codes
    
    wc course_codes
     18181  79223 603446 course_codes
    
    head course_codes
    ACCT1501	Accounting & Financial Mgt 1A
    ACCT1511	Accounting & Financial Mgt 1B
    ACCT2101	Industry Placement 1
    ACCT2507	Intro  to Accounting Research
    ACCT2522	Management Accounting 1
    ACCT2532	Management Accounting (Hons)
    ACCT2542	Corporate Financial Reporting
    ACCT2552	Corporate Financial Rep (Hons)
    ACCT3202	Industry Placement 2
    ACCT3303	Industry Placement 3
    
    It looks like the code is separated from the title by a number of spaces. We can check this via cat -A:
    head -5 course_codes | cat -A
    ACCT1501^IAccounting & Financial Mgt 1A$
    ACCT1511^IAccounting & Financial Mgt 1B$
    ACCT2101^IIndustry Placement 1$
    ACCT2507^IIntro  to Accounting Research$
    ACCT2522^IManagement Accounting 1$
    
    This shows us that our initial guess was wrong, and there's actually a tab character between the course code and title (shown as ^I by cat -A). Also, the location of the end-of-line marker ($) indicates that there are no trailing spaces or tabs.

    If we need to know what COMP courses there are:

    grep -E -c COMP course_codes
    191
    
    grep -E COMP course_codes
    COMP0011	Fundamentals of Computing
    COMP1000	Web, Spreadsheets & Databases
    COMP1001	Introduction to Computing
    COMP1011	Computing 1A
    COMP1021	Computing 1B
    COMP1081	Harnessing the Power of IT
    COMP1091	Solving Problems with Software
    COMP1400	Programming for Designers
    COMP1711	Higher Computing 1A
    COMP1721	Higher Computing 1B
    COMP1911	Computing 1A
    COMP1917	Computing 1
    COMP1921	Computing 1B
    COMP1927	Computing 2
    COMP2011	Data Organisation
    COMP2021	Digital System Structures
    COMP2041	Software Construction
    COMP2091	Computing 2
    COMP2110	Software System Specification
    COMP2111	System Modelling and Design
    COMP2121	Microprocessors & Interfacing
    COMP2411	Logic and Logic Programming
    COMP2711	Higher Data Organisation
    COMP2811	Computing B
    COMP2911	Eng. Design in Computing
    COMP2920	Professional Issues and Ethics
    COMP3111	Software Engineering
    COMP3120	Introduction to Algorithms
    COMP3121	Algorithms & Programming Tech
    COMP3131	Programming Languages & Compil
    COMP3141	Software Sys Des&Implementat'n
    COMP3151	Foundations of Concurrency
    COMP3152	Comparative Concurrency Semant
    COMP3153	Algorithmic Verification
    COMP3161	Concepts of Programming Lang.
    COMP3171	Object-Oriented Programming
    COMP3211	Computer Architecture
    COMP3221	Microprocessors & Embedded Sys
    COMP3222	Digital Circuits and Systems
    COMP3231	Operating Systems
    COMP3241	Real Time Systems
    COMP3311	Database Systems
    COMP3331	Computer Networks&Applications
    COMP3411	Artificial Intelligence
    COMP3421	Computer Graphics
    COMP3431	Robotic Software Architecture
    COMP3441	Security Engineering
    COMP3511	Human Computer Interaction
    COMP3601	Design Project A
    COMP3710	Software Project Management
    COMP3711	Software Project Management
    COMP3720	Total Quality Management
    COMP3821	Ext Algorithms&Prog Techniques
    COMP3881	Ext Digital Circuits & Systems
    COMP3891	Ext Operating Systems
    COMP3901	Special Project A
    COMP3902	Special Project B
    COMP3931	Ext Computer Networks & App
    COMP4001	Object-Oriented Software Dev
    COMP4002	Logic Synthesis & Verification
    COMP4003	Industrial Software Developmen
    COMP4011	Web Applications Engineering
    COMP4012	Occasional Elec S2 - Comp.Eng.
    COMP4121	Advanced & Parallel Algorithms
    COMP4128	Programming Challenges
    COMP4131	Programming Language Semantics
    COMP4132	Adv. Functional Programming
    COMP4133	Advanced Compiler Construction
    COMP4141	Theory of Computation
    COMP4151	Algorithmic Verification
    COMP4161	Advanced Verification
    COMP4181	Language-based Software Safety
    COMP4211	Adv Architectures & Algorithms
    COMP4314	Next Generation Database Systs
    COMP4317	XML and Databases
    COMP4335	Wireless Mesh&Sensor Networks
    COMP4336	Mobile Data Networking
    COMP4337	Securing Wireless Networks
    COMP4411	Experimental Robotics
    COMP4412	Introduction to Modal Logic
    COMP4415	First-order Logic
    COMP4416	Intelligent Agents
    COMP4418	Knowledge Representation
    COMP4431	Game Design Workshop
    COMP4432	Game Design Studio
    COMP4442	Advanced Computer Security
    COMP4511	User Interface Design & Constr
    COMP4601	Design Project B
    COMP4903	Industrial Training
    COMP4904	Industrial Training 1
    COMP4905	Industrial Training 2
    COMP4906	Industrial Training 3
    COMP4910	Thesis Part A
    COMP4911	Thesis Part B
    COMP4913	Computer Science 4 Honours P/T
    COMP4914	Computer Science 4 Honours F/T
    COMP4920	Management and Ethics
    COMP4930	Thesis Part A
    COMP4931	Thesis Part B
    COMP4941	Thesis Part B
    COMP6714	Info Retrieval and Web Search
    COMP6721	(In-)Formal Methods
    COMP6731	Combinatorial Data Processing
    COMP6733	Internet of Things
    COMP6741	Parameterized & Exact Comp.
    COMP6752	Modelling Concurrent Systems
    COMP6771	Advanced C++ Programming
    COMP9000	Special Program
    COMP9001	E-Commerce Technologies
    COMP9008	Software Engineering
    COMP9009	Adv Topics in Software Eng
    COMP9015	Issues in Computing
    COMP9018	Advanced Graphics
    COMP9020	Foundations of Comp. Science
    COMP9021	Principles of Programming
    COMP9022	Digital Systems Structures
    COMP9024	Data Structures & Algorithms
    COMP9031	Internet Programming
    COMP9032	Microprocessors & Interfacing
    COMP9041	Software Construction
    COMP9081	Harnessing the Power of IT
    COMP9101	Design &Analysis of Algorithms
    COMP9102	Programming Lang & Compilers
    COMP9103	Algorithms & Comp. Complexity
    COMP9104	Quantum ICT
    COMP9116	S'ware Dev: B-Meth & B-Toolkit
    COMP9117	Software Architecture
    COMP9151	Foundations of Concurrency
    COMP9152	Comparative Concurrency Semant
    COMP9153	Algorithmic Verification
    COMP9161	Concepts of Programming Lang.
    COMP9171	Object-Oriented Programming
    COMP9181	Language-based Software Safety
    COMP9201	Operating Systems
    COMP9211	Computer Architecture
    COMP9221	Microprocessors & Embedded Sys
    COMP9222	Digital Circuits and Systems
    COMP9231	Integrated Digital Systems
    COMP9242	Advanced Operating Systems
    COMP9243	Distributed Systems
    COMP9244	Software View of Proc Architec
    COMP9245	Real-Time Systems
    COMP9282	Ext Micros & Interfacing
    COMP9283	Ext Operating Systems
    COMP9311	Database Systems
    COMP9313	Big Data Management
    COMP9314	Next Generation Database Systs
    COMP9315	Database Systems Implementat'n
    COMP9316	eCommerce Implementation
    COMP9317	XML and Databases
    COMP9318	Data Warehousing & Data Mining
    COMP9319	Web Data Compression & Search
    COMP9321	Web Applications Engineering
    COMP9322	Service-Oriented Architectures
    COMP9323	e-Enterprise Project
    COMP9331	Computer Networks&Applications
    COMP9332	Network Routing and Switching
    COMP9333	Advanced Computer Networks
    COMP9334	Systems Capacity Planning
    COMP9335	Wireless Mesh&Sensor Networks
    COMP9336	Mobile Data Networking
    COMP9337	Securing Wireless Networks
    COMP9414	Artificial Intelligence
    COMP9415	Computer Graphics
    COMP9416	Knowledge Based Systems
    COMP9417	Machine Learning & Data Mining
    COMP9418	Advanced Machine Learning
    COMP9431	Robotic Software Architecture
    COMP9441	Security Engineering
    COMP9444	Neural Networks
    COMP9447	Security Engineering Workshop
    COMP9511	Human Computer Interaction
    COMP9514	Advanced Decision Theory
    COMP9515	Pattern Classification
    COMP9517	Computer Vision
    COMP9518	Pattern Recognition
    COMP9519	Multimedia Systems
    COMP9520	Ext Foundations of Computer Sc
    COMP9596	Research Project
    COMP9790	Principles of GNSS Positioning
    COMP9791	Modern Navigation &Positioning
    COMP9801	Ext Design&Analysis of Algo
    COMP9814	Ext Artificial Intelligence
    COMP9833	Ext Computer Networks & Appl
    COMP9844	Ext Neural Networks
    COMP9901	P/T Res. Thesis Comp Sci & Eng
    COMP9902	Res. Thesis Comp Sci & Eng F/T
    COMP9910	Mgt&Com Skills-CompSci&Eng Res
    COMP9912	Project (24 UOC)
    COMP9930	Readings in Comp Sci and Eng
    COMP9945	Research Project
    
    Either of the two commands below tell us which courses have "comp" in their name or code (in upper or lower case).
    tr A-Z a-z <course_codes | grep -E comp
    aciv2518	eng computational methods 1
    acsc1600	computer science 1
    acsc1800	computer science 1e
    acsc2015	interactive computer graphics
    acsc2020	computer science core b2
    acsc2021	computer systems architectrue 2
    acsc2107	computer languages b
    acsc2601	computer science 2a
    acsc2602	computer science 2b
    acsc2802	computer science 2ee
    acsc3003	computer project
    acsc3029	computing project 3
    acsc3030	cryptography & computer securi
    acsc3601	computer science 3a
    acsc3603	computer science 3c
    acsc4191	computer science 4 (hons) f/t
    acsc7304	computer graphics
    acsc7306	computer speech processing
    acsc7336	computer security
    acsc8248	computer graphics (12 cpt)
    acsc9000	computer science research f/t
    acsc9001	computer science research p/t
    aele2007	computer design
    aele2508	microcomputer interfacing
    aele3031	microcomputer interfacing
    aele4511	computer control theory
    amat3107	complex variables
    amat3401	complex analysis 3e
    amat3503	complex variables e
    amec3512	pumps, turbines & compressors
    ance8001	computational mathematics
    ance8002	supercomputing techniques
    ance9105	comp techniques fluid dynamics
    aphy3028	computational physics
    arch1391	digital computation studio
    arch5202	computer applications 2
    arch5203	computer applications 3
    arch5205	theory of architectural computin
    arch5220	computer graphics programming 1
    arch5221	computer graphics programming 2
    arch5223	computer applications 2
    arch5940	theory of architectural computin
    arch5942	arctitectural computing seminar
    arch5943	theory of architectural computin
    arch6201	architectural computing 1
    arch6205	architectural computing 2
    arch6214	architectural computing 2
    arch7204	design computing theory
    arch7205	computer graphics programming
    arts2301	computers, brains & minds
    atax0002	computer information systems
    atax0053	acct for complex struct & inst
    atax0324	gst: complex issues & planning
    atax0341	comparative tax systems
    atax0424	gst: complex issues & planning
    atax0441	comparative tax systems
    atax0524	gst: complex issues & planning
    atax0641	comparative tax systems
    aust2003	aborig. studies: a global compar
    aven1500	computing for aviation
    beil0003	be annual design competition
    beil0004	design competitions and bids
    benv1141	computers and information tech
    benv1242	computer-aided design
    benv2405	computer graphics programming
    binf3020	computational bioinformatics
    binf9020	computational bioinformatics
    biom5912	comp thesis b&c
    biom5920	thesis part a (comp)
    biom5921	thesis part b (comp)
    biom9332	biocompatibility
    biom9501	computing for biomedical eng
    biom9601	biomed applic.of microcomp 1
    biom9602	biomed applic.of microcomp 2
    bios3021	comparative animal physiology
    bldg2281	introduction to computing
    bldg3282	computer apps in building
    bldg3482	computer aplications in constr
    ceic5310	computing studies in the process
    ceic8310	computing studies proc ind
    ceic8335	adv computer methods
    chem3031	inorg chem:trans metals & comp
    chem3640	computers in chemistry
    civl1015	computing
    civl1106	computing & graphics
    civl3015	engineering computations
    civl3106	engineering computations
    cmed9517	adv biostatistic & stat comp
    code1110	computational design theory 1
    code1210	computational design theory 2
    code2110	computational design theory 3
    code2120	computational sustainability
    code2121	advanced computational design
    cofa2682	multi-media computing unit 3
    cofa3681	multi-media computing elective 1
    cofa5116	design & computers
    cofa5130	typography & composition
    cofa5216	design & computers 1
    cofa5240	design & computers 2 cad
    cofa5241	design & computers 2 graphics
    cofa5338	design & computers 3 - cad
    cofa5339	design & computers 3 - graphic
    cofa8670	intro to multi-media computing
    comd2040	of tigers & pussycats: a compa
    comp0011	fundamentals of computing
    comp1000	web, spreadsheets & databases
    comp1001	introduction to computing
    comp1011	computing 1a
    comp1021	computing 1b
    comp1081	harnessing the power of it
    comp1091	solving problems with software
    comp1400	programming for designers
    comp1711	higher computing 1a
    comp1721	higher computing 1b
    comp1911	computing 1a
    comp1917	computing 1
    comp1921	computing 1b
    comp1927	computing 2
    comp2011	data organisation
    comp2021	digital system structures
    comp2041	software construction
    comp2091	computing 2
    comp2110	software system specification
    comp2111	system modelling and design
    comp2121	microprocessors & interfacing
    comp2411	logic and logic programming
    comp2711	higher data organisation
    comp2811	computing b
    comp2911	eng. design in computing
    comp2920	professional issues and ethics
    comp3111	software engineering
    comp3120	introduction to algorithms
    comp3121	algorithms & programming tech
    comp3131	programming languages & compil
    comp3141	software sys des&implementat'n
    comp3151	foundations of concurrency
    comp3152	comparative concurrency semant
    comp3153	algorithmic verification
    comp3161	concepts of programming lang.
    comp3171	object-oriented programming
    comp3211	computer architecture
    comp3221	microprocessors & embedded sys
    comp3222	digital circuits and systems
    comp3231	operating systems
    comp3241	real time systems
    comp3311	database systems
    comp3331	computer networks&applications
    comp3411	artificial intelligence
    comp3421	computer graphics
    comp3431	robotic software architecture
    comp3441	security engineering
    comp3511	human computer interaction
    comp3601	design project a
    comp3710	software project management
    comp3711	software project management
    comp3720	total quality management
    comp3821	ext algorithms&prog techniques
    comp3881	ext digital circuits & systems
    comp3891	ext operating systems
    comp3901	special project a
    comp3902	special project b
    comp3931	ext computer networks & app
    comp4001	object-oriented software dev
    comp4002	logic synthesis & verification
    comp4003	industrial software developmen
    comp4011	web applications engineering
    comp4012	occasional elec s2 - comp.eng.
    comp4121	advanced & parallel algorithms
    comp4128	programming challenges
    comp4131	programming language semantics
    comp4132	adv. functional programming
    comp4133	advanced compiler construction
    comp4141	theory of computation
    comp4151	algorithmic verification
    comp4161	advanced verification
    comp4181	language-based software safety
    comp4211	adv architectures & algorithms
    comp4314	next generation database systs
    comp4317	xml and databases
    comp4335	wireless mesh&sensor networks
    comp4336	mobile data networking
    comp4337	securing wireless networks
    comp4411	experimental robotics
    comp4412	introduction to modal logic
    comp4415	first-order logic
    comp4416	intelligent agents
    comp4418	knowledge representation
    comp4431	game design workshop
    comp4432	game design studio
    comp4442	advanced computer security
    comp4511	user interface design & constr
    comp4601	design project b
    comp4903	industrial training
    comp4904	industrial training 1
    comp4905	industrial training 2
    comp4906	industrial training 3
    comp4910	thesis part a
    comp4911	thesis part b
    comp4913	computer science 4 honours p/t
    comp4914	computer science 4 honours f/t
    comp4920	management and ethics
    comp4930	thesis part a
    comp4931	thesis part b
    comp4941	thesis part b
    comp6714	info retrieval and web search
    comp6721	(in-)formal methods
    comp6731	combinatorial data processing
    comp6733	internet of things
    comp6741	parameterized & exact comp.
    comp6752	modelling concurrent systems
    comp6771	advanced c++ programming
    comp9000	special program
    comp9001	e-commerce technologies
    comp9008	software engineering
    comp9009	adv topics in software eng
    comp9015	issues in computing
    comp9018	advanced graphics
    comp9020	foundations of comp. science
    comp9021	principles of programming
    comp9022	digital systems structures
    comp9024	data structures & algorithms
    comp9031	internet programming
    comp9032	microprocessors & interfacing
    comp9041	software construction
    comp9081	harnessing the power of it
    comp9101	design &analysis of algorithms
    comp9102	programming lang & compilers
    comp9103	algorithms & comp. complexity
    comp9104	quantum ict
    comp9116	s'ware dev: b-meth & b-toolkit
    comp9117	software architecture
    comp9151	foundations of concurrency
    comp9152	comparative concurrency semant
    comp9153	algorithmic verification
    comp9161	concepts of programming lang.
    comp9171	object-oriented programming
    comp9181	language-based software safety
    comp9201	operating systems
    comp9211	computer architecture
    comp9221	microprocessors & embedded sys
    comp9222	digital circuits and systems
    comp9231	integrated digital systems
    comp9242	advanced operating systems
    comp9243	distributed systems
    comp9244	software view of proc architec
    comp9245	real-time systems
    comp9282	ext micros & interfacing
    comp9283	ext operating systems
    comp9311	database systems
    comp9313	big data management
    comp9314	next generation database systs
    comp9315	database systems implementat'n
    comp9316	ecommerce implementation
    comp9317	xml and databases
    comp9318	data warehousing & data mining
    comp9319	web data compression & search
    comp9321	web applications engineering
    comp9322	service-oriented architectures
    comp9323	e-enterprise project
    comp9331	computer networks&applications
    comp9332	network routing and switching
    comp9333	advanced computer networks
    comp9334	systems capacity planning
    comp9335	wireless mesh&sensor networks
    comp9336	mobile data networking
    comp9337	securing wireless networks
    comp9414	artificial intelligence
    comp9415	computer graphics
    comp9416	knowledge based systems
    comp9417	machine learning & data mining
    comp9418	advanced machine learning
    comp9431	robotic software architecture
    comp9441	security engineering
    comp9444	neural networks
    comp9447	security engineering workshop
    comp9511	human computer interaction
    comp9514	advanced decision theory
    comp9515	pattern classification
    comp9517	computer vision
    comp9518	pattern recognition
    comp9519	multimedia systems
    comp9520	ext foundations of computer sc
    comp9596	research project
    comp9790	principles of gnss positioning
    comp9791	modern navigation &positioning
    comp9801	ext design&analysis of algo
    comp9814	ext artificial intelligence
    comp9833	ext computer networks & appl
    comp9844	ext neural networks
    comp9901	p/t res. thesis comp sci & eng
    comp9902	res. thesis comp sci & eng f/t
    comp9910	mgt&com skills-compsci&eng res
    comp9912	project (24 uoc)
    comp9930	readings in comp sci and eng
    comp9945	research project
    crim3010	comparative criminal justice
    cven1015	computing
    cven1025	computing
    cven2002	engineering computations
    cven2025	engineering computations 1
    cven2702	engineering computations
    cven3025	engineering computations 2
    cven4307	steel & composite structures
    cven8827	composite steel-concrete struc
    cven9820	computational struct mechanics
    cven9822	steel & composite structures
    cven9827	composite steel-concrete struc
    danc2000	dance analysis & composition 1
    danc2005	dance analysis & composition 2
    danc2015	dance analysis & composition 3
    econ3213	comparative forecasting techs
    econ5122	compet. in the know. econ.
    econ5255	computational stats & econ mod
    edst1492	computer skills for teachers
    edst4092	computer skills for teachers
    edst4157	computing studies method 1
    edst4158	computing studies method 2
    elec4343	source coding & compression
    elec4432	computer control & instrumenta
    elec4632	computer control systems
    elec9401	computer control systems 1
    elec9402	computer control systems 2
    elec9403	real time computing & control
    elec9733	real computing and control
    engg1811	computing for engineers
    euro2302	the messiah complex
    fins5553	insur. comp. oper. & manage.
    fndn0301	computing studies
    fndn0302	computing studies and research
    fndn0311	computing studies - t
    food4220	computer applications
    food4320	computer applications
    food4537	computing in food science
    food9101	complex fluid micro & rheology
    gbat9131	leadership in a complex enviro
    gend1212	analysing a picture:comp.&des.
    gend4201	design and computing
    gene8001	computer game design
    genm0515	computers for professionals
    genp0515	computers for professionals
    gens2001	the computer
    gens5525	the comp: its impact, sign'fcnce
    gent0407	tv soaps: a comparative study
    gent0603	the computer: impact, significan
    gent0802	the complexity of everyday life
    gent1003	computers into the 21st c
    geog3161	computer mapping & data displa
    geog3861	computer mapping
    geog9014	computer mapping &data display
    geog9210	computer mapping & data displa
    geol0300	computing & stats for geol
    geol2041	geological computing
    gmat1111	introduction to computing
    gmat1150	survey methods& computations
    gmat1300	comp appl in geomatics
    gmat2111	principles of computer processin
    gmat2112	principles of computer processin
    gmat2122	computer graphics 1
    gmat2131	survey computations
    gmat2350	comp for spatial info sciences
    gmat2500	surveying computations a
    gmat2550	surveying computations b
    gmat3111	survey computations
    gmat3122	computer graphics 1
    gmat3231	geodetic computations
    gmat4111	data analysis & computing 1
    gmat4112	data analysis & computing 1
    gmat5111	data analysis & computing 2
    gmat5112	data analysis & computing 2
    gmat5122	computer graphics 2
    heal9471	comparative h'lth care systems
    heal9501	comp tech for health serv mngt
    hist2487	the messiah complex
    hpsc2610	computers, brains & minds
    hpst2004	computers, brains & minds
    hpst2109	computers, brains & minds
    ides2121	introduction to computing
    ides3101	design studio 5: complexity
    ides3231	adv computer aided product des
    ides5153	computer graphic applications
    ides5154	computer aided design
    iest5009	competencies in sustainability
    iest5010	competencies in sustainability
    ilas0232	computer prog'mng for info. appl
    ilas0233	computing applications in the in
    infs3607	distributed computer systems
    irob5732	spec topic- internat & comp ir
    irob5734	adv seminar-internat & comp ir
    jurd7348	harry gibbs moot comp 6uoc
    jurd7419	competition law and policy
    jurd7473	asian competition law
    jurd7474	competition law and ip
    jurd7489	complex civil litigation
    jurd7522	competition law
    jurd7559	int'l&comparative law w'shop
    jurd7610	mediation competition
    jurd7616	international & comparative ip
    jurd7648	transitional justice intl comp
    jurd7989	comparative anti-terrorism law
    jwst2104	the messiah complex
    land1131	introduction to computer applica
    laws1032	computer applications to law
    laws2065	comparative law
    laws2085	comparative law
    laws2110	comparative constitutional law
    laws2148	harry gibbs moot comp 8uoc
    laws2410	mediation competition
    laws2589	complex civil litigation
    laws3009	comparative criminal justice:
    laws3022	competition law
    laws3035	developing comp apps to law
    laws3051	telecomm. competition & cons.
    laws3148	harry gibbs moot comp
    laws3159	int'l&comparative law w'shop
    laws3348	transitional justice intl comp
    laws3510	mediation competition
    laws3589	complex civil litigation
    laws4016	international & comparative ip
    laws4019	competition law
    laws4089	comparative anti-terrorism law
    laws4120	themes in asian & compar. law
    laws4133	issues in asian & comp law
    laws4291	comparative constitutional law
    laws4620	computer applications to law
    laws4765	complex commercial litigation
    laws5234	competition law and regulation
    laws7003	global issues in comp policy
    laws8016	international & comparative ip
    laws8073	asian competition law
    laws8074	competition law and ip
    laws8118	legal systems in comp persp
    laws8143	comparative patent law
    laws8144	comparative trade mark law
    laws8219	competition law and policy
    laws8289	comparative anti-terrorism law
    laws8348	transitional justice intl comp
    laws8765	complex commercial litigation
    laws9973	comparative law
    laws9984	int. & comp. indigenous law
    legt5531	comp. bus. & legal strategies
    legt5602	tax admin. & compliance
    libs0233	computer applications in the inf
    manf3500	computers in manufacturing 1
    manf4500	computers in manufacturing 2
    manf4601	comp aided production mgmt a
    manf4602	comp aided production mgmt b
    manf8560	computer integrated manufact.
    manf9500	computer-aided progrmg for numcl
    manf9543	comp aided design/manufacture
    manf9560	computer integrated manufact.
    mark3022	computer applications in marketi
    math1061	introductory applied computing
    math2301	mathematical computing
    math2430	symbolic computing
    math2520	complex analysis
    math2521	complex analysis
    math2620	higher complex analysis
    math2621	higher complex analysis
    math2810	statistical computing
    math2910	higher statistical computing
    math3101	computational mathematics
    math3301	advanced math computing
    math3311	math computing for finance
    math3400	logic & computability
    math3421	logic and computability
    math3430	symbolic computing
    math3680	higher complex analysis
    math3790	higher computat. combinatorics
    math3800	statistical computation 1
    math3810	statistical computation 2
    math3821	stat modelling & computing
    math3871	bayesian inference and comp
    math4003	maths and comp sci honours f/t
    math4004	maths and comp sci honours p/t
    math5009	comp'l coursework thesis ft
    math5010	comp'l coursework thesis pt
    math5305	computational mathematics
    math5315	high perf numerical computing
    math5335	comput'l methods for finance
    math5400	logic & computability
    math5505	computational combinatorics
    math5685	complex analysis
    math5856	intro to stats and stat comput
    math5960	bayesian inference & comput'n
    math9315	topics in mathematical computing
    mats1021	computing in materials science
    mats1264	fibre reinforced plastic composi
    mats3064	composite materials
    mats4005	composites and functional mats
    mats5342	comp modelling & design
    mats6110	computational materials
    mbax9131	leadership in a complex enviro
    mech1500	computing 1m
    mech3500	computing 2m
    mech3510	computing applications in mech.
    mech3530	computing applcts in mechanical
    mech3540	computational engineering
    mech4130	computer-aided engineering desig
    mech4150	design & maintenance of componen
    mech4500	computing 3m
    mech4620	computational fluid dynamics
    mech8620	computational fluid dynamics
    mech9150	design & maintenance of componen
    mech9420	composite materials and mechan
    mech9620	computational fluid dynamics
    meft5103	computer media
    mgmt2106	comparative management systems
    mgmt5050	teams, ethics & comp adv
    mgmt5802	comp. adv. through people
    mine0710	computing 1
    mine1720	microcomputers (mining)
    mine1730	computer applications in mining
    mine4082	computational methods
    mine4810	comp methods in geomechanics
    mtrn2500	comp for mtrn
    mtrn3500	comp appl in mechatonic sys
    mtrn3530	computing applcts in mech.sys.
    pfst2000	dance analysis & composition 1
    pfst2005	dance analysis & composition 2
    pfst2011	performance composition
    phar9121	postmarketing compliance meds
    phcm9471	comparative h'lth care systems
    phil5206	ai & computer science
    phil5207	ai & computer science 2a
    phys1601	comp. applic'ns in exp. sci. 1
    phys2001	mechanics & computational phys
    phys2020	computational physics
    phys2120	mechanics and computational
    phys2601	computer applications 2
    phys3601	computer applications in instrum
    phys3610	computational physics
    phys3620	computer based signal processing
    plan1061	computer literacy
    pols2016	concepts in comparative pol cult
    pols3953	comparative politics: russia
    psyc3191	computer science & psychology
    ptrl1013	computing-petroleum engineers
    ptrl4013	well completion & stimulation
    ptrl5016	well completions & stimulation
    ptrl6016	well completions & stimulation
    regs0044	comp law in global context
    regs0115	compliance: financial service
    regs0218	compliance: financial services
    regs0428	computer applications in linguis
    regs0453	multiple regress. & stat comp
    regs0474	comparative international tax
    regs0633	comparative corp & comm law
    regs0638	international comparative corp
    regs0718	energy co-compliance in bldgs
    regs3092	comp cntrl of machines & proc
    regs3265	intl and comparative ind. rel.
    regs3410	computer networks
    regs3873	introduction to computer graphic
    regs3909	trade marks & unfair comp
    regs3948	competition law
    regs4045	competition reg. of mergers
    regs5618	comp integrated manufacturing
    regs7726	composites & multiphase polyme
    regs7908	service managing for comp.adv.
    sart1608	digital composite 1
    sart1681	multimedia computing elective1
    sart1810	introduction to computing
    sart2608	digital composite 2
    sart2681	multimedia computing elective2
    sart2811	multimedia computing workshop
    sart2835	composition and design
    sart3608	digital composite 3
    sart3681	multimedia computing elective3
    sart3840	advanced multimedia computing
    sart9725	intro to multimedia computing
    sart9739	multimedia computing elective
    sart9741	composition and design
    sdes1106	design and computers 1
    sdes1110	design and computers 2
    sdes1111	integrated design computing 1
    sdes1211	integrated design computing 2
    sdes1601	colour,composition &typography
    sdes2107	design and computers 3
    sdes2115	design and computers 2b
    sdes3107	design and computers 4
    sdes3173	advanced computer graphics
    sdes4103	design and computers 4
    sdes6714	intro 3d computer aided design
    slsp2902	computers and comm.
    soca3314	the messiah complex
    soci3401	computer analysis of social data
    soci3408	computer analysis of social data
    soma1608	digital composite
    soma1681	intro multimedia computing
    soma1810	introduction to computing
    soma2402	tangible computing
    soma2608	digital composite 2
    soma2681	advanced multimedia computing
    soma2811	multimedia computing workshop
    soma3415	compositional project
    soma3608	digital composite 3
    surv1111	introduction to computing
    surv2111	principles of computer processin
    surv2122	computer graphics 1
    surv3111	survey computations
    surv3231	geodetic computations
    surv4111	data analysis & computing 1
    surv5111	data analysis & computing 2
    surv5122	computer graphics 2
    surv6121	computer graphics
    tabl1002	computer information systems
    tabl2053	acct for complex struct & inst
    tabl3044	comparative tax systems
    tabl5544	comparative tax systems
    tedg1101	computers in education
    tedg1106	computer-based resources: design
    tedg1107	managing with computers in schoo
    tedg1112	computers - gifted & talented st
    tedg1113	computer control technology in e
    teed1134	fundamentals of computing
    teed2119	computers & people
    tele4343	source coding and compression
    tele9302	computer networks
    text2501	computing applications
    zacm3011	component design
    zacm3433	compressible flow
    zacm4020	computational structures
    zacm4031	compressible flow
    zacm4913	eng app of comp fluid dynamics
    zbus2200	markets and competition
    zeit1101	computational problem solving
    zeit1110	computer games
    zeit2102	computer technology
    zeit2305	computer games
    zeit3113	computer languages & algorithm
    zeit3304	computing proj - info sys
    zeit3307	computer games
    zeit4003	computational fluid dynamics
    zeit7101	computational problem solving
    zeit8020	computer network operations
    zeit8028	computer forensics
    zeit9100	computer science research f/t
    zeit9101	computer science research p/t
    zgen2300	computers in society
    zgen2301	computer games
    zhss8431	comparative defence planning
    zint1001	eng comp methods 1
    zite1001	computer tools for engineers
    zite1101	intro to computer science
    zite2101	computer languages & algorithm
    zite2102	computer technology
    zite3101	computing proj - comp sci
    zite3105	human computer interaction
    zite3106	interactive computer graphics
    zite3113	computer languages & algorithm
    zite3211	microcomputer interfacing
    zite3304	computing proj - info sys
    zite4101	computer sci 4 (comb hons) f/t
    zite4102	computer sci 4 (comb hon) p/t
    zite4103	computer science 4 (hons) f/t
    zite4104	computer science 4 (hons) p/t
    zite8103	computer graphics
    zite8104	computer security
    zite8105	computer speech processing
    zite8145	softcomp
    zite9100	computer science research f/t
    zite9101	computer science research p/t
    zpem3302	complex variables
    
    grep -E -i comp course_codes
    ACIV2518	Eng Computational Methods 1
    ACSC1600	Computer Science 1
    ACSC1800	Computer Science 1E
    ACSC2015	Interactive Computer Graphics
    ACSC2020	Computer Science Core B2
    ACSC2021	Computer Systems Architectrue 2
    ACSC2107	Computer Languages B
    ACSC2601	Computer Science 2A
    ACSC2602	Computer Science 2B
    ACSC2802	Computer Science 2EE
    ACSC3003	Computer Project
    ACSC3029	Computing Project 3
    ACSC3030	Cryptography & Computer Securi
    ACSC3601	Computer Science 3A
    ACSC3603	Computer Science 3C
    ACSC4191	Computer Science 4 (Hons) F/T
    ACSC7304	Computer Graphics
    ACSC7306	Computer Speech Processing
    ACSC7336	Computer Security
    ACSC8248	Computer Graphics (12 Cpt)
    ACSC9000	Computer Science Research F/T
    ACSC9001	Computer Science Research P/T
    AELE2007	Computer Design
    AELE2508	Microcomputer Interfacing
    AELE3031	Microcomputer Interfacing
    AELE4511	Computer Control Theory
    AMAT3107	Complex Variables
    AMAT3401	Complex Analysis 3E
    AMAT3503	Complex Variables E
    AMEC3512	Pumps, Turbines & Compressors
    ANCE8001	Computational Mathematics
    ANCE8002	Supercomputing Techniques
    ANCE9105	Comp Techniques Fluid Dynamics
    APHY3028	Computational Physics
    ARCH1391	Digital Computation Studio
    ARCH5202	Computer Applications 2
    ARCH5203	Computer Applications 3
    ARCH5205	Theory of Architectural Computin
    ARCH5220	Computer Graphics Programming 1
    ARCH5221	Computer Graphics Programming 2
    ARCH5223	Computer Applications 2
    ARCH5940	Theory of Architectural Computin
    ARCH5942	Arctitectural Computing Seminar
    ARCH5943	Theory of Architectural Computin
    ARCH6201	Architectural Computing 1
    ARCH6205	Architectural Computing 2
    ARCH6214	Architectural Computing 2
    ARCH7204	Design Computing Theory
    ARCH7205	Computer Graphics Programming
    ARTS2301	Computers, Brains & Minds
    ATAX0002	Computer Information Systems
    ATAX0053	Acct for Complex Struct & Inst
    ATAX0324	GST: Complex Issues & Planning
    ATAX0341	Comparative Tax Systems
    ATAX0424	GST: Complex Issues & Planning
    ATAX0441	Comparative Tax Systems
    ATAX0524	GST: Complex Issues & Planning
    ATAX0641	Comparative Tax Systems
    AUST2003	Aborig. Studies: a Global Compar
    AVEN1500	Computing for Aviation
    BEIL0003	BE Annual Design Competition
    BEIL0004	Design Competitions and Bids
    BENV1141	Computers and Information Tech
    BENV1242	Computer-Aided Design
    BENV2405	Computer Graphics Programming
    BINF3020	Computational Bioinformatics
    BINF9020	Computational Bioinformatics
    BIOM5912	Comp Thesis B&C
    BIOM5920	Thesis Part A (Comp)
    BIOM5921	Thesis Part B (Comp)
    BIOM9332	Biocompatibility
    BIOM9501	Computing for Biomedical Eng
    BIOM9601	Biomed Applic.of Microcomp 1
    BIOM9602	Biomed Applic.of Microcomp 2
    BIOS3021	Comparative Animal Physiology
    BLDG2281	Introduction To Computing
    BLDG3282	Computer Apps in Building
    BLDG3482	Computer Aplications in Constr
    CEIC5310	Computing Studies in The Process
    CEIC8310	Computing Studies Proc Ind
    CEIC8335	Adv Computer Methods
    CHEM3031	Inorg Chem:Trans Metals & Comp
    CHEM3640	Computers in Chemistry
    CIVL1015	Computing
    CIVL1106	Computing & Graphics
    CIVL3015	Engineering Computations
    CIVL3106	Engineering Computations
    CMED9517	Adv Biostatistic & Stat Comp
    CODE1110	Computational Design Theory 1
    CODE1210	Computational Design Theory 2
    CODE2110	Computational Design Theory 3
    CODE2120	Computational Sustainability
    CODE2121	Advanced Computational Design
    COFA2682	Multi-media Computing Unit 3
    COFA3681	Multi-media Computing Elective 1
    COFA5116	Design & Computers
    COFA5130	Typography & Composition
    COFA5216	Design & Computers 1
    COFA5240	Design & Computers 2 Cad
    COFA5241	Design & Computers 2 Graphics
    COFA5338	Design & Computers 3 - Cad
    COFA5339	Design & Computers 3 - Graphic
    COFA8670	Intro To Multi-media Computing
    COMD2040	Of Tigers & Pussycats: a Compa
    COMP0011	Fundamentals of Computing
    COMP1000	Web, Spreadsheets & Databases
    COMP1001	Introduction to Computing
    COMP1011	Computing 1A
    COMP1021	Computing 1B
    COMP1081	Harnessing the Power of IT
    COMP1091	Solving Problems with Software
    COMP1400	Programming for Designers
    COMP1711	Higher Computing 1A
    COMP1721	Higher Computing 1B
    COMP1911	Computing 1A
    COMP1917	Computing 1
    COMP1921	Computing 1B
    COMP1927	Computing 2
    COMP2011	Data Organisation
    COMP2021	Digital System Structures
    COMP2041	Software Construction
    COMP2091	Computing 2
    COMP2110	Software System Specification
    COMP2111	System Modelling and Design
    COMP2121	Microprocessors & Interfacing
    COMP2411	Logic and Logic Programming
    COMP2711	Higher Data Organisation
    COMP2811	Computing B
    COMP2911	Eng. Design in Computing
    COMP2920	Professional Issues and Ethics
    COMP3111	Software Engineering
    COMP3120	Introduction to Algorithms
    COMP3121	Algorithms & Programming Tech
    COMP3131	Programming Languages & Compil
    COMP3141	Software Sys Des&Implementat'n
    COMP3151	Foundations of Concurrency
    COMP3152	Comparative Concurrency Semant
    COMP3153	Algorithmic Verification
    COMP3161	Concepts of Programming Lang.
    COMP3171	Object-Oriented Programming
    COMP3211	Computer Architecture
    COMP3221	Microprocessors & Embedded Sys
    COMP3222	Digital Circuits and Systems
    COMP3231	Operating Systems
    COMP3241	Real Time Systems
    COMP3311	Database Systems
    COMP3331	Computer Networks&Applications
    COMP3411	Artificial Intelligence
    COMP3421	Computer Graphics
    COMP3431	Robotic Software Architecture
    COMP3441	Security Engineering
    COMP3511	Human Computer Interaction
    COMP3601	Design Project A
    COMP3710	Software Project Management
    COMP3711	Software Project Management
    COMP3720	Total Quality Management
    COMP3821	Ext Algorithms&Prog Techniques
    COMP3881	Ext Digital Circuits & Systems
    COMP3891	Ext Operating Systems
    COMP3901	Special Project A
    COMP3902	Special Project B
    COMP3931	Ext Computer Networks & App
    COMP4001	Object-Oriented Software Dev
    COMP4002	Logic Synthesis & Verification
    COMP4003	Industrial Software Developmen
    COMP4011	Web Applications Engineering
    COMP4012	Occasional Elec S2 - Comp.Eng.
    COMP4121	Advanced & Parallel Algorithms
    COMP4128	Programming Challenges
    COMP4131	Programming Language Semantics
    COMP4132	Adv. Functional Programming
    COMP4133	Advanced Compiler Construction
    COMP4141	Theory of Computation
    COMP4151	Algorithmic Verification
    COMP4161	Advanced Verification
    COMP4181	Language-based Software Safety
    COMP4211	Adv Architectures & Algorithms
    COMP4314	Next Generation Database Systs
    COMP4317	XML and Databases
    COMP4335	Wireless Mesh&Sensor Networks
    COMP4336	Mobile Data Networking
    COMP4337	Securing Wireless Networks
    COMP4411	Experimental Robotics
    COMP4412	Introduction to Modal Logic
    COMP4415	First-order Logic
    COMP4416	Intelligent Agents
    COMP4418	Knowledge Representation
    COMP4431	Game Design Workshop
    COMP4432	Game Design Studio
    COMP4442	Advanced Computer Security
    COMP4511	User Interface Design & Constr
    COMP4601	Design Project B
    COMP4903	Industrial Training
    COMP4904	Industrial Training 1
    COMP4905	Industrial Training 2
    COMP4906	Industrial Training 3
    COMP4910	Thesis Part A
    COMP4911	Thesis Part B
    COMP4913	Computer Science 4 Honours P/T
    COMP4914	Computer Science 4 Honours F/T
    COMP4920	Management and Ethics
    COMP4930	Thesis Part A
    COMP4931	Thesis Part B
    COMP4941	Thesis Part B
    COMP6714	Info Retrieval and Web Search
    COMP6721	(In-)Formal Methods
    COMP6731	Combinatorial Data Processing
    COMP6733	Internet of Things
    COMP6741	Parameterized & Exact Comp.
    COMP6752	Modelling Concurrent Systems
    COMP6771	Advanced C++ Programming
    COMP9000	Special Program
    COMP9001	E-Commerce Technologies
    COMP9008	Software Engineering
    COMP9009	Adv Topics in Software Eng
    COMP9015	Issues in Computing
    COMP9018	Advanced Graphics
    COMP9020	Foundations of Comp. Science
    COMP9021	Principles of Programming
    COMP9022	Digital Systems Structures
    COMP9024	Data Structures & Algorithms
    COMP9031	Internet Programming
    COMP9032	Microprocessors & Interfacing
    COMP9041	Software Construction
    COMP9081	Harnessing the Power of IT
    COMP9101	Design &Analysis of Algorithms
    COMP9102	Programming Lang & Compilers
    COMP9103	Algorithms & Comp. Complexity
    COMP9104	Quantum ICT
    COMP9116	S'ware Dev: B-Meth & B-Toolkit
    COMP9117	Software Architecture
    COMP9151	Foundations of Concurrency
    COMP9152	Comparative Concurrency Semant
    COMP9153	Algorithmic Verification
    COMP9161	Concepts of Programming Lang.
    COMP9171	Object-Oriented Programming
    COMP9181	Language-based Software Safety
    COMP9201	Operating Systems
    COMP9211	Computer Architecture
    COMP9221	Microprocessors & Embedded Sys
    COMP9222	Digital Circuits and Systems
    COMP9231	Integrated Digital Systems
    COMP9242	Advanced Operating Systems
    COMP9243	Distributed Systems
    COMP9244	Software View of Proc Architec
    COMP9245	Real-Time Systems
    COMP9282	Ext Micros & Interfacing
    COMP9283	Ext Operating Systems
    COMP9311	Database Systems
    COMP9313	Big Data Management
    COMP9314	Next Generation Database Systs
    COMP9315	Database Systems Implementat'n
    COMP9316	eCommerce Implementation
    COMP9317	XML and Databases
    COMP9318	Data Warehousing & Data Mining
    COMP9319	Web Data Compression & Search
    COMP9321	Web Applications Engineering
    COMP9322	Service-Oriented Architectures
    COMP9323	e-Enterprise Project
    COMP9331	Computer Networks&Applications
    COMP9332	Network Routing and Switching
    COMP9333	Advanced Computer Networks
    COMP9334	Systems Capacity Planning
    COMP9335	Wireless Mesh&Sensor Networks
    COMP9336	Mobile Data Networking
    COMP9337	Securing Wireless Networks
    COMP9414	Artificial Intelligence
    COMP9415	Computer Graphics
    COMP9416	Knowledge Based Systems
    COMP9417	Machine Learning & Data Mining
    COMP9418	Advanced Machine Learning
    COMP9431	Robotic Software Architecture
    COMP9441	Security Engineering
    COMP9444	Neural Networks
    COMP9447	Security Engineering Workshop
    COMP9511	Human Computer Interaction
    COMP9514	Advanced Decision Theory
    COMP9515	Pattern Classification
    COMP9517	Computer Vision
    COMP9518	Pattern Recognition
    COMP9519	Multimedia Systems
    COMP9520	Ext Foundations of Computer Sc
    COMP9596	Research Project
    COMP9790	Principles of GNSS Positioning
    COMP9791	Modern Navigation &Positioning
    COMP9801	Ext Design&Analysis of Algo
    COMP9814	Ext Artificial Intelligence
    COMP9833	Ext Computer Networks & Appl
    COMP9844	Ext Neural Networks
    COMP9901	P/T Res. Thesis Comp Sci & Eng
    COMP9902	Res. Thesis Comp Sci & Eng F/T
    COMP9910	Mgt&Com Skills-CompSci&Eng Res
    COMP9912	Project (24 UOC)
    COMP9930	Readings in Comp Sci and Eng
    COMP9945	Research Project
    CRIM3010	Comparative Criminal Justice
    CVEN1015	Computing
    CVEN1025	Computing
    CVEN2002	Engineering Computations
    CVEN2025	Engineering Computations 1
    CVEN2702	Engineering Computations
    CVEN3025	Engineering Computations 2
    CVEN4307	Steel & Composite Structures
    CVEN8827	Composite Steel-Concrete Struc
    CVEN9820	Computational Struct Mechanics
    CVEN9822	Steel & Composite Structures
    CVEN9827	Composite Steel-Concrete Struc
    DANC2000	Dance Analysis & Composition 1
    DANC2005	Dance Analysis & Composition 2
    DANC2015	Dance Analysis & Composition 3
    ECON3213	Comparative Forecasting Techs
    ECON5122	Compet. in the Know. Econ.
    ECON5255	Computational Stats & Econ Mod
    EDST1492	Computer Skills for Teachers
    EDST4092	Computer Skills for Teachers
    EDST4157	Computing Studies Method 1
    EDST4158	Computing Studies Method 2
    ELEC4343	Source Coding & Compression
    ELEC4432	Computer Control & Instrumenta
    ELEC4632	Computer Control Systems
    ELEC9401	Computer Control Systems 1
    ELEC9402	Computer Control Systems 2
    ELEC9403	Real Time Computing & Control
    ELEC9733	Real Computing and Control
    ENGG1811	Computing for Engineers
    EURO2302	The Messiah Complex
    FINS5553	Insur. Comp. Oper. & Manage.
    FNDN0301	Computing Studies
    FNDN0302	Computing Studies and Research
    FNDN0311	Computing Studies - T
    FOOD4220	Computer Applications
    FOOD4320	Computer Applications
    FOOD4537	Computing in Food Science
    FOOD9101	Complex Fluid Micro & Rheology
    GBAT9131	Leadership in a Complex Enviro
    GEND1212	Analysing a Picture:Comp.&Des.
    GEND4201	Design and Computing
    GENE8001	Computer Game Design
    GENM0515	Computers for Professionals
    GENP0515	Computers for Professionals
    GENS2001	The Computer
    GENS5525	The Comp: Its Impact, Sign'fcnce
    GENT0407	Tv Soaps: a Comparative Study
    GENT0603	The Computer: Impact, Significan
    GENT0802	The Complexity of Everyday Life
    GENT1003	Computers into the 21st C
    GEOG3161	Computer Mapping & Data Displa
    GEOG3861	Computer Mapping
    GEOG9014	Computer Mapping &Data Display
    GEOG9210	Computer Mapping & Data Displa
    GEOL0300	Computing & Stats for Geol
    GEOL2041	Geological Computing
    GMAT1111	Introduction To Computing
    GMAT1150	Survey Methods& Computations
    GMAT1300	Comp Appl in Geomatics
    GMAT2111	Principles of Computer Processin
    GMAT2112	Principles of Computer Processin
    GMAT2122	Computer Graphics 1
    GMAT2131	Survey Computations
    GMAT2350	Comp for Spatial Info Sciences
    GMAT2500	Surveying Computations A
    GMAT2550	Surveying Computations B
    GMAT3111	Survey Computations
    GMAT3122	Computer Graphics 1
    GMAT3231	Geodetic Computations
    GMAT4111	Data Analysis & Computing 1
    GMAT4112	Data Analysis & Computing 1
    GMAT5111	Data Analysis & Computing 2
    GMAT5112	Data Analysis & Computing 2
    GMAT5122	Computer Graphics 2
    HEAL9471	Comparative H'lth Care Systems
    HEAL9501	Comp Tech for Health Serv Mngt
    HIST2487	The Messiah Complex
    HPSC2610	Computers, Brains & Minds
    HPST2004	Computers, Brains & Minds
    HPST2109	Computers, Brains & Minds
    IDES2121	Introduction To Computing
    IDES3101	Design Studio 5: Complexity
    IDES3231	Adv Computer Aided Product Des
    IDES5153	Computer Graphic Applications
    IDES5154	Computer Aided Design
    IEST5009	Competencies in Sustainability
    IEST5010	Competencies in Sustainability
    ILAS0232	Computer Prog'mng for Info. Appl
    ILAS0233	Computing Applications in The in
    INFS3607	Distributed Computer Systems
    IROB5732	Spec Topic- Internat & Comp IR
    IROB5734	Adv Seminar-Internat & Comp IR
    JURD7348	Harry Gibbs Moot Comp 6uoc
    JURD7419	Competition Law and Policy
    JURD7473	Asian Competition Law
    JURD7474	Competition Law and IP
    JURD7489	Complex Civil Litigation
    JURD7522	Competition Law
    JURD7559	Int'l&Comparative Law W'shop
    JURD7610	Mediation Competition
    JURD7616	International & Comparative IP
    JURD7648	Transitional Justice Intl Comp
    JURD7989	Comparative Anti-Terrorism Law
    JWST2104	The Messiah Complex
    LAND1131	Introduction To Computer Applica
    LAWS1032	Computer Applications to Law
    LAWS2065	Comparative Law
    LAWS2085	Comparative Law
    LAWS2110	Comparative Constitutional Law
    LAWS2148	Harry Gibbs Moot Comp 8uoc
    LAWS2410	Mediation Competition
    LAWS2589	Complex Civil Litigation
    LAWS3009	Comparative Criminal Justice:
    LAWS3022	Competition Law
    LAWS3035	Developing Comp Apps to Law
    LAWS3051	Telecomm. Competition & Cons.
    LAWS3148	Harry Gibbs Moot Comp
    LAWS3159	Int'l&Comparative Law W'shop
    LAWS3348	Transitional Justice Intl Comp
    LAWS3510	Mediation Competition
    LAWS3589	Complex Civil Litigation
    LAWS4016	International & Comparative IP
    LAWS4019	Competition Law
    LAWS4089	Comparative Anti-Terrorism Law
    LAWS4120	Themes in Asian & Compar. Law
    LAWS4133	Issues in Asian & Comp Law
    LAWS4291	Comparative Constitutional Law
    LAWS4620	Computer Applications To Law
    LAWS4765	Complex Commercial Litigation
    LAWS5234	Competition Law and Regulation
    LAWS7003	Global Issues in Comp Policy
    LAWS8016	International & Comparative IP
    LAWS8073	Asian Competition Law
    LAWS8074	Competition Law and IP
    LAWS8118	Legal Systems in Comp Persp
    LAWS8143	Comparative Patent Law
    LAWS8144	Comparative Trade Mark Law
    LAWS8219	Competition Law and Policy
    LAWS8289	Comparative Anti-Terrorism Law
    LAWS8348	Transitional Justice Intl Comp
    LAWS8765	Complex Commercial Litigation
    LAWS9973	Comparative Law
    LAWS9984	Int. & Comp. Indigenous Law
    LEGT5531	Comp. Bus. & Legal Strategies
    LEGT5602	Tax Admin. & Compliance
    LIBS0233	Computer Applications in The Inf
    MANF3500	Computers in Manufacturing 1
    MANF4500	Computers in Manufacturing 2
    MANF4601	Comp Aided Production Mgmt A
    MANF4602	Comp Aided Production Mgmt B
    MANF8560	Computer Integrated Manufact.
    MANF9500	Computer-aided Progrmg for Numcl
    MANF9543	Comp Aided Design/Manufacture
    MANF9560	Computer Integrated Manufact.
    MARK3022	Computer Applications in Marketi
    MATH1061	Introductory Applied Computing
    MATH2301	Mathematical Computing
    MATH2430	Symbolic Computing
    MATH2520	Complex Analysis
    MATH2521	Complex Analysis
    MATH2620	Higher Complex Analysis
    MATH2621	Higher Complex Analysis
    MATH2810	Statistical Computing
    MATH2910	Higher Statistical Computing
    MATH3101	Computational Mathematics
    MATH3301	Advanced Math Computing
    MATH3311	Math Computing for Finance
    MATH3400	Logic & Computability
    MATH3421	Logic and Computability
    MATH3430	Symbolic Computing
    MATH3680	Higher Complex Analysis
    MATH3790	Higher Computat. Combinatorics
    MATH3800	Statistical Computation 1
    MATH3810	Statistical Computation 2
    MATH3821	Stat Modelling & Computing
    MATH3871	Bayesian Inference and Comp
    MATH4003	Maths and Comp Sci Honours F/T
    MATH4004	Maths and Comp Sci Honours P/T
    MATH5009	Comp'l Coursework Thesis FT
    MATH5010	Comp'l Coursework Thesis PT
    MATH5305	Computational Mathematics
    MATH5315	High Perf Numerical Computing
    MATH5335	Comput'l Methods for Finance
    MATH5400	Logic & Computability
    MATH5505	Computational Combinatorics
    MATH5685	Complex Analysis
    MATH5856	Intro to Stats and Stat Comput
    MATH5960	Bayesian Inference & Comput'n
    MATH9315	Topics in Mathematical Computing
    MATS1021	Computing in Materials Science
    MATS1264	Fibre Reinforced Plastic Composi
    MATS3064	Composite Materials
    MATS4005	Composites and Functional Mats
    MATS5342	Comp Modelling & Design
    MATS6110	Computational Materials
    MBAX9131	Leadership in a Complex Enviro
    MECH1500	Computing 1M
    MECH3500	Computing 2M
    MECH3510	Computing Applications in Mech.
    MECH3530	Computing Applcts in Mechanical
    MECH3540	Computational Engineering
    MECH4130	Computer-aided Engineering Desig
    MECH4150	Design & Maintenance of Componen
    MECH4500	Computing 3M
    MECH4620	Computational Fluid Dynamics
    MECH8620	Computational Fluid Dynamics
    MECH9150	Design & Maintenance of Componen
    MECH9420	Composite Materials and Mechan
    MECH9620	Computational Fluid Dynamics
    MEFT5103	Computer Media
    MGMT2106	Comparative Management Systems
    MGMT5050	Teams, Ethics & Comp Adv
    MGMT5802	Comp. Adv. Through People
    MINE0710	Computing 1
    MINE1720	Microcomputers (mining)
    MINE1730	Computer Applications in Mining
    MINE4082	Computational Methods
    MINE4810	Comp Methods in Geomechanics
    MTRN2500	Comp for MTRN
    MTRN3500	Comp Appl in Mechatonic Sys
    MTRN3530	Computing Applcts in Mech.Sys.
    PFST2000	Dance Analysis & Composition 1
    PFST2005	Dance Analysis & Composition 2
    PFST2011	Performance Composition
    PHAR9121	Postmarketing Compliance Meds
    PHCM9471	Comparative H'lth Care Systems
    PHIL5206	AI & Computer Science
    PHIL5207	Ai & Computer Science 2A
    PHYS1601	Comp. Applic'ns in Exp. Sci. 1
    PHYS2001	Mechanics & Computational Phys
    PHYS2020	Computational Physics
    PHYS2120	Mechanics and Computational
    PHYS2601	Computer Applications 2
    PHYS3601	Computer Applications in Instrum
    PHYS3610	Computational Physics
    PHYS3620	Computer Based Signal Processing
    PLAN1061	Computer Literacy
    POLS2016	Concepts in Comparative Pol Cult
    POLS3953	Comparative Politics: Russia
    PSYC3191	Computer Science & Psychology
    PTRL1013	Computing-Petroleum Engineers
    PTRL4013	Well Completion & Stimulation
    PTRL5016	Well Completions & Stimulation
    PTRL6016	Well Completions & Stimulation
    REGS0044	Comp Law in Global Context
    REGS0115	Compliance: Financial Service
    REGS0218	Compliance: Financial Services
    REGS0428	Computer Applications in Linguis
    REGS0453	Multiple Regress. & Stat Comp
    REGS0474	Comparative International Tax
    REGS0633	Comparative Corp & Comm Law
    REGS0638	International Comparative Corp
    REGS0718	Energy Co-Compliance in Bldgs
    REGS3092	Comp Cntrl of Machines & Proc
    REGS3265	Intl and Comparative Ind. Rel.
    REGS3410	Computer Networks
    REGS3873	Introduction To Computer Graphic
    REGS3909	Trade Marks & Unfair Comp
    REGS3948	Competition Law
    REGS4045	Competition Reg. of Mergers
    REGS5618	Comp Integrated Manufacturing
    REGS7726	Composites & Multiphase Polyme
    REGS7908	Service Managing for Comp.Adv.
    SART1608	Digital Composite 1
    SART1681	Multimedia Computing Elective1
    SART1810	Introduction to Computing
    SART2608	Digital Composite 2
    SART2681	Multimedia Computing Elective2
    SART2811	Multimedia Computing Workshop
    SART2835	Composition and Design
    SART3608	Digital Composite 3
    SART3681	Multimedia Computing Elective3
    SART3840	Advanced Multimedia Computing
    SART9725	Intro to Multimedia Computing
    SART9739	Multimedia Computing Elective
    SART9741	Composition and Design
    SDES1106	Design and Computers 1
    SDES1110	Design and Computers 2
    SDES1111	Integrated Design Computing 1
    SDES1211	Integrated Design Computing 2
    SDES1601	Colour,Composition &Typography
    SDES2107	Design and Computers 3
    SDES2115	Design and Computers 2B
    SDES3107	Design and Computers 4
    SDES3173	Advanced Computer Graphics
    SDES4103	Design and Computers 4
    SDES6714	Intro 3D Computer Aided Design
    SLSP2902	Computers and Comm.
    SOCA3314	The Messiah Complex
    SOCI3401	Computer Analysis of Social Data
    SOCI3408	Computer Analysis of Social Data
    SOMA1608	Digital Composite
    SOMA1681	Intro Multimedia Computing
    SOMA1810	Introduction to Computing
    SOMA2402	Tangible Computing
    SOMA2608	Digital Composite 2
    SOMA2681	Advanced Multimedia Computing
    SOMA2811	Multimedia Computing Workshop
    SOMA3415	Compositional Project
    SOMA3608	Digital Composite 3
    SURV1111	Introduction To Computing
    SURV2111	Principles of Computer Processin
    SURV2122	Computer Graphics 1
    SURV3111	Survey Computations
    SURV3231	Geodetic Computations
    SURV4111	Data Analysis & Computing 1
    SURV5111	Data Analysis & Computing 2
    SURV5122	Computer Graphics 2
    SURV6121	Computer Graphics
    TABL1002	Computer Information Systems
    TABL2053	Acct for Complex Struct & Inst
    TABL3044	Comparative Tax Systems
    TABL5544	Comparative Tax Systems
    TEDG1101	Computers in Education
    TEDG1106	Computer-based Resources: Design
    TEDG1107	Managing With Computers in Schoo
    TEDG1112	Computers - Gifted & Talented St
    TEDG1113	Computer Control Technology in E
    TEED1134	Fundamentals of Computing
    TEED2119	Computers & People
    TELE4343	Source Coding and Compression
    TELE9302	Computer Networks
    TEXT2501	Computing Applications
    ZACM3011	Component Design
    ZACM3433	Compressible Flow
    ZACM4020	Computational Structures
    ZACM4031	Compressible Flow
    ZACM4913	Eng App of Comp Fluid Dynamics
    ZBUS2200	Markets and Competition
    ZEIT1101	Computational Problem Solving
    ZEIT1110	Computer Games
    ZEIT2102	Computer Technology
    ZEIT2305	Computer Games
    ZEIT3113	Computer Languages & Algorithm
    ZEIT3304	Computing Proj - Info Sys
    ZEIT3307	Computer Games
    ZEIT4003	Computational Fluid Dynamics
    ZEIT7101	Computational Problem Solving
    ZEIT8020	Computer Network Operations
    ZEIT8028	Computer Forensics
    ZEIT9100	Computer Science Research F/T
    ZEIT9101	Computer Science Research P/T
    ZGEN2300	Computers in Society
    ZGEN2301	Computer Games
    ZHSS8431	Comparative Defence Planning
    ZINT1001	Eng Comp Methods 1
    ZITE1001	Computer Tools for Engineers
    ZITE1101	Intro to Computer Science
    ZITE2101	Computer Languages & Algorithm
    ZITE2102	Computer Technology
    ZITE3101	Computing Proj - Comp Sci
    ZITE3105	Human Computer Interaction
    ZITE3106	Interactive Computer Graphics
    ZITE3113	Computer Languages & Algorithm
    ZITE3211	Microcomputer Interfacing
    ZITE3304	Computing Proj - Info Sys
    ZITE4101	Computer Sci 4 (Comb Hons) F/T
    ZITE4102	Computer Sci 4 (Comb Hon) P/T
    ZITE4103	Computer Science 4 (Hons) F/T
    ZITE4104	Computer Science 4 (Hons) P/T
    ZITE8103	Computer Graphics
    ZITE8104	Computer Security
    ZITE8105	Computer Speech Processing
    ZITE8145	SoftComp
    ZITE9100	Computer Science Research F/T
    ZITE9101	Computer Science Research P/T
    ZPEM3302	Complex Variables
    
    The second one looks better because the data itself isn't transformed, only the internal comparisons.

    If we want to know how many courses have "computing" or "computer" in their title, we have to use grep -E, which recognises the alternative operator "|", and wc to count the number of matches. There are a couple of ways to construct the regexp:

    grep -E -i 'computer|computing' course_codes | wc
        262    1149    9027
    
    grep -E -i 'comput(er|ing)' course_codes | wc
        262    1149    9027
    
    If you don't like the irrelevant word and character counts, use wc -l.

    Most of these 80 matches were CSE offerings, whose course codes begin with COMP, SENG or BINF. Which of the matches were courses offered by other schools?

    Think about it for a moment.... There's no "but not" regexp operator, so instead we construct a composite filter with an extra step to deal with eliminating the CSE courses:

    grep -E -i 'computer|computing' course_codes | grep -E -v '^(COMP|SENG|BINF)'
    ACSC1600	Computer Science 1
    ACSC1800	Computer Science 1E
    ACSC2015	Interactive Computer Graphics
    ACSC2020	Computer Science Core B2
    ACSC2021	Computer Systems Architectrue 2
    ACSC2107	Computer Languages B
    ACSC2601	Computer Science 2A
    ACSC2602	Computer Science 2B
    ACSC2802	Computer Science 2EE
    ACSC3003	Computer Project
    ACSC3029	Computing Project 3
    ACSC3030	Cryptography & Computer Securi
    ACSC3601	Computer Science 3A
    ACSC3603	Computer Science 3C
    ACSC4191	Computer Science 4 (Hons) F/T
    ACSC7304	Computer Graphics
    ACSC7306	Computer Speech Processing
    ACSC7336	Computer Security
    ACSC8248	Computer Graphics (12 Cpt)
    ACSC9000	Computer Science Research F/T
    ACSC9001	Computer Science Research P/T
    AELE2007	Computer Design
    AELE2508	Microcomputer Interfacing
    AELE3031	Microcomputer Interfacing
    AELE4511	Computer Control Theory
    ANCE8002	Supercomputing Techniques
    ARCH5202	Computer Applications 2
    ARCH5203	Computer Applications 3
    ARCH5220	Computer Graphics Programming 1
    ARCH5221	Computer Graphics Programming 2
    ARCH5223	Computer Applications 2
    ARCH5942	Arctitectural Computing Seminar
    ARCH6201	Architectural Computing 1
    ARCH6205	Architectural Computing 2
    ARCH6214	Architectural Computing 2
    ARCH7204	Design Computing Theory
    ARCH7205	Computer Graphics Programming
    ARTS2301	Computers, Brains & Minds
    ATAX0002	Computer Information Systems
    AVEN1500	Computing for Aviation
    BENV1141	Computers and Information Tech
    BENV1242	Computer-Aided Design
    BENV2405	Computer Graphics Programming
    BIOM9501	Computing for Biomedical Eng
    BLDG2281	Introduction To Computing
    BLDG3282	Computer Apps in Building
    BLDG3482	Computer Aplications in Constr
    CEIC5310	Computing Studies in The Process
    CEIC8310	Computing Studies Proc Ind
    CEIC8335	Adv Computer Methods
    CHEM3640	Computers in Chemistry
    CIVL1015	Computing
    CIVL1106	Computing & Graphics
    COFA2682	Multi-media Computing Unit 3
    COFA3681	Multi-media Computing Elective 1
    COFA5116	Design & Computers
    COFA5216	Design & Computers 1
    COFA5240	Design & Computers 2 Cad
    COFA5241	Design & Computers 2 Graphics
    COFA5338	Design & Computers 3 - Cad
    COFA5339	Design & Computers 3 - Graphic
    COFA8670	Intro To Multi-media Computing
    CVEN1015	Computing
    CVEN1025	Computing
    EDST1492	Computer Skills for Teachers
    EDST4092	Computer Skills for Teachers
    EDST4157	Computing Studies Method 1
    EDST4158	Computing Studies Method 2
    ELEC4432	Computer Control & Instrumenta
    ELEC4632	Computer Control Systems
    ELEC9401	Computer Control Systems 1
    ELEC9402	Computer Control Systems 2
    ELEC9403	Real Time Computing & Control
    ELEC9733	Real Computing and Control
    ENGG1811	Computing for Engineers
    FNDN0301	Computing Studies
    FNDN0302	Computing Studies and Research
    FNDN0311	Computing Studies - T
    FOOD4220	Computer Applications
    FOOD4320	Computer Applications
    FOOD4537	Computing in Food Science
    GEND4201	Design and Computing
    GENE8001	Computer Game Design
    GENM0515	Computers for Professionals
    GENP0515	Computers for Professionals
    GENS2001	The Computer
    GENT0603	The Computer: Impact, Significan
    GENT1003	Computers into the 21st C
    GEOG3161	Computer Mapping & Data Displa
    GEOG3861	Computer Mapping
    GEOG9014	Computer Mapping &Data Display
    GEOG9210	Computer Mapping & Data Displa
    GEOL0300	Computing & Stats for Geol
    GEOL2041	Geological Computing
    GMAT1111	Introduction To Computing
    GMAT2111	Principles of Computer Processin
    GMAT2112	Principles of Computer Processin
    GMAT2122	Computer Graphics 1
    GMAT3122	Computer Graphics 1
    GMAT4111	Data Analysis & Computing 1
    GMAT4112	Data Analysis & Computing 1
    GMAT5111	Data Analysis & Computing 2
    GMAT5112	Data Analysis & Computing 2
    GMAT5122	Computer Graphics 2
    HPSC2610	Computers, Brains & Minds
    HPST2004	Computers, Brains & Minds
    HPST2109	Computers, Brains & Minds
    IDES2121	Introduction To Computing
    IDES3231	Adv Computer Aided Product Des
    IDES5153	Computer Graphic Applications
    IDES5154	Computer Aided Design
    ILAS0232	Computer Prog'mng for Info. Appl
    ILAS0233	Computing Applications in The in
    INFS3607	Distributed Computer Systems
    LAND1131	Introduction To Computer Applica
    LAWS1032	Computer Applications to Law
    LAWS4620	Computer Applications To Law
    LIBS0233	Computer Applications in The Inf
    MANF3500	Computers in Manufacturing 1
    MANF4500	Computers in Manufacturing 2
    MANF8560	Computer Integrated Manufact.
    MANF9500	Computer-aided Progrmg for Numcl
    MANF9560	Computer Integrated Manufact.
    MARK3022	Computer Applications in Marketi
    MATH1061	Introductory Applied Computing
    MATH2301	Mathematical Computing
    MATH2430	Symbolic Computing
    MATH2810	Statistical Computing
    MATH2910	Higher Statistical Computing
    MATH3301	Advanced Math Computing
    MATH3311	Math Computing for Finance
    MATH3430	Symbolic Computing
    MATH3821	Stat Modelling & Computing
    MATH5315	High Perf Numerical Computing
    MATH9315	Topics in Mathematical Computing
    MATS1021	Computing in Materials Science
    MECH1500	Computing 1M
    MECH3500	Computing 2M
    MECH3510	Computing Applications in Mech.
    MECH3530	Computing Applcts in Mechanical
    MECH4130	Computer-aided Engineering Desig
    MECH4500	Computing 3M
    MEFT5103	Computer Media
    MINE0710	Computing 1
    MINE1720	Microcomputers (mining)
    MINE1730	Computer Applications in Mining
    MTRN3530	Computing Applcts in Mech.Sys.
    PHIL5206	AI & Computer Science
    PHIL5207	Ai & Computer Science 2A
    PHYS2601	Computer Applications 2
    PHYS3601	Computer Applications in Instrum
    PHYS3620	Computer Based Signal Processing
    PLAN1061	Computer Literacy
    PSYC3191	Computer Science & Psychology
    PTRL1013	Computing-Petroleum Engineers
    REGS0428	Computer Applications in Linguis
    REGS3410	Computer Networks
    REGS3873	Introduction To Computer Graphic
    SART1681	Multimedia Computing Elective1
    SART1810	Introduction to Computing
    SART2681	Multimedia Computing Elective2
    SART2811	Multimedia Computing Workshop
    SART3681	Multimedia Computing Elective3
    SART3840	Advanced Multimedia Computing
    SART9725	Intro to Multimedia Computing
    SART9739	Multimedia Computing Elective
    SDES1106	Design and Computers 1
    SDES1110	Design and Computers 2
    SDES1111	Integrated Design Computing 1
    SDES1211	Integrated Design Computing 2
    SDES2107	Design and Computers 3
    SDES2115	Design and Computers 2B
    SDES3107	Design and Computers 4
    SDES3173	Advanced Computer Graphics
    SDES4103	Design and Computers 4
    SDES6714	Intro 3D Computer Aided Design
    SLSP2902	Computers and Comm.
    SOCI3401	Computer Analysis of Social Data
    SOCI3408	Computer Analysis of Social Data
    SOMA1681	Intro Multimedia Computing
    SOMA1810	Introduction to Computing
    SOMA2402	Tangible Computing
    SOMA2681	Advanced Multimedia Computing
    SOMA2811	Multimedia Computing Workshop
    SURV1111	Introduction To Computing
    SURV2111	Principles of Computer Processin
    SURV2122	Computer Graphics 1
    SURV4111	Data Analysis & Computing 1
    SURV5111	Data Analysis & Computing 2
    SURV5122	Computer Graphics 2
    SURV6121	Computer Graphics
    TABL1002	Computer Information Systems
    TEDG1101	Computers in Education
    TEDG1106	Computer-based Resources: Design
    TEDG1107	Managing With Computers in Schoo
    TEDG1112	Computers - Gifted & Talented St
    TEDG1113	Computer Control Technology in E
    TEED1134	Fundamentals of Computing
    TEED2119	Computers & People
    TELE9302	Computer Networks
    TEXT2501	Computing Applications
    ZEIT1110	Computer Games
    ZEIT2102	Computer Technology
    ZEIT2305	Computer Games
    ZEIT3113	Computer Languages & Algorithm
    ZEIT3304	Computing Proj - Info Sys
    ZEIT3307	Computer Games
    ZEIT8020	Computer Network Operations
    ZEIT8028	Computer Forensics
    ZEIT9100	Computer Science Research F/T
    ZEIT9101	Computer Science Research P/T
    ZGEN2300	Computers in Society
    ZGEN2301	Computer Games
    ZITE1001	Computer Tools for Engineers
    ZITE1101	Intro to Computer Science
    ZITE2101	Computer Languages & Algorithm
    ZITE2102	Computer Technology
    ZITE3101	Computing Proj - Comp Sci
    ZITE3105	Human Computer Interaction
    ZITE3106	Interactive Computer Graphics
    ZITE3113	Computer Languages & Algorithm
    ZITE3211	Microcomputer Interfacing
    ZITE3304	Computing Proj - Info Sys
    ZITE4101	Computer Sci 4 (Comb Hons) F/T
    ZITE4102	Computer Sci 4 (Comb Hon) P/T
    ZITE4103	Computer Science 4 (Hons) F/T
    ZITE4104	Computer Science 4 (Hons) P/T
    ZITE8103	Computer Graphics
    ZITE8104	Computer Security
    ZITE8105	Computer Speech Processing
    ZITE9100	Computer Science Research F/T
    ZITE9101	Computer Science Research P/T
    
    The last ones are from the Computer Science school at ADFA.
  2. Consider a file called enrollments which contains data about student enrollment in courses. There is one line for each student enrolled in a course:
    ls -l enrollments
    -rw-r--r-- 1 cs2041 cs2041 1066833 Feb 19  2021 enrollments
    
    wc enrollments
       9441   53087 1066833 enrollments
    
    head enrollments
    COMP1521|5289619|Zou, Ronan Isaac                                  |8543  |COMPAS       |078.167|20T2|19971221|M
    COMP2511|5289619|Zou, Ronan Isaac                                  |8543  |COMPAS       |078.167|20T2|19971221|M
    COMP3511|5289619|Zou, Ronan Isaac                                  |8543  |COMPAS       |078.167|20T2|19971221|M
    COMP9313|5257864|Lin, Catherine                                    |3707/1|COMPSS       |078.667|20T2|19941124|F
    COMP9444|5257864|Lin, Catherine                                    |3707/1|COMPSS       |078.667|20T2|19941124|F
    COMP9417|5253259|Sun, Raymond Martin Yu                            |8543  |SENGAH       |000.000|20T2|19921106|M
    COMP2511|5292087|Ji, Jake                                          |3707/4|COMPA1 MATHT1|000.000|20T2|20010315|M
    COMP3121|5292087|Ji, Jake                                          |3707/4|COMPA1 MATHT1|000.000|20T2|20010315|M
    COMP9417|5292087|Ji, Jake                                          |3707/4|COMPA1 MATHT1|000.000|20T2|20010315|M
    COMP6443|5225639|Leung, Syed Sunny                                 |8543  |COMPAS COMPSS|090.000|20T2|20010517|M
    
    The following commands count how many students are enrolled in COMP2041 or COMP9041. The course IDs differ only in one character, so a character class is used instead of alternation.

    The first version below is often ferred because initially you may want to know "how many xxx", then having found that out the next question might be, "well give me a sample of 10 or so of them". Then it's a simple matter of replacing wc by head.

    grep -E '^COMP(2041|9044)' enrollments | wc -l
    588
    
    grep -E -c '^COMP(2041|9044)' enrollments
    588
    
    The last field field in the enrollment file records the student's gender. This command counts the number of female students enrolled in the courses.
    grep -E '^COMP(2041|9044)' enrollments | grep -E 'F$' | wc -l
    164
    
    Not a very good gender balance, is it?

    By the way, the two grep -Es could have been combined into one. How?

    This command will give a sorted list of course codes:

    cut -d'|' -f1 enrollments | sort | uniq
    COMP1000
    COMP1511
    COMP1521
    COMP1911
    COMP2041
    COMP2511
    COMP2521
    COMP3121
    COMP3141
    COMP3151
    COMP3231
    COMP3331
    COMP3511
    COMP3900
    COMP4336
    COMP4951
    COMP4952
    COMP4953
    COMP4961
    COMP4962
    COMP4963
    COMP6443
    COMP6447
    COMP6448
    COMP6452
    COMP6721
    COMP6752
    COMP6771
    COMP6843
    COMP9020
    COMP9021
    COMP9024
    COMP9044
    COMP9101
    COMP9154
    COMP9201
    COMP9242
    COMP9311
    COMP9313
    COMP9319
    COMP9323
    COMP9331
    COMP9332
    COMP9336
    COMP9414
    COMP9417
    COMP9444
    COMP9511
    COMP9517
    COMP9900
    COMP9901
    COMP9902
    COMP9991
    COMP9992
    COMP9993
    
    The student records system known to users as myUNSW is built on top of a large US product known as PeopleSoft (the company was taken over by Oracle in 2004). On a scale of 1 to 10 the quality of the design of this product is about 3. One of its many flaws is its insistence that everybody must have two names, a "Last Name" and a "First Name", neither of which can be empty. To signify that a person has only a single name (common in Sri Lanka, for example), the system stores a dot character in the "First Name" field. The enrollments file shows the data as stored in the system, with a comma and space separating the component names. It has some single-named people (note that the names themselves have been disguised):
    grep -E ', \.' enrollments
    COMP9021|5251019|Sun, .                                            |8543  |COMPBH       |076.667|20T2|20000312|F
    COMP9313|5251019|Sun, .                                            |8543  |COMPBH       |076.667|20T2|20000312|F
    COMP9417|5251019|Sun, .                                            |8543  |COMPBH       |076.667|20T2|20000312|F
    COMP2521|5228391|Gu, . Ziwei Mohamed Chan Yuchen                   |8543  |COMPY1       |000.000|20T2|19920218|M
    COMP1511|5258901|Lin, . Michelle Ying Amy                          |3785/1|COMPAS COMPSS|060.278|20T2|19951222|F
    COMP9044|5218745|Smith, . Sean                                     |3764/1|COMPA1       |065.571|20T2|19980727|M
    COMP9313|5218745|Smith, . Sean                                     |3764/1|COMPA1       |065.571|20T2|19980727|M
    COMP9414|5218745|Smith, . Sean                                     |3764/1|COMPA1       |065.571|20T2|19980727|M
    COMP9313|5200281|Peng, . Xu                                        |3707/2|COMPY1       |083.000|20T2|19991019|M
    COMP9414|5200281|Peng, . Xu                                        |3707/2|COMPY1       |083.000|20T2|19991019|M
    COMP1521|5288268|He, . Josephine Jade                              |4515/1|TELEAS       |078.385|20T2|19930811|F
    COMP3511|5288268|He, . Josephine Jade                              |4515/1|TELEAS       |078.385|20T2|19930811|F
    COMP1521|5253307|Zhou, .                                           |3707/1|COMPA1       |072.889|20T2|19980326|F
    COMP2521|5253307|Zhou, .                                           |3707/1|COMPA1       |072.889|20T2|19980326|F
    COMP9517|5263026|Chau, .                                           |3707/3|COMPA1 MTRNAH|000.000|20T2|19930614|M
    COMP2521|5232033|Nguyen, .                                         |3778/3|COMPCS       |000.000|20T2|19911111|M
    COMP2521|5228434|Ji, .                                             |8543  |ACTLD1       |072.000|20T2|19910711|M
    COMP3121|5227211|Cai, . Danny                                      |3782/1|COMPSS       |078.250|20T2|19991110|M
    COMP3141|5227211|Cai, . Danny                                      |3782/1|COMPSS       |078.250|20T2|19991110|M
    COMP9242|5227211|Cai, . Danny                                      |3782/1|COMPSS       |078.250|20T2|19991110|M
    COMP1511|5261621|Jiang, . Tian                                     |3707/2|COMPI1 MTRNAH|071.059|20T2|20040116|F
    COMP3121|5210829|Liu, . Sean                                       |3706/2|SENGAH       |056.545|20T2|20010422|M
    COMP9313|5227956|Shukla, .                                         |3778/3|COMPCS       |066.444|20T2|19990124|M
    COMP9319|5227956|Shukla, .                                         |3778/3|COMPCS       |066.444|20T2|19990124|M
    COMP1521|5283475|Mehta, .                                          |5543  |ELECAH       |081.593|20T2|19940507|M
    COMP2521|5283475|Mehta, .                                          |5543  |ELECAH       |081.593|20T2|19940507|M
    COMP9021|5292664|Hu, . Lauren                                      |3586/3|COMPAS COMPSS|044.000|20T2|20010107|F
    COMP3231|5286104|Tian, . Jason                                     |3781/4|COMPAS       |070.154|20T2|19880725|M
    COMP6447|5286104|Tian, . Jason                                     |3781/4|COMPAS       |070.154|20T2|19880725|M
    COMP6843|5286104|Tian, . Jason                                     |3781/4|COMPAS       |070.154|20T2|19880725|M
    COMP1521|5223988|Lo, . Peter                                       |3785/3|COMPAS       |082.250|20T2|20030106|M
    COMP3141|5223988|Lo, . Peter                                       |3785/3|COMPAS       |082.250|20T2|20030106|M
    COMP9319|5223988|Lo, . Peter                                       |3785/3|COMPAS       |082.250|20T2|20030106|M
    COMP1511|5270628|Zhang, . Hannah Samantha                          |3785/3|ACCTA1 COMPA1|076.583|20T2|19941114|F
    COMP1511|5237863|Tao, . Tanya Angela                               |1650  |COMPAS       |067.500|20T2|20041108|F
    COMP9024|5291313|Pan, .                                            |3778/2|COMPAS       |000.000|20T2|20040528|F
    COMP9311|5291313|Pan, .                                            |3778/2|COMPAS       |000.000|20T2|20040528|F
    COMP9414|5291313|Pan, .                                            |3778/2|COMPAS       |000.000|20T2|20040528|F
    COMP9024|5239540|Hua, . Cheng Julian                               |8543  |MTRNAH       |000.000|20T2|19990517|M
    COMP9331|5239540|Hua, . Cheng Julian                               |8543  |MTRNAH       |000.000|20T2|19990517|M
    COMP3900|5229290|Yao, .                                            |3707/2|COMPCS       |000.000|20T2|19980912|M
    COMP3141|5269992|Jain, . Wenkai                                    |3778/3|COMPAS       |077.000|20T2|20040517|M
    COMP6443|5269992|Jain, . Wenkai                                    |3778/3|COMPAS       |077.000|20T2|20040517|M
    COMP1521|5271820|Liao, . Siddharth Danny                           |3778/2|COMPAS       |079.400|20T2|19960129|M
    COMP1511|5274740|Truong, . Derek                                   |8543  |COMPCS       |048.675|20T2|20040822|M
    COMP3141|5281370|Dang, .                                           |3784/3|COMPAS       |056.778|20T2|20011220|M
    COMP1521|5279690|Ho, .                                             |8543  |COMPCS       |052.286|20T2|19941130|F
    COMP1911|5237187|Yao, . Vivian                                     |3673/1|COMPCS       |000.000|20T2|20020126|F
    COMP9414|5204473|Chong, .                                          |1650  |COMPI1       |070.412|20T2|19970304|M
    COMP1511|5233661|Brown, . Philip                                   |3778/3|COMPAS COMPDS|063.500|20T2|19920311|M
    COMP3121|5285844|Hou, . Dominic Samuel                             |5543  |COMPAS       |074.250|20T2|19990318|M
    COMP9417|5285844|Hou, . Dominic Samuel                             |5543  |COMPAS       |074.250|20T2|19990318|M
    COMP3141|5211498|Fu, . Oliver Eric                                 |3586/1|COMPBH       |071.200|20T2|19920703|M
    COMP6771|5211498|Fu, . Oliver Eric                                 |3586/1|COMPBH       |071.200|20T2|19920703|M
    COMP3121|5265590|Lu, . Alexandra                                   |8543  |COMPAS COMPSS|053.444|20T2|19991204|F
    COMP6443|5265590|Lu, . Alexandra                                   |8543  |COMPAS COMPSS|053.444|20T2|19991204|F
    COMP9417|5290779|Yu, . Abigail                                     |3970/1|ENGGAH       |064.875|20T2|20000102|F
    COMP3141|5209358|Dang, . Gabriel                                   |8543  |COMPCS       |061.786|20T2|19910419|M
    COMP9021|5206769|Yuan, . Yifei                                     |3707/3|MTRNAH       |043.000|20T2|19941227|M
    COMP9900|5294140|Ji, . Grace Joanna                                |8543  |SENGAH       |078.529|20T2|19951216|F
    COMP9020|5246136|Luo, . Zeyu                                       |8543  |COMPSS       |056.000|20T2|19960517|M
    COMP9021|5246136|Luo, . Zeyu                                       |8543  |COMPSS       |056.000|20T2|19960517|M
    COMP3121|5229473|Ren, .                                            |8543  |COMPCS       |080.500|20T2|20030819|M
    COMP6771|5229473|Ren, .                                            |8543  |COMPCS       |080.500|20T2|20030819|M
    COMP9900|5281227|Ren, .                                            |3778/3|COMPCS       |077.000|20T2|20030101|M
    COMP9319|5253678|Gao, . Xin                                        |3785/3|COMPCS       |077.214|20T2|19961214|F
    COMP2511|5241659|Ma, .                                             |8543  |COMPA1       |081.333|20T2|20001201|M
    COMP9417|5241659|Ma, .                                             |8543  |COMPA1       |081.333|20T2|20001201|M
    COMP9101|5238198|Yin, .                                            |3736/5|COMPA1       |086.286|20T2|19971108|M
    COMP9313|5238198|Yin, .                                            |3736/5|COMPA1       |086.286|20T2|19971108|M
    COMP9414|5238198|Yin, .                                            |3736/5|COMPA1       |086.286|20T2|19971108|M
    COMP2521|5298417|So, . Lily Amy                                    |3707/1|COMPCS       |073.500|20T2|19941031|F
    COMP3511|5298417|So, . Lily Amy                                    |3707/1|COMPCS       |073.500|20T2|19941031|F
    
    What would have happened if we forgot the backslash?

    If we wanted to know how many different students there were of this type rather than all enrollments, just cut out the second field (student ID) and use uniq. It's not necessary to sort the data in this case only because the data is clustered, that is, all equal values are adjacent although they're not necessarily sorted.

    grep -E ', \.' enrollments | cut -d'|' -f2 | uniq | wc
         45      45     360
    
  3. Now let us turn our attention from students and courses to programs. The enrollments file, as well as linking a student to the courses they're taking, also links them to the program (degree) that they are currently enrolled in. Consider that we want to find out the program codes of the students taking COMP2041. The following pipeline will do this:
    grep -E 'CCOMP(2041|9044)' enrollments | cut -d'|' -f4 | cut -d/ -f1  | sort | uniq
    
    If we want to know how many students come from each program, ordered from most common program to least common program, try this:
    grep -E 'COMP(2041|9044)' enrollments | cut -d'|' -f4 | cut -d/ -f1 | sort | uniq -c | sort -nr
        165 8543  
         91 3778
         58 3707
         37 3784
         30 3785
         28 7543  
         16 3789
         14 3959
         13 3781
         13 3764
         11 3768
          8 5543  
          8 3782
          8 3767
          8 1650  
          6 3970
          5 8338  
          4 3979
          4 3761
          4 3736
          3 8161
          3 4515
          3 3805
          3 3791
          3 3788
          3 3783
          3 3762
          3 3706
          2 3786
          2 3674
          2 3588
          2 3155
          2 3131
          1 8750
          1 6115
          1 4795
          1 4733
          1 4520
          1 3981
          1 3978
          1 3969
          1 3967
          1 3962
          1 3961
          1 3956
          1 3776
          1 3673
          1 3589
          1 3586
          1 3564
          1 3558
          1 3502
          1 3332
          1 3133
          1 2912  
          1 1630  
    
    Note that a tab is usually inserted between the count and the data, but not all implementations of the uniq command ensure this.
  4. Consider a file called program_codes that contains the code and name of each program offered at UNSW (excluding research programs):

    wc program_codes
     1798  6466 46572 program_codes
    
    head program_codes
    0350 Medicine (Prince Henry/POW)
    0351 Medicine (SWS Clinical School)
    0352 Medicine (St George)
    0353 Medicine (St Vincent's)
    0360 Pathology
    0370 Physiology and Pharmacology
    0375 Rural Health
    0380 Obstetrics and Gynaecology
    0390 Psychiatry
    0400 Surgery (Prince Henry/POW)
    
    We can use this file to give more details of the programs that COMP2041 students are taking, if some users don't want to deal with just course codes.
    grep -E 'COMP(2041|9044)' enrollments | cut -d'|' -f4 | cut -d/ -f1 | sort | uniq | join - program_codes
    1630  Civil & Environmental Eng
    1650  Computer Science and Eng
    3131 Mat Sci and Eng Hons
    3133 Mat Sci and Eng Hons/BiomedEng
    3155 Actuarial Studies / Commerce
    3502 Commerce
    3558 Commerce (International)
    3564 Economics / Science (Adv Math)
    3586 Actuarial Studies
    3588 Actuarial Studies / Economics
    3589 Actuarial Stu/Adv Maths (Hons)
    3706 Engineering Science
    3707 Engineering (Honours)
    3736 BE (Hons) ME Elec Eng
    3761 Adv Math (Hons) / Eng (Hons)
    3762 AdvSci(Hons)/Engineering(Hons)
    3764 Engineering (Hons)/Commerce
    3767 Engineering (Hons) / Science
    3768 Eng (Hons) / MBiomedE
    3776 Engineering (Hons) / Surveying
    3805 Medicine
    3956 Advanced Mathematics (Honours)
    3961 Engineering (Honours) / Arts
    3962 Advanced Science (Honours)
    3967 Commerce / Computer Science
    3969 Media Arts (Hons) / Comp Sci
    3970 Science
    3978 Computer Science
    3979 Information Systems
    3981 Aviation (Management)
    4515 Comp Sci & Eng (Honours)
    4733 Commerce / Law
    5543  Information Technology
    6115 UNSW Preparation Program 17-19
    7543  Computing
    8161 Financial Mathematics
    8338  Engineering Science
    8543  Information Technology
    8750 Statistics
    
    We can combine the enrollment counts (for both courses) with the program titles to produce a self-descriptive tally. It's even better if it's in decreasing order of popularity, so after joining the tallies with the program titles, re-sort the composite data:
    grep -E 'COMP(2041|9044)' enrollments | cut -d'|' -f4 | cut -d/ -f1 | sort | uniq -c | join -1 2 -a 1 - program_codes  | sort -k2rn
    8543 165  Information Technology
    3778 91
    3707 58 Engineering (Honours)
    3784 37
    3785 30
    7543 28  Computing
    3789 16
    3959 14
    3764 13 Engineering (Hons)/Commerce
    3781 13
    3768 11 Eng (Hons) / MBiomedE
    1650 8  Computer Science and Eng
    3767 8 Engineering (Hons) / Science
    3782 8
    5543 8  Information Technology
    3970 6 Science
    8338 5  Engineering Science
    3736 4 BE (Hons) ME Elec Eng
    3761 4 Adv Math (Hons) / Eng (Hons)
    3979 4 Information Systems
    3706 3 Engineering Science
    3762 3 AdvSci(Hons)/Engineering(Hons)
    3783 3
    3788 3
    3791 3
    3805 3 Medicine
    4515 3 Comp Sci & Eng (Honours)
    8161 3 Financial Mathematics
    3131 2 Mat Sci and Eng Hons
    3155 2 Actuarial Studies / Commerce
    3588 2 Actuarial Studies / Economics
    3674 2
    3786 2
    1630 1  Civil & Environmental Eng
    2912 1 
    3133 1 Mat Sci and Eng Hons/BiomedEng
    3332 1
    3502 1 Commerce
    3558 1 Commerce (International)
    3564 1 Economics / Science (Adv Math)
    3586 1 Actuarial Studies
    3589 1 Actuarial Stu/Adv Maths (Hons)
    3673 1
    3776 1 Engineering (Hons) / Surveying
    3956 1 Advanced Mathematics (Honours)
    3961 1 Engineering (Honours) / Arts
    3962 1 Advanced Science (Honours)
    3967 1 Commerce / Computer Science
    3969 1 Media Arts (Hons) / Comp Sci
    3978 1 Computer Science
    3981 1 Aviation (Management)
    4520 1
    4733 1 Commerce / Law
    4795 1
    6115 1 UNSW Preparation Program 17-19
    8750 1 Statistics
    
    Note the curious extra space before the title of some programs. It took me a while to work it out, can you? (Hint: how are the programs shown in the enrollment file?) Suggest an appopriate change to the pipeline.
  5. Lecture exercises on wc:
    1. how many different programs does UNSW offer?
      wc -l program_codes
      1798 program_codes
      
    2. how many times was WebCMS accessed?
      wc -l access_log
      59779 access_log
      
    3. how many students are studying in CSE?
      wc -l enrollments
      9441 enrollments
      

      The above solutions assume that we're talking about total enrollments. If the question actually meant how many distinct indivduals are studying courses offered by CSE, then we'd answer it as:

      cut -d'|' -f2 enrollments | sort | uniq | wc -l
      5658
      
    4. how many words are there in the book?
      wc -w book
      60428 book
      
    5. how many lines are there in the story?
      wc -l story
      87 story
      
Shell
Shell commands for power users.

#include <stdio.h>

// print arguments to stdout
int main(int argc, char *argv[]) {

    for (int i = 1; i < argc; i++) {
        if (i > 1) {
            fputc(' ', stdout);
        }
        fputs(argv[i], stdout);
    }
    fputc('\n', stdout);

    return 0;
}

Download echo.c



import sys


def main():
    """
    print arguments to stdout
    """
    print(' '.join(sys.argv[1:]))


if __name__ == '__main__':
    main()

Download echo.py


A simple shell script demonstrating access to arguments.
echo My name is "$0"
echo My process number is $$
echo I have $# arguments

# your not going to see any difference unless you use these in a loop
echo My arguments separately are $*
echo My arguments together are "$*"
echo My arguments separately are $@
echo My arguments as quoted are "$@"

echo My 5th argument is "'$5'"
echo My 10th argument is "'${10}'"
echo My 255th argument is "'${255}'"

Download args.sh


$ ./accessing_args.sh one two "three four"
Using "$*": one two three four
Using $*: one two three four
Using "$@": one two three four
echo 'Using $*:'
for a in $*
do
    echo "$a"
done

echo 'Using "$*":'
for a in "$*"
do
    echo "$a"
done

echo 'Using "$@":'
for a in "$@"
do
  echo "$a"
done

Download accessing_args.sh


l [file|directories...] - list files


Short shell scripts can be used for convenience.

It is common to put these scripts in a directory such as /home/z1234567/scripts then add this directory to PATH e.g in .bash_login
PATH=$PATH:/home/z1234567/scripts

Note: "$@" like $* expands to the arguments to the script, but preserves whitespace in arguments.
ls -las "$@"

Download l



Count the number of time each different word occurs in the files given as arguments, or stdin if no arguments, e.g. word_frequency.sh dracula.txt
cat "$@" |                   # tr doesn't take filenames as arguments
tr '[:upper:]' '[:lower:]' | # map uppercase to lower case
tr ' ' '\n' |                # convert to one word per line
tr -cd "a-z'" |              # remove all characters except a-z and '
grep -E -v '^$' |            # remove empty lines
sort |                       # place words in alphabetical order
uniq -c |                    # count how many times each word occurs
sort -rn                     # order in reverse frequency of occurrence

# notes:
# - first 2 tr commands could be combined
# - sed 's/ /\n/g' could be used instead of tr ' ' '\n'
# - sed "s/[^a-z']//g" could be used instead of tr -cd "a-z'"

Download word_frequency.sh

simple emulation of /usr/bin/seq for a COMP(2041|9044) example

Print the integers 1..n or n..m
if test $# = 1
then
    first=1
    last=$1
elif test $# = 1
then
    first=$1
    last=$2
else
    echo "Usage: $0 <last> or  $0 <first> <last>" 1>&2
fi

number=$first
while test $number -le "$last"
do
    echo $number
    number=$((number + 1))
done

Download seq.v1.sh

simple emulation of /usr/bin/seq for a COMP(2041|9044) example
Print the integers 1..n or m..n
if [ $# = 1 ]
then
    first=1
    last=$1
elif [ $# = 1 ]
then
    first=$1
    last=$2
else
    echo "Usage: $0 <last> or  $0 <first> <last>" 1>&2
fi

number=$first
while [ $number -le $last ]
do
    echo $number
    number=$((number + 1))
done

Download seq.v2.sh


Repeatedly download a specified web page until a specified regexp matches its source then notify the specified email address.

For example:
repeat_seconds=300  #check every 5 minutes

if test $# = 3
then
    url=$1
    regexp=$2
    email_address=$3
else
    echo "Usage: $0 <url> <regex>" 1>&2
    exit 1
fi

while true
do
    if curl --silent "$url"|grep -E "$regexp" >/dev/null
    then
        echo "Generated by $0" |
        mail -s "$url now matches $regexp" "$email_address"
        exit 0
    fi
    sleep $repeat_seconds
done

Download watch_website.sh



Change the names of the specified files to lower case. (simple version of the perl utility rename)

Note use of test to check if the new filename is unchanged.

Note the double quotes around $filename so filenames containing spaces are not broken into multiple words

Note the use of mv -- to stop mv interpreting a filename beginning with - as an option

Note files named -n or -e still break the script because echo will treat them as an option,
if test $# = 0
then
    echo "Usage $0: <files>" 1>&2
    exit 1
fi

for filename in "$@"
do
    new_filename=$(echo "$filename" | tr '[:upper:]' '[:lower:]')

    test "$filename" = "$new_filename" &&
        continue

    if test -r "$new_filename"
    then
        echo "$0: $new_filename exists" 1>&2
    elif test -e "$filename"
    then
        mv -- "$filename" "$new_filename"
    else
        echo "$0: $filename not found" 1>&2
    fi

done

Download tolower.sh

create 1001 C files, compile and run them
this programs create 1000 files f0.c .. f999.c file f$i.c contains function f$i which returns $i for example file42.c contains function f42 which returns 42 main.c is created with code to call all 1000 functions and print the sum of their return values
first add the initial lines to main.c note the use of quotes on eof to disable variable interpolation in the here document
cat >main.c <<'eof'
#include <stdio.h>

int main(void) {
    int v = 0 ;
eof

i=0
while test $i -lt 1000
do
    # add a line to main.c to call the function f$i

    cat >>main.c <<eof
    int f$i(void);
    v += f$i();
eof

    # create file$i.c containing function f$i

    cat >file$i.c <<eof
int f$i(void) {
    return $i;
}
eof

    i=$((i + 1))
done

cat >>main.c <<'eof'
    printf("%d\n", v);
    return 0;
}
eof

# compile and run the 1001 C files
# time clang main.c file*.c
# ./a.out

Download create_1001_file_C_program.sh


set -x
# written by andrewt@unsw.edu.au for COMP(2041|9044)
#
# Run as plagiarism_detection.simple_diff.sh <files>
# Report if any of the files are copies of each other
#
# Note use of diff -iw so changes in white-space or case
# are ignored

for file1 in "$@"
do
    for file2 in "$@"
    do
        test "$file1" = "$file2" &&
            break # avoid comparing pairs of assignments twice

        if diff -i -w "$file1" "$file2" >/dev/null
        then
            echo "$file1 is a copy of $file2"
        fi

    done
done

Download plagiarism_detection.simple_diff.sh



Improved version of plagiarism_detection.simple_diff.sh

The substitution s/\/\/.*// removes // style C comments.
This means changes in comments won't affect comparisons.

Note use of temporary files
TMP_FILE1=/tmp/plagiarism_tmp1$$
TMP_FILE2=/tmp/plagiarism_tmp2$$


for file1 in "$@"
do
    for file2 in "$@"
    do
        test "$file1" = "$file2" &&
            break # avoid comparing pairs of assignments twice

        sed 's/\/\/.*//' "$file1" >$TMP_FILE1
        sed 's/\/\/.*//' "$file2" >$TMP_FILE2

        if diff -i -w $TMP_FILE1 $TMP_FILE2 >/dev/null
        then
            echo "$file1 is a copy of $file2"
        fi

    done
done

rm -f $TMP_FILE1 $TMP_FILE2

Download plagiarism_detection.comments.sh



Improved version of plagiarism_detection.comments.sh
change all C strings to the letter 's' and change all identifiers to the letter 'v'.
Hence changes in strings & identifiers will be ignored.
TMP_FILE1=/tmp/plagiarism_tmp1$$
TMP_FILE2=/tmp/plagiarism_tmp2$$

# s/"["]*"/s/g changes strings to the letter 's'
# It won't match a few C strings which is OK for our purposes

# s/[a-zA-Z_][a-zA-Z0-9_]*/v/g changes variable names to 'v'
# It will also change function names, keywords etc.
# which is OK for our purposes.

substitutions='
    s/\/\/.*//
    s/"[^"]"/s/g
    s/[a-zA-Z_][a-zA-Z0-9_]*/v/g'

for file1 in "$@"
do
    for file2 in "$@"
    do
        test "$file1" = "$file2" &&
            break # avoid comparing pairs of assignments twice

        sed "$substitutions" "$file1" >$TMP_FILE1
        sed "$substitutions" "$file2" >$TMP_FILE2

        if diff -i -w $TMP_FILE1 $TMP_FILE2 >/dev/null
        then
            echo "$file1 is a copy of $file2"
        fi
    done
done
rm -f $TMP_FILE1 $TMP_FILE2

Download plagiarism_detection.identifiers.sh



Improved version of plagiarism_detection.identifiers.sh

Note the use of sort so line reordering won't prevent detection of plagiarism.
TMP_FILE1=/tmp/plagiarism_tmp1$$
TMP_FILE2=/tmp/plagiarism_tmp2$$

substitutions='
    s/\/\/.*//
    s/"[^"]"/s/g
    s/[a-zA-Z_][a-zA-Z0-9_]*/v/g'

for file1 in "$@"
do
    for file2 in "$@"
    do
        test "$file1" = "$file2" &&
            break # avoid comparing pairs of assignments twice

        sed "$substitutions" "$file1"|sort >$TMP_FILE1
        sed "$substitutions" "$file2"|sort >$TMP_FILE2

        if diff -i -w $TMP_FILE1 $TMP_FILE2 >/dev/null
        then
            echo "$file1 is a copy of $file2"
        fi
    done
done
rm -f $TMP_FILE1 $TMP_FILE2

Download plagiarism_detection.reordering.sh



Improved version of plagiarism_detection.reordering.sh with robust creation and removal of temporary files
TMP_FILE1=$(mktemp /tmp/plagiarism_tmp.1.XXXXXXXXXX)
TMP_FILE2=$(mktemp /tmp/plagiarism_tmp.2.XXXXXXXXXX)
trap 'rm -f $TMP_FILE1 $TMP_FILE2;exit' INT TERM EXIT

substitutions='
    s/\/\/.*//
    s/"[^"]"/s/g
    s/[a-zA-Z_][a-zA-Z0-9_]*/v/g'

for file1 in "$@"
do
    for file2 in "$@"
    do
        test "$file1" = "$file2" &&
            break # avoid comparing pairs of assignments twice

        sed "$substitutions" "$file1"|sort >$TMP_FILE1
        sed "$substitutions" "$file2"|sort >$TMP_FILE2

        if diff -i -w $TMP_FILE1 $TMP_FILE2 >/dev/null
        then
            echo "$file1 is a copy of $file2"
        fi
    done
done

Download plagiarism_detection.mktemp.sh




securely & robustly create a new temporary directory
temporary_directory=$(mktemp -d /tmp/dir.XXXXXXXXXX)

# ensure temporary directory + all its contents removed on exit
trap 'rm -rf "$temporary_directory; exit"' INT TERM EXIT

# change working directory to the new temporary directory
cd "$temporary_directory" || exit 1

# we are now in an empty directory
# and create any number of files & directories
# which all will be removed by the trap above

# e.g. create one thousand empty files
seq 1 1000|xargs touch

# print current directory and list files
pwd
ls -l

Download create_temporary_directory.sh



Improved version of plagiarism_detection.reordering.sh

Note use sha256sum to calculate a Cryptographic hash of the modified file https://en.wikipedia.org/wiki/SHA-2 and use of sort && uniq to find files with the same hash
This allows execution time linear in the number of files
We could use a faster less secure hashing fucntion instead of sha2
substitutions='
    s/\/\/.*//
    s/"[^"]"/s/g
    s/[a-zA-Z_][a-zA-Z0-9_]*/v/g'

for file in "$@"
do
    sha2hash=$(sed "$substitutions" "$file"|sort|sha256sum)
    echo "$sha2hash $file"
done|
sort|
uniq -w32 -d --all-repeated=separate|
cut -c36-

Download plagiarism_detection.hash.sh

demonstrate simple use of read
echo -n "Do you like learning Shell? "
read answer

case "$answer" in
[Yy]*)
    response=":)"
    ;;

[Nn]*)
    response=":("
    ;;

*)
    response="??"
esac

echo "$response"

Download read_response.sh

over-simple /bin/cat emulation using read
setting the special variable IFS to the empty trings stops white space being stripped
for file in "$@"
do
    while IFS= read -r line
    do
        echo "$line"
    done <$file
done

Download read_cat.sh

demonstrate simple use of a shell function
repeat_message() {
    n=$1
    message=$2
    for i in $(seq 1 $n)
    do
        echo "$i: $message"
    done
}

i=0
while test $i -lt 4
do
    repeat_message 3 "hello Andrew"
    i=$((i + 1))
done

Download repeat_message.sh


print print numbers < 1000
note use of local Shell builtin to scope a variable without the local declaration the variable i in the function would be global and would break the bottom while loop
local is not (yet) POSIX but is widely supported
is_prime() {
    local n i
    n=$1
    i=2
    while test $i -lt $n
    do
        test $((n % i)) -eq 0 &&
            return 1
        i=$((i + 1))
    done
    return 0
}

i=0
while test $i -lt 1000
do
    is_prime $i && echo $i
    i=$((i + 1))
done

Download local.sh

print positive integers for one second real time
my_process_id=$$

# launch a asynchronous sub-shell that will kill
# this process in a second
(sleep 1; kill $my_process_id) &

i=0
while true
do
    echo $i
    i=$((i + 1))
done

Download async.v0.sh

count slowly and laugh at interrupts (ctrl-C)
catch signal SIGINT and print message
trap 'echo ha ha' INT

n=0
while true
do
    echo "$n"
    sleep 1
    n=$((n + 1))
done

Download laugh.sh

print positive integers for one second real time

catch signal SIGTERM, print message and exit
trap 'echo loop executed $n times in 1 second; exit 0' TERM

# launch a sub-shell that will terminate
# this process in 1 second
my_process_id=$$
(sleep 1; kill $my_process_id) &

n=0
while true
do
    n=$((n + 1))
done

Download async.v1.sh


compile the files of a muti-file C program in parallel use create_1001_file_C_program.sh to create suitable test data

On a CPU with n cores this can be (nearly) n times faster

If there are large number of C files we may exhaust memory or operating system resources

for f in "$@"
do
    clang -c "$f" &
done

# wait for the incremental compiles to finish
# and then compile .o files into single binary
wait
clang *.o -o binary

Download parallel_compile.v0.sh


compile the files of a muti-file C program in parallel use create_1001_file_C_program.sh to create suitable test data
on Linux getconf will tell us how many cores the machine has otherwise assume 8
max_processes=$(getconf _NPROCESSORS_ONLN 2>/dev/null) ||
    max_processes=8

# NOTE: this breaks if a filename contains whitespace or quotes

echo "$@"|
xargs --max-procs=$max_processes --max-args=1 clang -c

clang *.o -o binary

Download parallel_compile.v1.sh


compile the files of a multi-file C program in parallel use create_1001_file_C_program.sh to create suitable test data
find's -print0 option terminates pathnames with a '\0' xargs's --null option expects '\0' terminated input as '\0' can not appear in file names this can handle any filename
on Linux getconf will tell us how many cores the machine has if getconf assume 8
max_processes=$(getconf _NPROCESSORS_ONLN 2>/dev/null) ||
    max_processes=8

find "$@" -print0|
xargs --max-procs=$max_processes --max-args=1  --null clang -c

clang *.o -o binary

Download parallel_compile.v2.sh


compile the files of a muti-file C program in parallel use create_1001_file_C_program.sh to create suitable test data
parallel clang -c '{}' ::: "$@"

clang *.o -o binary

Download parallel_compile.v3.sh


print print numbers < 1000

Rewritten to use bash arithmetic extension (())
This makes the program more readable but less portable.
is_prime() {
    local n i
    n=$1
    i=2
    while ((i < n))
    do
        if ((n % i == 0))
        then
            return 1
        fi
        i=$((i + 1))
    done
    return 0
}

i=0
while ((i < 1000))
do
    is_prime $i && echo $i
    i=$((i + 1))
done

Download bash_arithmetic.sh

Perl Intro
compute Pythagoras' Theorem
print "Enter x: ";
$x = <STDIN>;
chomp $x;
print "Enter y: ";
$y = <STDIN>;
chomp $y;
$pythagoras = sqrt $x * $x + $y * $y;
print "Square root of $x squared + $y squared is $pythagoras\n";

Download pythagoras.pl


Read numbers until end of input (or a non-number) is reached then print the sum of the numbers
$sum = 0;
while ($line = <STDIN>) {
    $line =~ s/^\s*//; # remove leading white space
    $line =~ s/\s*$//; # remove leading trailing white space
    # Test if string looks like an integer or real (scientific notation not handled!)
    if ($line !~ /^\d[.\d]*$/) {
        last;
    }
    $sum += $line;
}
print "Sum of the numbers is $sum\n";

Download sum_stdin.pl


Simple example reading a line of input and examining characters
printf "Enter some input: ";
$line = <STDIN>;

if (!defined $line) {
    die "$0: could not read any characters\n";
}

chomp $line;
$n_chars = length $line;
print "That line contained $n_chars characters\n";

if ($n_chars > 0) {
    $first_char = substr($line, 0, 1);
    $last_char = substr($line, $n_chars - 1, 1);
    print "The first character was '$first_char'\n";
    print "The last character was '$last_char'\n";
}

Download line_chars.pl



Reads lines of input until end-of-input
Print snap! if two consecutive lines are identical
print "Enter line: ";
$last_line = <STDIN>;
print "Enter line: ";
while ($line = <STDIN>) {
    if ($line eq $last_line) {
        print "Snap!\n";
    }
    $last_line = $line;
    print "Enter line: ";
}

Download snap_consecutive.pl

create a string of size 2^n by concatenation
die "Usage: $0 <n>\n" if @ARGV != 1;
$n = 0;
$string = '@';
while ($n  < $ARGV[0]) {
    $string = "$string$string";
    $n++;
}
$size = length $string;
printf "String of 2^%d = %d characters created\n", $n, $size;

Download exponential_concatenation.pl

Perl Arrays

Perl implementation of /bin/echo always writes a trailing space
foreach $arg (@ARGV) {
    print $arg, " ";
}
print "\n";

Download echo.0.pl


Perl implementation of /bin/echo
print "@ARGV\n";

Download echo.1.pl


Perl implementation of /bin/echo
print join(" ", @ARGV), "\n";

Download echo.2.pl

sum integers supplied as command line arguments no check that aguments are numeric
$sum = 0;
foreach $arg (@ARGV) {
    $sum += $arg;
}
print "Sum of the numbers is $sum\n";

Download sum_arguments.pl


while (1) {
    print "Enter array index: ";
    $n = <STDIN>;
    if (!$n) {
        last;
    }
    chomp $n;
    $a[$n] = 42;
    print "Array element $n now contains $a[$n]\n";
    printf "Array size is now %d\n", $#a+1;
}

Download array_growth_demo.pl


Count the number of lines on standard input.
$line_count = 0;
while (1) {
    $line = <STDIN>;
    last if !$line;
    $line_count++;
}
print "$line_count lines\n";

Download line_count.0.pl


Count the number of lines on standard input slightly more concise
$line_count = 0;
while (<STDIN>) {
    $line_count++;
}
print "$line_count lines\n";

Download line_count.1.pl


Count the number of lines on standard input using a backwards while to be really concise
$line_count = 0;
$line_count++ while <STDIN>;
print "$line_count lines\n";

Download line_count.2.pl


Count the number of lines on standard input. read the input into an array and use the array size.
@lines = <STDIN>;
print $#lines+1, " lines\n";

Download line_count.3.pl


Count the number of lines on standard input.
Assignment to () forces a list context.
Hence all lines of input are read.
The special variable $. contains the current line number
() = <STDIN>;
print "$. lines\n";

Download line_count.4.pl


Simple cp implementation using line by line I/O relying on the default variable $_
die "Usage: $0 <infile> <outfile>\n" if @ARGV != 2;

$infile = shift @ARGV;
$outfile = shift @ARGV;

open my $in, '<', $infile or die "Cannot open $infile: $!";
open my $out, '>', $outfile or die "Cannot open $outfile: $!";

# loop could also be written in one line:
# print OUT while <IN>;

while (<$in>) {
    print $out;
}

close $in;
close $out;
exit 0;

Download cp.1.pl


Simple cp implementation reading entire file into array note that <> returns an array of lines in a list context (in a scalar context it returns a single line)
die "Usage: $0 <infile> <outfile>\n" if @ARGV != 2;

$infile = shift @ARGV;
$outfile = shift @ARGV;

open my $in, '<', $infile or die "Cannot open $infile: $!";
@lines = <$in>;
close $in;

open my $out, '>', $outfile or die "Cannot open $outfile: $!";
print $out @lines;
close $out;

exit 0;

Download cp.2.pl



Reads lines of input until end-of-input
Print snap! if a line has been seen previously
while (1) {
    print "Enter line: ";
    $line = <STDIN>;

    if (!defined $line) {
        last;
    }

    if ($seen{$line}) {
        print "Snap!\n";
    }

    $seen{$line}++;
}

Download snap_memory.0.pl


More concise version of snap_memory.0.pl
while (1) {
    print "Enter line: ";
    $line = <STDIN>;
    last if !defined $line;
    print "Snap!\n" if $seen{$line};
    $seen{$line} = 1;
}

Download snap_memory.1.pl

Perl Regex
count how many people enrolled in each course
open my $f, '<', "course_codes" or die "$0: can not open course_codes: $!";
while ($line = <$f>) {
    chomp $line;
    $line =~ /([^ ]+) (.+)/ or die "$0: bad line format '$line'";
    $course_names{$1} = $2;
}
close $f;

while ($course = <>) {
    chomp $course;
    $course =~ s/\|.*//;
    $count{$course}++;
}

foreach $course (sort keys %count) {
    print "$course_names{$course} has $count{$course} students enrolled\n";
}

Download count_enrollments.pl

run as count_first_names.pl enrollments count how many people enrolled have each first name
while ($line = <>) {
    @fields = split /\|/, $line;
    $student_number = $fields[1];
    next if $already_counted{$student_number};
    $already_counted{$student_number} = 1;
    $full_name = $fields[2];
    $full_name =~ /.*,\s+(\S+)/ or next;
    $first_name = $1;
    $fn{$first_name}++;
}

foreach $first_name (sort keys %fn) {
    printf "There are %2d people with the first name $first_name\n", $fn{$first_name};
}

Download count_first_names.pl

run as duplicate_first_names.pl enrollments
Report cases where there are multiple people of the same same first name enrolled in a course
while ($line = <>) {
    @fields = split /\|/, $line;
    $course = $fields[0];
    $full_name = $fields[2];
    $full_name =~ /.*,\s+(\S+)/ or next;
    $first_name = $1;
    $cfn{$course}{$first_name}++;
}

foreach $course (sort keys %cfn) {
    foreach $first_name (sort keys %{$cfn{$course}}) {
        next if $cfn{$course}{$first_name} < 2;
        printf "In $course there are %d people with the first name $first_name\n", $cfn{$course}{$first_name};
    }
}

Download duplicate_first_names.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod
modified text is written to a temporary file
foreach $filename (@ARGV) {

    $tmp_filename = "$filename.new";
    die "$0: $tmp_filename already exists" if -e "$tmp_filename";

    open my $f, '<', $filename or
        die "$0: Can not open $filename: $!";
    open my $g, '>', $tmp_filename or
        die "$0: Can not open $tmp_filename : $!";
    while ($line = <$f>) {
        $line =~ s/Herm[io]+ne/Zaphod/g;
        $line =~ s/Harry/Hermione/g;
        $line =~ s/Zaphod/Harry/g;
        print $g $line;
    }
    close $f;
    close $g;

    rename "$tmp_filename", $filename or
        die "$0: Can not rename file";
}

Download gender_reversal.0.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod
modified text is stored in array then file over-written
foreach $filename (@ARGV) {
    open my $f, '<', $filename or
        die "$0: Can not open $filename: $!";
    $line_count = 0;
    while ($line = <$f>) {
        $line =~ s/Herm[io]+ne/Zaphod/g;
        $line =~ s/Harry/Hermione/g;
        $line =~ s/Zaphod/Harry/g;
        $new_lines[$line_count++] = $line;
    }
    close $f;
    open my $g, '>', ">$filename"
        or die "$0: Can not open $filename : $!";
    print $g @new_lines;
    close $g;
}

Download gender_reversal.1.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod
modified text is stored in array then file over-written
foreach $filename (@ARGV) {
    open my $f, '<', $filename or
        die "$0: Can not open $filename: $!";
    @lines = <$f>;
    close $f;

    # note loop variable $line is aliased to array elements
    # changes to it change the corresponding array element
    foreach $line (@lines) {
        $line =~ s/Herm[io]+ne/Zaphod/g;
        $line =~ s/Harry/Hermione/g;
        $line =~ s/Zaphod/Harry/g;
    }

    open my $g, '>', ">$filename" or
        die "$0: Can not open $filename : $!";
    print $g @lines;
    close $g;
}

Download gender_reversal.2.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod
modified text is stored in array then file over-written

See http://www.perlmonks.org/?node_id=1952 for alternative way to read a file into a string
foreach $filename (@ARGV) {
    open my $f, '<', $filename or
        die "$0: Can not open $filename: $!";
    while ($line = <$f>) {
        $novel .= $line;
    }
    close $f;

    $novel =~ s/Herm[io]+ne/Zaphod/g;
    $novel =~ s/Harry/Hermione/g;
    $novel =~ s/Zaphod/Harry/g;

    open my $g, '>', "$filename" or
        die "$0: Can not open $filename : $!";
    print $g $novel;
    close $g;
}

Download gender_reversal.3.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod

The unix filter-like behaviour of <> is used to read files
Perl's -i option replaces file with output from script
while ($line = <>) {
    chomp $line;
    $line =~ s/Herm[io]+ne/Zaphod/g;
    $line =~ s/Harry/Hermione/g;
    $line =~ s/Zaphod/Harry/g;
    print $line;
}

Download gender_reversal.4.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod

The unix filter-like behaviour of <> is used to read files
Perl's -i option replaces file with output from script
Perl's default variable $_ is used
while (<>) {
    s/Herm[io]+ne/Zaphod/g;
    s/Harry/Hermione/g;
    s/Zaphod/Harry/g;
}

Download gender_reversal.5.pl



For each file given as argument replace occurrences of Hermione with Harry and vice-versa, relies on file not containing Zaphod

The unix filter-like behaviour of <> is used to read files
Perl's -i option replaces file with output from script
Perl's -p option is used to produce unix filter-like behaviour.
Perl's default variable $_ is used
s/Herm[io]+ne/Zaphod/g;
s/Harry/Hermione/g;
s/Zaphod/Harry/g;

Download gender_reversal.6.pl


Fetch a web page removing HTML tags and constants (e.g &amp;)
Lines between script or style tags are skipped.
Non-blank lines are printed

There are better ways to fetch web pages (e.g. HTTP::Request::Common)
The regex code below doesn't handle a number of cases. It is often better to use a library to properly parse HTML before processing it.
But beware illegal HTML is common & can break parsers.
foreach $url (@ARGV) {
    open my $f, '-|', "wget -q -O- '$url'" or die;
    while ($line = <$f>) {
        if ($line =~ /^\s*<(script|style)/i) {
            while ($line = <$f>) {
                last if $line =~ /^\s*<\/(script|style)/i;
            }
        } else {
            $line =~ s/&\w+;/ /g;
            $line =~ s/<[^>]*>//g;
            print $line if $line =~ /\S/;
        }
    }
    close $f;
}

Download wget.0.pl


Fetch a web page removing HTML tags and constants
The contents of script or style tags are removed..
Non-blank lines are printed

The regex code below doesn't handle a number of cases. It is often better to use a library to properly parse HTML before processing it.
But beware illegal HTML is common & often causes problems for parsers.
note the use of the s modifier to allow . to match a newline


use LWP::Simple;
foreach $url (@ARGV) {
    $html = get $url;

    # remove script tags including contents
    $html =~ s/<script.*?<\/script>//isg;

    # remove style tags including contents
    $html =~ s/<style.*?<\/style>//isg;

    # remove tags
    $html =~ s/<.*?>//isg;

    # remove blank lines
    $html =~ s/\n\s*\n/\n/ig;

    print $html;
}

Download wget.1.pl



Find the positive integers among input text print their sum and mean

Note regexp to split on non-digits
Note check to handle empty string from split
@input_text_array = <>;
$input_text_array = join "", @input_text_array;

@numbers = split(/\D+/, $input_text_array);
print join(",", @numbers), "\n";

foreach $number (@numbers) {
    if ($number ne '') {
        $total += $number;
        $n++;
    }
}

if (@numbers) {
    printf "$n numbers: total $total mean %s\n", $total/$n;
}

Download find_numbers.0.pl



Find integers (positive and negative) among input text print their sum and mean

Note regexp to match number: -?\d+
Harder to use split here (unlike just positive integers)
@input_text_array = <>;
$input_text_array = join "", @input_text_array;

@numbers = $input_text_array =~ /-?\d+/g;

foreach $number (@numbers) {
    $total += $number;
}

if (@numbers) {
    $n = @numbers;
    printf "$n numbers: total $total mean %s\n", $total/$n;
}

Download find_numbers.1.pl


Print the last number (real or integer) on every line
Note regexp to match number: -?\d+(\.\d+)?
while ($line = <>) {
    if ($line =~ /(-?\d+(\.\d+)?)\D*$/) {
        print "$1\n";
    }
}

Download print_last_number.pl

for each courses specified as arguments print a summary of the other courses taken by students in this course
$enrollment_file = shift @ARGV or die;
$debug = 0;

open my $c, '<', "course_codes" or die "$0: can not open course_codes: $!";
while (<$c>) {
    ($code, $name) = /\s*(\S+)\s+(.*)/ or die "$0: invalid course codes line: $_";
    $course_name{$code} = $name;
    print STDERR "code='$code' -> name='$name'\n" if $debug;
}
close $c;

open my $f, "<$enrollment_file" or die "$0: can not open $enrollment_file: $!";;
while (<$f>) {
    ($course,$zid,$name) = split /\s*\|\s*/;
    push @{$course{$zid}}, $course;
    $name =~ s/(.*), (.*)/$2 $1/;
    $name =~ s/ .* / /;
    $name{$zid} = $name;
}
close $f;

foreach $course (@ARGV) {
    %n_taking = ();
    $n_students = 0;
    foreach $zid (keys %course) {
        @courses = @{$course{$zid}};
        next if !grep(/$course/, @courses);
        foreach $c (@courses) {
            $n_taking{$c}++;
        }
        $n_students++;
    }
    foreach $c (sort {$n_taking{$a} <=> $n_taking{$b}} keys %n_taking) {
        printf "%5.1f%% of %s students take %s %s\n",
            100*$n_taking{$c}/$n_students, $course, $c, $course_name{$c};
    }
}

Download course_statistics.pl

Perl Functions


This shows a bug due to a missing my declaration

There is no my declaration for $i in is_prime
So is_prime changes $i outside the function and breaks the while loop calling the function
sub is_prime {
    my ($n) = @_;
    $i = 2;
    while ($i < $n) {
        return 0 if $n % $i == 0;
        $i++;
    }
    return 1;
}

$i = 0;
while ($i < 1000) {
    print "$i\n" if is_prime($i);
    $i++;
}

Download my_declaration_bug.pl

3 different ways to sum a list - illustrating various aspects of Perl
simple for loop
sub sum_list0 {
    my (@list) = @_;
    my $total = 0;
    foreach $element (@list) {
       $total += $element;
    }
    return $total;
}

# recursive
sub sum_list1 {
    my (@list) = @_;
    return 0 if !@list;
    return $list[0] + sum_list1(@list[1..$#list]);
}

# join+eval - interesting but not recommended
sub sum_list2 {
    my (@list) = @_;
    return eval(join("+", @list))
}

print sum_list0(1..10), " ", sum_list1(1..10), " ", sum_list2(1..10),  "\n";

Download sum_list.pl


implementations of Perl's split & join
sub my_join {
    my ($separator, @list) = @_;

    return "" if !@list;

    my $string = shift @list;
    foreach $thing (@list) {
        $string .= $separator . $thing;
    }

    return $string;
}

sub my_split1 {
    my ($regexp, $string) = @_;
    my @list = ();

    while ($string =~ /(.*)$regexp(.*)/) {
        unshift @list, $2;
        $string = $1;
    }
    unshift @list, $string if $string ne "";

    return @list;
}

sub my_split2 {
    my ($regexp, $string) = @_;

    my @list = ();
    while ($string =~ s/(.*?)$regexp//) {
        push @list, $1;
    }
    push @list, $string if $string ne "";

    return @list;
}

$s = my_join("+", 1..5);

# prints 1+2+3+4+5 = 15
print "$s = ", eval $s, "\n";

# prints 2 4 8 16
@a = my_split1(",", "2,4,8,16");
print "@a\n";

# prints 2 4 8 16
@a = my_split2(",", "2,4,8,16");
print "@a\n";

Download split_join.pl


calculate Dot Product https://en.wikipedia.org/wiki/Dot_product of 2 lists - list are assumed to be the same length
broken version of dot_produce
Perl functions arguments are passed in a single array
A function can't determine how the list of arguments was formed
sub dot_product {
    my (@a, @b) = @_;   # BROKEN

    print "\@a = @a\n"; # all elements of @_ will be in @a
    print "\@b = @b\n"; # @b will be empty

    my $sum;
    foreach $i (0..$#a) {
        $sum += $a[$i] * $b[$i];
    }

    return $sum;
}

@x = (5..9);
@y = (11..15);

$dp = dot_product @x, @y;

print "(@x) . (@y) = $dp\n";

Download dot_product.0.pl


calculate Dot Product https://en.wikipedia.org/wiki/Dot_product of 2 lists - list are assumed to be the same length
this version of dot_product divides the single list of arguments into two lists this works in this case, but is not a general solution
sub dot_product {
    my $n = @_/2;
    my @a = @_[0 .. ($n-1)];
    my @b = @_[$n .. $#_];
    print "n=$n \@a=@a \@b=@b\n";
    my $sum;
    foreach $i (0..$#a) {
        $sum += $a[$i] * $b[$i];
    }

    return $sum;
}

@x = (5..9);
@y = (11..15);

$dp = dot_product @x, @y;

print "(@x) . (@y) = $dp\n";

Download dot_product.1.pl


calculate Dot Product https://en.wikipedia.org/wiki/Dot_product of 2 lists - list are assumed to be the same length
this version of dot_product expects two array references
sub dot_product {
    my ($aref, $bref) = @_;

    my $sum;
    foreach $i (0..$#$aref) {
        $sum += $aref->[$i] * $bref->[$i];
    }

    return $sum;
}

@x = (5..9);
@y = (11..15);

$dp = dot_product \@x, \@y;

print "(@x) . (@y) = $dp\n";

Download dot_product.2.pl

print a HTML times table

Note html_times_table has 6 parameters calls to the function are hard to read and its easy to introduce errors
sub html_times_table {
    my ($min_x, $max_x, $min_y, $max_y, $bgcolor, $border) = @_;

    my $html = "<table border=$border bgcolor=$bgcolor>\n";

    foreach $y ($min_y..$max_y) {
        $html .= "<tr>";
        foreach $x ($min_x..$max_x) {
            $html .= sprintf "<td align=right>%s</td>", $x * $y;
        }
        $html .=  "</tr>\n";
    }

    $html .=  "</table>\n";

    return $html;
}

# what do each of these parameters do?
print html_times_table(1, 12, 1, 12, "pink", 1);

Download html_times_table0.pl

print a HTML times table

Note use of a hash to pass named parameters
sub html_times_table {
    my %parameters = @_;

    my $html = "<table border=$parameters{border}";
    $html .= "bgcolor=$parameters{bgcolor}>\n";

    foreach $y ($parameters{min_y}..$parameters{max_y}) {
        $html .= "<tr>";
        foreach $x ($parameters{min_x}..$parameters{max_y}) {
            $html .= sprintf "<td align=right>%s</td>", $x * $y;
        }
        $html .=  "</tr>\n";
    }

    $html .=  "</table>\n";

    return $html;
}

# easy to understand what each parameter does
print html_times_table(bgcolor => 'pink', min_y => 1, max_y => 12,
                       border => 1, min_x => 1, max_x => 12);

Download html_times_table1.pl

print a HTML times table

Note use of a hash to pass named parameters combined with a hash to provide default values for parameters
sub html_times_table {
    my %arguments = @_;

    my %defaults = (min_x => 1, max_x => 10, min_y => 1,
                    max_y => 10, bgcolor => 'white', border => 0);

    my %parameters = (%defaults,%arguments);

    my $html = "<table border=$parameters{border}";
    $html .= "bgcolor=$parameters{bgcolor}>\n";

    foreach $y ($parameters{min_y}..$parameters{max_y}) {
        $html .= "<tr>";
        foreach $x ($parameters{min_x}..$parameters{max_y}) {
            $html .= sprintf "<td align=right>%s</td>", $x * $y;
        }
        $html .=  "</tr>\n";
    }

    $html .=  "</table>\n";

    return $html;
}

#  we don't have to supply default values for parameters

print html_times_table(max_y => 12, max_x => 12, bgcolor => 'pink');

Download html_times_table2.pl

implementations of Perl's push
sub my_push1 {
    my ($array_ref,@elements) = @_;

    @$array_ref = (@$array_ref, @elements);

    return $#$array_ref + 1;
}


# same but with prototype
sub my_push2(\@@) {
    my ($array_ref,@elements) = @_;

    @$array_ref = (@$array_ref, @elements);

    return $#$array_ref + 1;
}

sub mypush2 {
    my ($array_ref,@elements) = @_;
    if (@elements) {
        @$array_ref = (@$array_ref, @elements);
    } else {
        @$array_ref = (@$array_ref, $_);
    }
}

@a = (1..5);

# note explicitly passing an array reference \@a
my_push1 \@a, 10..15;

# note prototype allows caused reference to array to be passed
my_push2 @a, 20..25;

# prints 1 2 3 4 5 10 11 12 13 14 15 20 21 22 23 24 25
print "@a\n";

Download push.pl


calculate Dot Product https://en.wikipedia.org/wiki/Dot_product of 2 lists - list are assumed to be the same length
this version of dot_product expects two array references and has a function_prototype specifying this which changes how dot_product can be called
sub dot_product(\@\@) {
    my ($aref, $bref) = @_;

    my $sum;
    foreach $i (0..$#$aref) {
        $sum += $aref->[$i] * $bref->[$i];
    }

    return $sum;
}

@x = (5..9);
@y = (11..15);

# due to the function prototype, implicitly a reference will be passed to @a and @b

$dp = dot_product @x, @y;

print "(@x) . (@y) = $dp\n";

Download dot_product.3.pl


simple example illustrating use of sorting comparison function note use of <=>
sub random_date {
    my $day = 1 + rand 28;
    my $month = 1 + rand 12;
    my $year = 2000 +rand 20;
    return sprintf "%02d/%02d/%04d", $day, $month, $year;
}

sub compare_date {
    my ($day1, $month1, $year1) = split /\D+/, $a;
    my ($day2, $month2, $year2) = split /\D+/, $b;
    return $year1 <=> $year2 ||
           $month1 <=> $month2 ||
           $day1 <=> $day2;
}

push @random_dates, random_date() foreach 1..5;
print "random_dates=@random_dates\n";

@sorted_dates = sort compare_date @random_dates;
print "sorted dates=@sorted_dates\n";

Download sort_dates.pl



Simple example of sorting a list based on the values in a hash.
This is a common programming pattern in Perl.
%days = (Sunday => 0, Monday => 1, Tuesday => 2, Wednesday => 3,
         Thursday => 4, Friday => 5, Saturday => 6);

sub random_day_of_week {
    my @days = keys %days;
    return $days[rand @days];
}

sub compare_day {
    return $days{$a} <=> $days{$b};
}

push @random_days, random_day_of_week() foreach 1..5;
print "random days = @random_days\n";
@sorted_days = sort compare_day @random_days;
print "sorted days = @sorted_days\n";

Download sort_days.pl



Simple example of sorting a list based on the values in a hash.
This is very common pattern in Perl.
modified version illustrating Perl's quote word operator and a hash slice

The quote word operator is a convenient way to create a list of words
@days = qw/Sunday Monday Tuesday Wednesday Thursday Friday Saturday/;

# A Hash slice allows assignment of multiple values to a hash
@days{@days} = (0..6);

sub random_day_of_week {
    return $days[rand @days];
}

sub compare_day {
    return $days{$a} <=> $days{$b};
}

push @random_days, random_day_of_week() foreach 1..5;
print "random days = @random_days\n";

@sorted_days = sort compare_day @random_days;
print "sorted days = @sorted_days\n";

Download sort_days.1.pl


8 different ways to print the odd numbers in a list - illustrating various aspects of Perl
simple for loop
sub print_odd0 {
    my (@list) = @_;

    foreach $element (@list) {
        print "$element\n" if $element % 2;
    }
}

# simple for loop using index
sub print_odd1 {
    my (@list) = @_;

    foreach $i (0..$#list) {
        print "$list[$i]\n" if $list[$i] % 2;
    }
}

# set $_ in turn to each item in list
# evaluate supplied expression
# print item if the expression evaluates to true
sub print_list0 {
    my ($select_expression, @list) = @_;
    foreach $_ (@list) {
        print "$_\n" if &$select_expression;
    }
}

# more concise version of print_list0
sub print_list1 {
   &{$_[0]} && print "$_\n" foreach @_[1..$#_];
}


# set $_ in turn to each item in list
# evaluate supplied expression
# return a list of items for which the expression evaluated to true
sub my_grep0 {
    my $select_expression = $_[0];
    my @matching_elements;
    foreach $_ (@_[1..$#_]) {
        push @matching_elements, $_ if &$select_expression;
    }
    return @matching_elements;
}


# more concise version of my_grep0
sub my_grep1 {
    my $select_expression = shift;
    my @matching_elements;
    &$select_expression && push @matching_elements, $_ foreach @_;
    return @matching_elements;
}

# calling helper function which returns
# list items selected by an expression
sub print_odd4 {
    my @odd = my_grep0 sub {$_ % 2}, @_;
    foreach $x (@odd) {
        print "$x\n";
    }
}

sub odd {
    return $_[0] % 2 == 1;
}

@numbers = (1..10);

# all 8 statements print the numbers 1,3,5,7,9 one per line

print_odd0(@numbers);

print_odd1(@numbers);

print_list0(sub {$_ % 2}, @numbers);

print_list1(sub {$_ % 2}, @numbers);

print_odd4(@numbers);

my_grep1 sub {$_ % 2 && print "$_\n"}, @numbers;

# using built-in grep and combining print
grep {$_ % 2 && print "$_\n"} @numbers;

# using built-in grep and join
print join("\n", grep {$_ % 2} @numbers), "\n";

Download print_odd.pl

rename specified files using specified Perl code
For each file the code is executed with $_ set to the filename and the file is renamed to the value of $_ after the execution. /usr/bin/rename provides this functionality
die "Usage: $0 <perl> [files]\n" if !@ARGV;
$perl_code = shift @ARGV;
foreach $filename (@ARGV) {

    $_ = $filename;
    eval $perl_code;
    die "$0: $?" if $?; # eval leaves any error message in $?
    $new_filename = $_;

    next if $filename eq $new_filename;

    die "$0: $new_filename exists already\n" if -e $new_filename;

    rename $filename, $new_filename or
        die "$0: rename '$filename' -> '$new_filename' failed: $!\n";
}

Download rename.pl


@list = randomize_list(1..20);
print "@list\n";
@sorted_list0 = sort {$a <=> $b} @list;
print "@sorted_list0\n";
@sorted_list1 = quicksort0(@list);
print "@sorted_list1\n";
@sorted_list2 = quicksort1(sub {$a <=> $b}, @list);
print "@sorted_list2\n";

sub quicksort0 {
    return @_ if @_ < 2;
    my ($pivot,@numbers) = @_;
    my @less = grep {$_ < $pivot} @numbers;
    my @more = grep {$_ >= $pivot} @numbers;
    my @sorted_less = quicksort0(@less);
    my @sorted_more = quicksort0(@more);
    return (@sorted_less, $pivot, @sorted_more);
}


sub quicksort1 {
    my ($compare) = shift @_;
    return @_ if @_ < 2;
    my ($pivot, @input) = @_;
    my (@less, @more);
    partition1($compare, $pivot, \@input, \@less, \@more);
    my @sorted_less = quicksort1($compare, @less);
    my @sorted_more = quicksort1($compare, @more);
    my @r = (@sorted_less, $pivot, @sorted_more);
    return (@sorted_less, $pivot, @sorted_more);
}

sub partition1 {
    my ($compare, $pivot, $input, $smaller, $larger) = @_;
    foreach $x (@$input) {
        our $a = $x;
        our $b = $pivot;
        if (&$compare  < 0) {
            push @$smaller, $x;
        } else {
            push @$larger, $x;
        }
    }
}

sub randomize_list {
    my @newlist;
    while (@_) {
        my $random_index = rand @_;
        my $r = splice @_,  $random_index, 1;
        push @newlist, $r;
    }
    return @newlist;
}

Download quicksort0.pl


sub quicksort0(@);
sub quicksort1(&@);
sub partition1(&$\@\@\@);
sub randomize_list(@);

@list = randomize_list 1..20;
print "@list\n";
@sorted_list0 = sort {$a <=> $b} @list;
print "@sorted_list0\n";
@sorted_list1 = quicksort0 @list;
print "@sorted_list1\n";
@sorted_list2 = quicksort1 {$a <=> $b} @list;
print "@sorted_list2\n";

sub quicksort0(@) {
    return @_ if @_ < 2;
    my ($pivot,@numbers) = @_;
    my @less = grep {$_ < $pivot} @numbers;
    my @more = grep {$_ >= $pivot} @numbers;
    my @sorted_less = quicksort0 @less;
    my @sorted_more = quicksort0 @more;
    return (@sorted_less, $pivot, @sorted_more);
}


sub quicksort1(&@) {
    my ($compare) = shift @_;
    return @_ if @_ < 2;
    my ($pivot, @input) = @_;
    my (@less, @more);
    partition1 \&$compare, $pivot, @input, @less, @more;
    my @sorted_less = quicksort1 \&$compare, @less;
    my @sorted_more = quicksort1 \&$compare, @more;
    my @r = (@sorted_less, $pivot, @sorted_more);
    return (@sorted_less, $pivot, @sorted_more);
}

sub partition1(&$\@\@\@) {
    my ($compare, $pivot, $input, $smaller, $larger) = @_;
    foreach $x (@$input) {
        our $a = $x;
        our $b = $pivot;
        if (&$compare  < 0) {
            push @$smaller, $x;
        } else {
            push @$larger, $x;
        }
    }
}

sub randomize_list(@) {
    my @newlist;
    while (@_) {
        my $random_index = rand @_;
        my $r = splice @_,  $random_index, 1;
        push @newlist, $r;
    }
    return @newlist;
}

Download quicksort1.pl

Perl Modules
package Example_Module;
# written by andrewt@cse.unsw.edu.au for COMP2041 
# 
# Definition of a simple Perl module.
#
# List::Util provides the functions below and more

use base 'Exporter';
our @EXPORT = qw/sum min max minstr maxstr/;
use List::Util qw/reduce/;


sub sum {
	return reduce {$a + $b} @_;
}

sub min {
	return reduce {$a < $b ? $a : $b} @_;
}

sub max {
	return reduce {$a > $b ? $a : $b} @_;
}

sub minstr {
	return reduce {$a lt $b ? $a : $b} @_;
}

sub maxstr {
	return reduce {$a gt $b ? $a : $b} @_;
}

1; # must return true to indicate loading succceeded

Download Example_Module.pm

Performance

 Written in C for "speed" but slow on large inputs:

% gcc -O3 -o word_frequency0 word_frequency0.c % time word_frequency0 <WarAndPeace.txt >/dev/null real 0m52.726s user 0m52.643s sys 0m0.020s

 Profiling with gprof revels get function is problem

gcc -p -g word_frequency0.c -o word_frequency0_profile head -10000 WarAndPeace.txt|word_frequency0_profile >/dev/null % gprof word_frequency0_profile % cumulative self self total time seconds seconds calls ms/call ms/call name 88.90 0.79 0.79 88335 0.01 0.01 get 7.88 0.86 0.07 7531 0.01 0.01 put 2.25 0.88 0.02 80805 0.00 0.00 get_word 1.13 0.89 0.01 1 10.02 823.90 read_words 0.00 0.89 0.00 2 0.00 0.00 size 0.00 0.89 0.00 1 0.00 0.00 create_map 0.00 0.89 0.00 1 0.00 0.00 keys 0.00 0.89 0.00 1 0.00 0.00 sort_words ....

#include <stdlib.h>
#include "time.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/*
 * returns the next word from the streeam
 * a word is a non-zero length sequence of
 * alphabetic characters
 *
 * NULL is returned if there are no more words to be read
 */
char *
get_word(FILE *stream) {
    int i, c;
    char *w;
    static char *buffer = NULL;
    static int buffer_length = 0;

    if (buffer == NULL) {
        buffer_length = 32;
        buffer = malloc(buffer_length*sizeof (char));
        if (buffer == NULL) {
            fprintf(stderr, "out of memory\n");
            exit(1);
        }
    }

    i = 0;
    while ((c = fgetc(stream)) != EOF) {
        if (!isalpha(c) && i == 0)
            continue;
        if (!isalpha(c))
            break;
        if (i >= buffer_length) {
            buffer_length += 16;
            buffer = realloc(buffer, buffer_length*sizeof (char));
            if (buffer == NULL) {
                fprintf(stderr, "out of memory\n");
                exit(1);
            }
        }
        buffer[i++] = c;
    }

    if (i == 0)
        return NULL;

    buffer[i] = '\0';

    w = malloc(strlen(buffer) + 1);
    if (w == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    strcpy(w, buffer);
    return w;
}

typedef struct map  map;

struct map {
       int              size;
       struct map_node  *list;
};

struct map_node {
       char             *key;
       void             *value;
       struct map_node  *next;
};


map *create_map() {
    struct map *m;
    if ((m = malloc(sizeof *m)) == NULL) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    m->size = 0;
    m->list = NULL;
    return m;
}

void *get(map *m, char *key) {
    struct map_node *v;
    for (v = m->list; v != NULL; v = v->next) {
        if (strcmp(key, v->key) == 0) {
            return v->value;
        }
    }
    return NULL;
}

void put(map *m, char *key, void *value) {
    struct map_node *v;
    for (v = m->list; v != NULL; v = v->next) {
        if (strcmp(key, v->key) == 0) {
            v->value = value;
            return;
        }
    }

    if ((v = malloc(sizeof *v)) == NULL) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    v->key = key;
    v->value = value;
    v->next = m->list;
    m->list = v;
    m->size++;
}

int size(map *m) {
    return m->size;
}

char **keys(map *m) {
    struct map_node *v;
    int  i, n_keys = size(m);
    char **key_array;

    if ((key_array = malloc(n_keys*sizeof (char **))) == NULL) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    for (v = m->list, i=0; v != NULL; v = v->next,i++)
        key_array[i] = v->key;
    return key_array;
}

static void free_map_nodes(struct map_node  *list) {
    if (list == NULL)
        return;
    free_map_nodes(list->next);
    free(list);
}

void free_map(map *m) {
    free_map_nodes(m->list);
    free(m);
}
/*
 * One word_count struct is malloc'ed for each
 * distinct word read
 */
struct word_count {
    int count;
};

/*
 * read the words from a stream
 * associate a word_count struct with
 * each new word
 *
 * increment the count field each time the
 * word is seen
 */
map *read_words(FILE *stream) {
    char *word;
    struct word_count *w;
    map *m;

    m = create_map();
    while (1) {
        word = get_word(stdin);
        if (word == NULL)
            return m;
        w = get(m, word);
        if (w != NULL) {
            w->count++;
            free(word);
            continue;
        }
        if ((w = malloc(sizeof *w)) == NULL) {
            fprintf(stderr, "Out of memory\n");
            exit(1);
        }
        w->count = 1;
        put(m, word, w);
    }
}

void sort_words(char **sequence, int length) {
    int i, j;
    char *pivotValue;
    char *temp;

    if (length <= 1)
        return;

    /* start from left and right ends */

    i = 0;
    j = length - 1;

    /* use middle value as pivot */

    pivotValue = sequence[length/2];
    while (i < j) {

        /* Find two out-of-place elements */

        while (strcmp(sequence[i], pivotValue) < 0)
            i++;
        while (strcmp(sequence[j], pivotValue) > 0)
           j--;
        /* and swap them over */

        if (i <= j) {
            temp = sequence[i];
            sequence[i] = sequence[j];
            sequence[j] = temp;
            i++;
            j--;
        }
    }
    sort_words(sequence, j + 1);
    sort_words(sequence+i, length - i);
}

int main(void) {
    int i, n_unique_words;
    char **key_array;
    map *m;

    m = read_words(stdin);

    key_array = (char **)keys(m);

    n_unique_words = size(m);

    sort_words(key_array, n_unique_words);

    for (i = 0; i < n_unique_words; i++) {
        struct word_count *w;
        w = (struct word_count *)get(m, key_array[i]);
        printf("%5d %s\n", w->count, key_array[i]);
    }

    return 0;
}

Download word_frequency0.c


 word_frequency0.c  with linked list replaced by binary tree - much faster:

% gcc -O3 word_frequency1.c -o word_frequency1 % time word_frequency1 <WarAndPeace.txt >/dev/null real 0m0.277s user 0m0.268s sys 0m0.008s

#include <stdlib.h>
#include "time.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/*
 * returns the next word from the streeam
 * a word is a non-zero length sequence of
 * alphabetic characters
 *
 * NULL is returned if there are no more words to be read
 */
char *get_word(FILE *stream) {
    int i, c;
    char *w;
    static char *buffer = NULL;
    static int buffer_length = 0;

    if (buffer == NULL) {
        buffer_length = 32;
        buffer = malloc(buffer_length*sizeof (char));
        if (buffer == NULL) {
            fprintf(stderr, "out of memory\n");
            exit(1);
        }
    }

    i = 0;
    while ((c = fgetc(stream)) != EOF) {
        if (!isalpha(c) && i == 0)
            continue;
        if (!isalpha(c))
            break;
        if (i >= buffer_length) {
            buffer_length += 16;
            buffer = realloc(buffer, buffer_length*sizeof (char));
            if (buffer == NULL) {
                fprintf(stderr, "out of memory\n");
                exit(1);
            }
        }
        buffer[i++] = c;
    }

    if (i == 0)
        return NULL;

    buffer[i] = '\0';

    w = malloc(strlen(buffer) + 1);
    if (w == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    strcpy(w, buffer);
    return w;
}

typedef struct map  map;

struct map {
       int              size;
       struct map_tnode *tree;
};

struct map_tnode {
       char             *key;
       void             *value;
       struct map_tnode *smaller;
       struct map_tnode *larger;
};

map *create_map() {
    struct map *m;
    if ((m = malloc(sizeof *m)) == NULL) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    m->size = 0;
    m->tree = NULL;
    return m;
}

/*
 * Return the value associated with key in map m.
 */
static void *get_tree(struct map_tnode *t, char *key) {
    int compare;
    if (t == NULL)
        return NULL;
    compare = strcmp(key, t->key);
    if (compare == 0)
        return t->value;
    else if (compare < 0)
        return get_tree(t->smaller, key);
    else
        return get_tree(t->larger, key);
}

void *get(map *m, char *key) {
    return  get_tree(m->tree, key);
}

/*
 * Return the value associated with key in map m.
 */
struct map_tnode *put_tree(struct map_tnode *t, char *key, void *value, map *m) {
    int compare;
    if (t == NULL) {
        if ((t = malloc(sizeof *t)) == NULL) {
            fprintf(stderr, "Out of memory\n");
            exit(1);
        }
        t->key = key;
        t->value = value;
        t->smaller = NULL;
        t->larger = NULL;
        m->size++;
        return t;
    }

    compare = strcmp(key, t->key);
    if (compare == 0) {
        t->value = value;
    } else if (compare < 0)
        t->smaller = put_tree(t->smaller, key, value, m);
    else
        t->larger = put_tree(t->larger, key, value, m);
    return t;
}

void put(map *m, char *key, void *value) {
    m->tree = put_tree(m->tree, key, value, m);
}

int size(map *m) {
    return m->size;
}

static int tree_to_array(struct map_tnode *t, char **key_array, int index) {
    if (t == NULL)
        return index;
    index = tree_to_array(t->smaller, key_array, index);
    key_array[index] = t->key;
    return tree_to_array(t->larger, key_array, index + 1);
}

char **keys(map *m) {
    char **key_array;

    if ((key_array = malloc(size(m)*sizeof (char **))) == NULL) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    tree_to_array(m->tree, key_array, 0);
    return key_array;
}

static void free_tnodes(struct map_tnode  *t) {
    if (t == NULL)
        return;
    free_tnodes(t->smaller);
    free_tnodes(t->larger);
    free(t);
}

void free_map(map *m) {
    free_tnodes(m->tree);
    free(m);
}

/*
 * One word_count struct is malloc'ed for each
 * distinct word read
 */
struct word_count {
    int count;
};

/*
 * read the words from a stream
 * associate a word_count struct with
 * each new word
 *
 * increment the count field each time the
 * word is seen
 */
map *read_words(FILE *stream) {
    char *word;
    struct word_count *w;
    map *m;

    m = create_map();
    while (1) {
        word = get_word(stdin);
        if (word == NULL)
            return m;
        w = get(m, word);
        if (w != NULL) {
            w->count++;
            free(word);
            continue;
        }
        if ((w = malloc(sizeof *w)) == NULL) {
            fprintf(stderr, "Out of memory\n");
            exit(1);
        }
        w->count = 1;
        put(m, word, w);
    }
}

void sort_words(char **sequence, int length) {
    int i, j;
    char *pivotValue;
    char *temp;

    if (length <= 1)
        return;

    /* start from left and right ends */

    i = 0;
    j = length - 1;

    /* use middle value as pivot */

    pivotValue = sequence[length/2];
    while (i < j) {

        /* Find two out-of-place elements */

        while (strcmp(sequence[i], pivotValue) < 0)
            i++;
        while (strcmp(sequence[j], pivotValue) > 0)
           j--;
        /* and swap them over */

        if (i <= j) {
            temp = sequence[i];
            sequence[i] = sequence[j];
            sequence[j] = temp;
            i++;
            j--;
        }
    }
    sort_words(sequence, j + 1);
    sort_words(sequence+i, length - i);
}

int main(void) {
    int i, n_unique_words;
    char **key_array;
    map *m;

    m = read_words(stdin);

    key_array = (char **)keys(m);

    n_unique_words = size(m);

    sort_words(key_array, n_unique_words);

    for (i = 0; i < n_unique_words; i++) {
        struct word_count *w;
        w = (struct word_count *)get(m, key_array[i]);
        printf("%5d %s\n", w->count, key_array[i]);
    }

    return 0;
}

Download word_frequency1.c


while ($line = <>) {
    $line =~ tr/A-Z/a-z/;
    foreach $word ($line =~ /[a-z]+/g) {
        $count{$word}++;
    }
}

@words = keys %count;

@sorted_words = sort {$count{$a} <=> $count{$b}} @words;

foreach $word (@sorted_words) {
    printf "%8d %s\n", $count{$word}, $word;
}

Download word_frequency.pl

tr -c a-zA-Z ' '|
tr ' ' '\n'|
tr A-Z a-z|
egrep -v '^$'|
sort|
uniq -c

Download word_frequency.sh

import fileinput,re, collections

count = collections.defaultdict(int)
for line in fileinput.input():
    for word in re.findall(r'\w+', line.lower()):
        count[word] += 1

words = count.keys()

sorted_words = sorted(words,  key=lambda w: count[w])

for word in sorted_words:
    print("%8d %s" % (count[word], word))

Download word_frequency.py

sub fib {
    my ($n) = @_;
    return 1 if $n < 3;
    return fib($n-1) + fib($n-2);
}
printf "fib(%d) = %d\n", $_, fib($_) foreach @ARGV;

Download fib0.pl

#include <stdio.h>
#include <stdlib.h>

int fib(int n) {
    if (n < 3) return 1;
    return fib(n-1) + fib(n-2);
}

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        int n = atoi(argv[i]);
        printf("fib(%d) = %d\n", n, fib(n));
    }
    return 0;
}

Download fib0.c

sub fib {
    my ($n) = @_;
    return 1 if $n < 3;
    return $fib{$n} || ($fib{$n} = fib($n-1) + fib($n-2));
}
printf "fib(%d) = %d\n", $_, fib($_) foreach @ARGV;

Download fib1.pl

use Memoize;
sub fib($);
memoize('fib');
printf "fib(%d) = %d\n", $_, fib($_) foreach @ARGV;
sub fib($) {
    my ($n) = @_;
    return 1 if $n < 3;
    return fib($n-1) + fib($n-2);
}

Download fib2.pl

Make

Simple makefile
game : main.o graphics.o world.o 
	gcc -o game main.o graphics.o world.o

main.o : main.c graphics.h world.h
	gcc -c main.c

graphics.o : graphics.c world.h 
	gcc -c graphics.c

world.o : world.c world.h 
	gcc -c world.c

clean:
	rm -f game main.o graphics.o world.o

Download Makefile.simple



Simple Perl implementation of "make".

It parses makefile rules and stores them in 2 hashes.

Building is done with a recursive function.
$makefile_name = "Makefile";
if (@ARGV >= 2 && $ARGV[0] eq "-f") {
    shift @ARGV;
    $makefile_name = shift @ARGV;
}

parse_makefile($makefile_name);
push @ARGV, $first_target if !@ARGV;
build($_) foreach @ARGV;
exit 0;

sub parse_makefile {
    my ($file) = @_;
    open MAKEFILE, $file or die "Can not open $file: $!";
    while (<MAKEFILE>) {
        my ($target, $dependencies) = /(\S+)\s*:\s*(.*)/ or next;
        $first_target ||= $target;
        $dependencies{$target} = $dependencies;
        while (<MAKEFILE>) {
            last if !/^\t/;
            $build_command{$target} .= $_;
        }
    }
}

sub build {
    my ($target) = @_;
    my $build_command = $build_command{$target};
    die "*** No rule to make target $target\n" if !$build_command && !-e $target;
    return if !$build_command;
    my $target_build_needed = ! -e $target;
    foreach $dependency (split /\s+/, $dependencies{$target}) {
        build($dependency);
        $target_build_needed ||= -M  $target > -M $dependency;
    }
    return if !$target_build_needed;
    print $build_command;
    system $build_command;
}

Download make0.pl


Simple makefile with variables & a comment
CC=gcc-4.9
CFLAGS=-O3 -Wall

game : main.o graphics.o world.o 
	$(CC) $(CFLAGS) -o game main.o graphics.o world.o

main.o : main.c graphics.h world.h
	$(CC) $(CFLAGS) -c main.c

graphics.o : graphics.c world.h 
	$(CC) $(CFLAGS) -c graphics.c

world.o : world.c world.h 
	$(CC) $(CFLAGS) -c world.c

clean:
	rm -f game main.o graphics.o world.o

Download Makefile.variables



Add a few lines of code to make0.pl and we can handle variables and comments.

A good example of how easy some tasks are in Perl.
$makefile_name = "Makefile";
if (@ARGV >= 2 && $ARGV[0] eq "-f") {
    shift @ARGV;
    $makefile_name = shift @ARGV;
}

parse_makefile($makefile_name);
push @ARGV, $first_target if !@ARGV;
build($_) foreach @ARGV;
exit 0;

sub parse_makefile {
    my ($file) = @_;
    open MAKEFILE, $file or die "Can not open $file: $!\n";
    while (<MAKEFILE>) {
        s/#.*//;
        s/\$\((\w+)\)/$variable{$1}||''/eg;
        if (/^\s*(\w+)\s*=\s*(.*)$/) {
            $variable{$1} = $2;
            next;
        }
        my ($target, $dependencies) = /(\S+)\s*:\s*(.*)/ or next;
        $first_target ||= $target;
        $dependencies{$target} = $dependencies;
        while (<MAKEFILE>) {
            s/#.*//;
            s/\$\((\w+)\)/$variable{$1}||''/eg;
            last if !/^\t/;
            $build_command{$target} .= $_;
        }
    }
}

sub build {
    my ($target) = @_;
    my $build_command = $build_command{$target};
    die "*** No rule to make target $target\n" if !$build_command && !-e $target;
    return if !$build_command;
    my $target_build_needed = ! -e $target;
    foreach $dependency (split /\s+/, $dependencies{$target}) {
        build($dependency);
        $target_build_needed ||= -M  $target > -M $dependency;
    }
    return if !$target_build_needed;
    print $build_command;
    system $build_command;
}

Download make1.pl


Simple makefile with builtin variables
game : main.o graphics.o world.o 
	$(CC) $(CFLAGS) -o $@ main.o graphics.o world.o

main.o : main.c graphics.h world.h
	$(CC) $(CFLAGS) -c $<

graphics.o : graphics.c world.h 
	$(CC) $(CFLAGS) -c $*.c

world.o : world.c world.h 
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f game main.o graphics.o world.o

Download Makefile.builtin_variables


Simple makefile with builtin variables relying on implict rules
game : main.o graphics.o world.o 
	$(CC) $(CFLAGS) -o $@ $^

main.o : main.c graphics.h world.h

graphics.o : graphics.c world.h 

world.o : world.c world.h 

clean:
	rm -f game main.o graphics.o world.o

Download Makefile.implicit



Add a few lines of code to make1.pl and we can handle some builtin variables and an implicit rule.

Another good example of how easy some tasks are in Perl.
$makefile_name = "Makefile";
if (@ARGV >= 2 && $ARGV[0] eq "-f") {
    shift @ARGV;
    $makefile_name = shift @ARGV;
}
%variable = (CC => 'cc', CFLAGS => '');
parse_makefile($makefile_name);
push @ARGV, $first_target if !@ARGV;
build($_) foreach @ARGV;
exit 0;

sub parse_makefile {
    my ($file) = @_;
    open MAKEFILE, $file or die "Can not open $file: $!";
    while (<MAKEFILE>) {
        s/#.*//;
        s/\$\((\w+)\)/$variable{$1}||''/eg;
        if (/^\s*(\w+)\s*=\s*(.*)$/) {
            $variable{$1} = $2;
            next;
        }
        my ($target, $dependencies) = /(\S+)\s*:\s*(.*)/ or next;
        $first_target = $target if !defined $first_target;
        $dependencies{$target} = $dependencies;
        while (<MAKEFILE>) {
            s/#.*//;
            s/\$\((\w+)\)/$variable{$1}||''/eg;
            last if !/^\t/;
            $build_command{$target} .= $_;
        }
    }
}

sub build {
    my ($target) = @_;
    my $build_command = $build_command{$target};
    if (!$build_command && $target =~ /(.*)\.o/) {
        $build_command = "$variable{CC} $variable{CFLAGS} -c \$< -o \$@\n";
    }
    die "*** No rule to make target $target\n" if !$build_command && !-e $target;
    return if !$build_command;
    my $target_build_needed = ! -e $target;
    foreach $dependency (split /\s+/, $dependencies{$target}) {
        build($dependency);
        $target_build_needed ||= -M  $target > -M $dependency;
    }
    return if !$target_build_needed;
    my %builtin_variables;
    $builtin_variables{'@'} = $target;
    ($builtin_variables{'*'} = $target) =~ s/\.[^\.]*$//;
    $builtin_variables{'^'} = $dependencies{$target};
    ($builtin_variables{'<'} = $dependencies{$target}) =~  s/\s.*//;
    $build_command =~ s/\$(.)/$builtin_variables{$1}||''/eg;
    print $build_command;
    system $build_command;
}

Download make2.pl

Linux Tools
Exam