This book, updated and enlarged for the second edition, is written as a text for a course aimed at 3rd or 4th year students. Only some familiarity with elementary linear algebra and probability is directly assumed, but some maturity is required. The students may specialize in discrete mathematics, computer science, or communication engineering. The book is also a suitable introduction to coding theory for researchers from related fields or for professionals who want to supplement their theoretical basis. The book gives the coding basics for working on projects in any of the above areas, but material specific to one of these fields has not been included. The chapters cover the codes and decoding methods that are currently of most interest in research, development, and application. They give a relatively brief presentation of the essential results, emphasizing the interrelations between different methods and proofs of all important results. A sequence of problems at the end of each chapter serves to review the results and give the student an appreciation of the concepts. In addition, some problems and suggestions for projects indicate direction for further work. The presentation encourages the use of programming tools for studying codes, implementing decoding methods, and simulating performance. Specific examples of programming exercises are provided on the book's home page.