Zum Inhalt springen

English:Introduction to Computer Science

Aus MOOCsWiki Staging
Die Druckversion wird nicht mehr unterstützt und kann Darstellungsfehler aufweisen. Bitte aktualisiere deine Browser-Lesezeichen und verwende stattdessen die Standard-Druckfunktion des Browsers.
aiMOOC-Siegel

Introduction to Computer Science



Introduction

Computer science is the systematic study of computation: how information can be represented, processed, communicated, protected, and used to solve problems. It includes programming, but it is much broader than learning a programming language. Computer scientists design and analyze algorithms, study the limits of what can be computed, build software and systems, organize data, reason about networks and security, and investigate fields such as Artificial intelligence, Human-computer interaction, and Computer graphics.

At university level, you should learn to move between several layers of abstraction. At one moment you may reason about electrical states and logic gates; at another you may design a data structure, prove an algorithm correct, test a software module, or evaluate the social consequences of a computing system. The same problem can often be viewed mathematically, algorithmically, technically, and ethically.

The image above shows programmers working with ENIAC, one of the earliest large-scale general-purpose electronic digital computers. Early machines made the physical nature of computation highly visible: cables, switches, vacuum tubes, and manual configuration. Modern computers hide most of that complexity behind layers of hardware and software abstraction.

Learning goals. By the end of this aiMOOC, you should be able to explain the major layers of a computing system, represent information in binary form, trace simple programs, compare common data structures and algorithms, interpret basic complexity claims, distinguish core system components, explain how networks and databases organize communication and data, describe fundamental ideas in computability and security, and connect technical design decisions with ethical and social consequences.


Computer Science as a Discipline

Computer science asks both constructive and analytical questions. A constructive question might be: How can you design a program that finds the shortest route through a network? An analytical question might be: How much time and memory will the program require as the network grows? A theoretical question might be: Is there an algorithm that can solve every instance of this type of problem? A human-centered question might be: How should the system communicate uncertainty to a user?

Several recurring ideas connect the discipline:

  1. Abstraction: Hide unnecessary detail while preserving the information needed at a particular level of reasoning.
  2. Algorithm: Specify a finite procedure for transforming inputs into outputs.
  3. Data: Represent information in forms that can be stored, transmitted, and processed.
  4. Correctness: Argue that a program or algorithm satisfies its specification under stated assumptions.
  5. Efficiency: Compare the resources used by alternative solutions, especially time and memory.
  6. Modularity: Decompose systems into components with clear responsibilities and interfaces.
  7. Security: Protect systems and information against accidental and intentional threats.
  8. Ethics of technology: Evaluate who may benefit, who may be harmed, and which values are embedded in technical choices.

Computer science therefore combines mathematics, engineering, experimentation, design, and empirical evaluation. A successful solution is not merely code that runs; it should also be understandable, testable, appropriate for its context, and supported by evidence.


Computational Thinking and Problem Solving

Computational thinking is a disciplined way of formulating problems so that a computational process can help solve them. It does not mean that every problem should be automated. Instead, you identify what information matters, define inputs and desired outputs, decompose the task, choose representations, design an algorithm, and evaluate the result.


From Problem Statement to Algorithm

A useful workflow is to begin with a precise specification. Suppose you need a program that reports the median response time from a set of measurements. You must clarify whether the input can be empty, how invalid values are handled, whether the values are already sorted, what precision is required, and what the program should return when the number of measurements is even. These details determine the algorithm and the tests.

Decomposition divides a complex task into smaller subproblems. Pattern recognition notices similarities with problems you already know. Abstraction removes details that do not affect the current decision. Algorithm design turns the chosen strategy into a step-by-step method. Evaluation checks correctness, efficiency, usability, and limits.

A flowchart can make control flow visible, but it is not the algorithm itself. The same algorithm can be represented in natural language, pseudocode, a diagram, or executable code. For complex software, precise specifications and modular interfaces usually scale better than a single large flowchart.


Abstraction and Interfaces

An abstraction defines what a component does while hiding details about how it does it. For example, a list abstraction may support operations such as append, remove, and lookup. A caller can use those operations without knowing whether the implementation uses a contiguous array, linked nodes, or another structure.

Interfaces support modular reasoning. If the contract of a component is clear, teams can develop and test components independently. Abstraction is powerful because it reduces the amount of detail you must consider at once, but it can also hide important costs. A high-level operation that looks simple may trigger expensive computation, network communication, or disk access.


Data Representation

Digital computers represent information using discrete states. At a foundational level, binary representation uses two symbols, commonly written as 0 and 1. A bit is one binary digit. A group of eight bits is commonly called a byte. What a particular bit pattern means depends on an agreed interpretation.


Numbers, Text, Images, and Sound

For unsigned binary integers, each bit position represents a power of two. For example, the binary pattern 101101 represents 32 + 8 + 4 + 1, which equals 45 in decimal. Signed integers require an encoding convention; modern systems commonly use two's complement. Real numbers are often approximated with floating-point formats, which means many decimal fractions cannot be represented exactly.

Text also requires an encoding. ASCII historically defined numeric codes for a limited set of characters, while Unicode provides a much larger character repertoire used by modern software. Character encoding is distinct from the visual font used to display a character.

Images can be represented as grids of pixels whose components store color values. Audio can be represented by samples taken from a signal over time. In both cases, representation choices affect storage size, fidelity, and processing cost. Compression methods may be lossless, preserving all original information needed to reconstruct the encoded data, or lossy, discarding some information to reduce size.


Boolean Logic

Bits can also represent truth values. Boolean algebra studies operations such as NOT, AND, and OR. Digital circuits implement such operations with logic gates, which can be combined to perform arithmetic, comparison, storage, and control.

A key lesson is that complex behavior can emerge from layers of simple operations. A modern processor contains enormous numbers of transistors, yet programmers typically work through higher-level abstractions such as instructions, variables, functions, objects, and services.


Computer Architecture

Computer architecture describes the organization and behavior of a computer system as seen through its components and instruction mechanisms. A simplified stored-program computer contains a processor, memory, and input/output devices. Programs and data are stored in memory, while the processor fetches and executes instructions.


CPU, Memory, and the Fetch-Execute Cycle

A CPU includes components that perform arithmetic and logic, control instruction execution, and store small amounts of very fast working data in registers. Main memory holds currently active program instructions and data. Persistent storage such as solid-state drives retains data without continuous power.

A simplified instruction cycle consists of fetching an instruction from memory, decoding what operation it requests, obtaining required operands, executing the operation, and storing a result. Real processors add pipelines, caches, speculation, multiple cores, vector units, and many other optimizations, but the simplified cycle remains a useful conceptual model.

Memory hierarchy matters because different storage technologies trade off speed, capacity, and cost. Registers are extremely fast but small; caches reduce the average cost of accessing frequently used data; main memory is larger; persistent storage is much larger but generally slower. Performance therefore depends not only on the number of arithmetic operations but also on data movement.


Programming Fundamentals

Programming is the activity of expressing computational processes in a language that can be translated or interpreted for execution. A programming language provides syntax, semantic rules, data types, control structures, and mechanisms for abstraction.


Variables, Control Flow, and Functions

A variable associates a name with a value or storage location according to the rules of a language. Expressions compute values. Conditionals choose among alternatives. Loops repeat computation. Functions package behavior behind a named interface and may accept inputs and return outputs.

A small Python example illustrates composition:

temperatures = [18, 21, 20, 24]
average = sum(temperatures) / len(temperatures)
print(average)

The example creates a list, applies two library functions, computes a quotient, stores the result, and passes that result to an output function. Even a short program therefore depends on several abstractions.


Types, State, and Errors

A type describes a set of values and the operations permitted on them. Type systems vary: some languages check many constraints before execution, while others detect more type errors at runtime. Neither approach automatically guarantees correctness.

Programs may also contain mutable state, meaning information that changes over time. State is useful but can make behavior harder to reason about, especially when multiple parts of a system share or modify it.

Common error categories include syntax errors, runtime errors, and logical errors. A program can run to completion and still be wrong because its logic does not match the specification. Testing should therefore include typical cases, boundary cases, invalid inputs where appropriate, and cases designed to reveal assumptions.


Compilation and Interpretation

Source code must ultimately be translated into operations a machine can execute. A compiler translates source code into another form, often machine code or an intermediate representation. An interpreter executes or evaluates program instructions through another program. Many modern language implementations combine compilation and interpretation, so the distinction is best understood as a set of implementation strategies rather than a strict division between languages.


Algorithms and Complexity

An algorithm is a finite, well-defined procedure for solving a class of problems. Algorithms should be evaluated not only by whether they produce correct results but also by how their resource requirements grow with input size.


Searching and Sorting

Linear search checks items one after another and in the worst case examines every element. Binary search repeatedly discards half of a sorted search interval, giving logarithmic growth in the number of comparisons. The requirement that the data be ordered is an important precondition.

Sorting illustrates algorithmic trade-offs. Simple methods can be easy to implement but scale poorly. Merge sort divides the input into smaller parts, sorts those parts recursively, and merges the sorted results.


Asymptotic Analysis

Big O notation describes an upper bound on the growth of a function and is commonly used to discuss algorithmic resource use. For introductory comparison, constant, logarithmic, linear, linearithmic, quadratic, and exponential growth represent increasingly different scaling behaviors.

If one algorithm performs about n operations and another performs about n squared operations, the difference may be small for tiny inputs but enormous for large inputs. Asymptotic analysis deliberately ignores many machine-specific constants so that growth can be compared at a higher level. It does not replace measurement: cache behavior, implementation details, data distribution, parallelism, and hardware all affect real runtime.

Correctness and efficiency are separate questions. A fast algorithm that returns the wrong answer is not acceptable, while a provably correct algorithm may still be unusable at realistic scale.


Data Structures

A data structure organizes information so that particular operations can be performed effectively. Choosing a data structure is therefore part of algorithm design. The best choice depends on which operations are frequent, which ordering guarantees are needed, how much memory is available, and whether data changes over time.


Arrays, Linked Lists, Stacks, Queues, Trees, and Hash Tables

An array provides indexed access to elements stored in a structured sequence. In many low-level implementations, elements occupy contiguous memory. A linked list stores elements in nodes connected by references, which makes some insertions and removals convenient but sacrifices direct indexed access.

A stack follows last-in, first-out access, while a queue follows first-in, first-out access. These simple interfaces appear in parsing, scheduling, graph traversal, undo systems, and many other applications.

A tree represents hierarchical relationships. A binary search tree can support ordered lookup efficiently when its shape remains favorable, but a badly unbalanced tree can degrade toward linear behavior.

A hash table computes an index from a key and is designed for fast average-case insertion, lookup, and deletion under suitable assumptions. Collisions must be handled because different keys can map to the same location.

When comparing structures, ask about operation costs, memory overhead, ordering, worst-case behavior, mutation, and the assumptions required to achieve expected performance.


Operating Systems and Concurrency

An operating system manages hardware resources and provides services to application programs. It creates abstractions such as processes, virtual memory, files, and sockets so that programs can use hardware through stable interfaces instead of directly controlling every device.


Processes, Threads, and Scheduling

A process is an executing program together with its associated state and resources. A process may contain multiple threads of execution. The operating system scheduler decides which runnable work receives processor time.

Concurrency means that multiple tasks make progress during overlapping periods. Parallelism means that multiple computations actually execute at the same time on separate processing resources. Concurrent programs can suffer from race conditions when outcomes depend on unintended timing between operations. Synchronization mechanisms such as locks, semaphores, messages, and atomic operations help coordinate shared state.

Virtual memory gives each process an abstract address space and allows the operating system and hardware to map virtual addresses to physical memory. File systems organize persistent data and metadata. Permissions and isolation contribute to security by controlling which resources processes and users may access.


Networks and the Internet

A computer network connects devices so they can exchange data. Network design relies on protocols: agreed rules for message formats, addressing, ordering, error handling, and communication behavior.


Layers, Packets, and Protocols

Layering allows network systems to separate concerns. One layer can provide a service to the layer above while relying on a service below. The OSI reference model is a conceptual seven-layer model; the protocols of the Internet are more often discussed through the TCP/IP suite. The models are related teaching frameworks but should not be treated as identical.

Data sent over a network is divided and encapsulated according to protocols. Ethernet is widely used for local networking. Internet Protocol provides addressing and packet delivery across interconnected networks. TCP adds reliable, ordered byte-stream transport between endpoints, while UDP provides a simpler datagram service without TCP's reliability guarantees. Application protocols such as HTTP define communication for higher-level services.

Networks are distributed systems, so latency, partial failure, congestion, security, and independent administration matter. A remote operation may fail even when the local program is correct.


Databases and Information Management

A database system stores, organizes, retrieves, and updates data while managing concerns such as persistence, concurrent access, integrity, and recovery. In the relational model, data is represented through relations commonly visualized as tables.


Relational Thinking and Queries

A relational table has rows and columns, while a schema specifies structure and constraints. Keys identify records and connect related data. SQL is a widely used language family for defining, querying, and modifying relational data.

Good database design reduces unnecessary duplication and makes integrity rules explicit. Transactions help group operations into meaningful units. The ACID properties—atomicity, consistency, isolation, and durability—describe important goals for transaction processing, though database systems provide different implementation choices and isolation guarantees.

Indexes can make selected queries faster at the cost of additional storage and update work. As with algorithms and data structures, performance depends on the workload: a design optimized for frequent reads may differ from one optimized for heavy writes or analytical scans.


Theory of Computation

Theoretical computer science studies formal models of computation, the kinds of problems they can solve, and the resources required. This area provides concepts that remain important even when hardware changes.


Computability and Complexity

A Turing machine is an abstract mathematical model with a finite control, a tape divided into cells, and a head that can read and write symbols while moving along the tape. It is intentionally simple but powerful enough to formalize the notion of general algorithmic computation.

A problem is computable if an algorithm can solve every valid instance under the chosen model. Some precisely stated problems are undecidable: no algorithm can correctly decide every possible instance. The classic Halting problem is one such example.

Computational complexity asks a different question: among computable problems, how many resources are required? Complexity theory groups problems according to resource bounds and studies relationships among these classes. This perspective explains why a problem can be computable in principle yet still be impractical for large inputs.


Software Engineering

Software engineering addresses the disciplined construction and evolution of software systems. Larger systems require more than individual programming skill: they require requirements analysis, architecture, version control, testing, code review, documentation, deployment, monitoring, and maintenance.


Correctness, Testing, and Maintainability

A specification states what a system should do. Tests provide evidence that selected behaviors match expectations, but passing tests alone does not prove that a nontrivial program is correct for every possible input. Formal methods can provide stronger mathematical guarantees for selected properties, while empirical testing remains essential for real implementations.

Version control records changes and supports collaboration. Code review can detect defects and spread knowledge. Automated tests help teams detect regressions. Continuous integration systems can rebuild and test a project whenever changes are proposed.

Maintainability depends on clear interfaces, readable code, limited duplication, explicit assumptions, useful documentation, and architecture that can evolve. Software is often read and modified more times than it is initially written.


Cybersecurity, Privacy, and Ethics

Computer security aims to protect systems and information against threats. A common framework focuses on confidentiality, integrity, and availability. Security is not a single product or feature; it is a property that depends on system design, implementation, operation, users, and threat models.


Threat Models and Defense in Depth

A threat model identifies assets, possible adversaries, attack surfaces, trust boundaries, and plausible harms. Controls should be selected in response to that model. Authentication establishes or checks identity claims; authorization determines permitted actions. Encryption can protect data confidentiality in storage and transit when keys are managed appropriately.

Defense in depth uses multiple layers of protection so that one failed control does not automatically compromise the entire system. Secure development also requires patching, careful dependency management, least privilege, logging, backups, and incident response planning.

Privacy is related to security but broader. A system can be secure against unauthorized access and still collect or use personal data in ways people consider inappropriate. Responsible design therefore considers data minimization, informed use, retention, transparency, and the consequences of combining datasets.


Computing Ethics and Social Impact

Technical systems can shape access to education, employment, credit, healthcare, communication, and public services. Data may reflect historical inequalities. Automated decisions can create different error rates or burdens for different groups. Interfaces can influence behavior through defaults and incentives.

Ethical analysis asks you to identify stakeholders, benefits, risks, uncertainties, power relationships, and alternatives. It also asks whether a system should be built or deployed at all, not merely whether it can be built. Professional responsibility includes communicating limitations rather than presenting technical outputs as infallible.


Artificial Intelligence and Human-Computer Interaction

Artificial intelligence studies computational systems that perform tasks associated with intelligent behavior, including perception, reasoning, planning, language processing, and learning. Machine learning is a major approach within AI in which models improve task performance using data or experience.

A machine-learning system normally requires choices about data, features or representations, model family, objective, training procedure, and evaluation. Performance on training data is not enough; you want evidence that the system generalizes to relevant new cases. Dataset shift, bias, overfitting, and poorly chosen metrics can make apparently strong results misleading.

Human-computer interaction focuses on how people interact with computing systems. Usability, accessibility, learnability, error recovery, and human control are design concerns. Good interfaces should make important system state visible, help users form accurate expectations, and support people with diverse abilities and contexts.


Connecting the Layers

A single application can involve almost every topic in this course. Consider a navigation service. The user interface collects a destination. A program represents roads and intersections as a graph. An algorithm searches for a route. Data structures organize the graph efficiently. Databases store maps and traffic information. Operating systems allocate memory and processor time. Networks carry requests and responses. Security mechanisms protect accounts and communication. Machine-learning models may estimate travel times. Ethical design considers privacy, accessibility, and the effects of automated route recommendations on communities.

The value of an introductory course is therefore not memorizing isolated vocabulary. It is learning to move between layers, choose useful abstractions, identify assumptions, and ask what evidence would justify a claim about correctness, performance, security, or social impact.


Interactive Tasks


Quiz: Test Your Knowledge

Which statement best describes abstraction in computer science? (Hiding unnecessary detail while preserving a useful interface) (!Converting every program directly into binary by hand) (!Storing all data in one global variable) (!Avoiding the use of algorithms)




What is the decimal value of the unsigned binary number 101101? (45) (!41) (!53) (!57)




Which component is primarily responsible for executing processor instructions? (CPU) (!Database) (!Router) (!Compiler)




What precondition makes ordinary binary search applicable to an array? (The search range is sorted) (!The array contains only text) (!The array has exactly ten elements) (!Every value is unique)




Which growth rate is typically associated with binary search comparisons? (Logarithmic) (!Quadratic) (!Exponential) (!Factorial)




Which data structure follows last in first out access? (Stack) (!Queue) (!Graph) (!Hash table)




What is a primary responsibility of an operating system? (Managing hardware resources and providing services to programs) (!Writing every application used by the user) (!Guaranteeing that all software is free of defects) (!Replacing every network protocol)




Which protocol provides reliable ordered byte stream transport on the Internet? (TCP) (!UDP) (!IP) (!Ethernet)




Which security goal means preventing unauthorized alteration of data? (Integrity) (!Availability) (!Compression) (!Caching)




What does the halting problem demonstrate? (Some precisely defined computational problems are undecidable) (!Every algorithm can be made constant time) (!All programs eventually terminate) (!Binary representation prevents logical errors)





Memory Game

Abstraction Hiding implementation detail behind a useful interface
Algorithm Finite procedure for transforming input into output
Byte Common group of eight bits
Compiler Program that translates source code into another form
Stack Data structure with last in first out access
Protocol Agreed rules for communication between systems
Transaction Group of database operations treated as one logical unit
Computability Study of which problems can be solved by algorithms





Drag and Drop

Match the correct terms. Topic
Binary search Repeatedly halves a sorted search interval
Hash table Uses a function to map keys toward storage locations
Operating system Manages resources and provides abstractions for programs
TCP Provides reliable ordered byte stream transport
Turing machine Formal model used to study general computation




...


Crossword Puzzle

Abstraction What concept hides unnecessary implementation details behind a useful interface?
Algorithm What word describes a finite procedure for solving a class of problems?
Compiler What program translates source code into another form?
Database What organized system stores and retrieves persistent structured information?
Protocol What agreed rule set governs communication between networked systems?
Recursion What technique allows a function or definition to refer to itself?





LearningApps


Cloze Text

Complete the text.
Computer science studies computation and the ways information can be represented, processed, and communicated through

. A single binary digit is called a

. A stored-program computer keeps instructions and data in

. Programming languages use mechanisms such as variables, conditionals, loops, and

to express computation. Binary search achieves efficient lookup by repeatedly reducing a sorted search interval by

. A data structure should be chosen according to the operations and performance requirements of the

. An operating system manages hardware resources and provides abstractions such as processes and

. Networked computers communicate according to agreed rules called

. Security engineering commonly considers confidentiality, integrity, and

. The theory of computability shows that some precisely stated problems are

.




Open-Ended Tasks


Easy

  1. Binary representation exercise: Choose a short word, encode its characters using a documented text encoding, show the corresponding bit patterns, and explain why the same bits need an agreed interpretation.
  2. Algorithm storyboard: Create a one-page visual storyboard that shows how linear search and binary search examine a collection, then annotate the assumptions that each method requires.
  3. Program tracing journal: Write a short Python program with a loop and a conditional, trace the values of its variables by hand for three inputs, and compare your prediction with the program output.
  4. Computing history interview: Interview someone about the first computer or networked device they used, then relate their experience to one technical change in hardware, software, or connectivity.


Standard

  1. Data structure benchmark: Implement or use two data structures that support the same task, measure their behavior on increasing input sizes, and explain how the results relate to theoretical operation costs.
  2. Campus systems map: Visit a campus computing laboratory, library technology area, or public computing facility and create a diagram showing visible hardware, software, network, authentication, and user-interface layers without recording private or restricted information.
  3. Database mini project: Design a small relational database for a realistic university scenario, define keys and constraints, insert sample data, write several queries, and justify one index choice.
  4. Network protocol explainer: Produce a three-to-five-minute video that follows a web request through application, transport, network, and local-link concepts, clearly distinguishing TCP, IP, and Ethernet roles.


Advanced

  1. Algorithmic complexity investigation: Implement at least two algorithms for the same problem, derive their expected asymptotic behavior, collect runtime data over a meaningful input range, and discuss where measurements diverge from the simple model.
  2. Concurrency experiment: Create a controlled program that demonstrates a race condition on shared state, then apply an appropriate synchronization mechanism and explain why the corrected design works.
  3. Security threat model: Build a threat model for a hypothetical student information service, identify assets, trust boundaries, adversary goals, and mitigations, and explain residual risks without attempting attacks on real systems.
  4. Responsible AI case study: Analyze a proposed machine-learning application using technical performance, data quality, privacy, fairness, human oversight, and failure consequences, then recommend whether and how it should be deployed.



Learning Assessment

  1. Integrated system analysis: Explain how a single application of your choice uses at least five layers from hardware, operating systems, data structures, algorithms, databases, networking, security, and user interaction, and identify one important interface between layers.
  2. Correctness and complexity argument: Given two competing algorithms for the same task, state the assumptions, argue why each is or is not correct, compare asymptotic costs, and recommend one for a specified workload.
  3. Representation transfer task: Take one piece of real information such as text, an image, or sensor data and explain how representation choices affect precision, storage, transmission, processing, and possible errors.
  4. Data architecture critique: Review a small database schema or data model, identify redundancy or integrity risks, propose a revision, and explain how your design changes query or update behavior.
  5. Security and privacy evaluation: Analyze a hypothetical networked service with a threat model, distinguish security from privacy concerns, and propose layered controls while acknowledging trade-offs and residual risk.
  6. Computability reflection: Compare a problem that is efficiently solvable, one that appears computationally expensive at scale, and one that is undecidable, explaining why these are three different kinds of limitations.




Evidence of Learning

Evidence of learning should show more than vocabulary recall. You should be able to demonstrate knowledge by accurately explaining representation, architecture, programming, algorithms, data structures, operating systems, networking, databases, theory, security, and AI. You should demonstrate skills by tracing programs, designing algorithms, choosing data structures, reasoning about complexity, modeling data, testing software, analyzing protocol roles, and evaluating risks.

Strong products include working programs, test suites, benchmark reports, database schemas and queries, system diagrams, threat models, explanatory videos, technical writing, and reproducible experiments. Strong reasoning includes explicit assumptions, justified design choices, counterexamples, boundary cases, and evidence that connects conclusions to observations or formal arguments.

Transfer achievement means using these concepts in unfamiliar situations. For example, you can recognize that a performance problem may actually be caused by data movement rather than arithmetic, that a user-interface decision can create security consequences, or that a data representation choice can affect both algorithmic performance and fairness. You should also be able to identify when you need deeper specialist knowledge rather than overclaiming from an introductory model.




OERs on the Topic

The English Wikipedia article on computer science offers a broad reference overview and links to specialist topics:


For additional open university-level study, you can use MIT OpenCourseWare 6.100L Introduction to CS and Programming using Python and Harvard CS50x. These resources include lectures, notes, exercises, and programming practice. Use them to deepen the topics introduced here and to compare different teaching approaches.


Linked Learning Areas


aiMOOC Projects