100% found this document useful (1 vote)
13 views

Python Programming Using Problem Solving Harsh Bhasin pdf download

The document is a promotional and informational piece about the book 'Python Programming Using Problem Solving' by Harsh Bhasin, which covers algorithmic problem-solving and Python fundamentals. It includes details about licensing, copyright, and the structure of the book, which consists of various chapters on programming concepts, data structures, and practical applications. Additionally, it provides links to other related Python programming resources and books available for download.

Uploaded by

hanoyamaet
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
13 views

Python Programming Using Problem Solving Harsh Bhasin pdf download

The document is a promotional and informational piece about the book 'Python Programming Using Problem Solving' by Harsh Bhasin, which covers algorithmic problem-solving and Python fundamentals. It includes details about licensing, copyright, and the structure of the book, which consists of various chapters on programming concepts, data structures, and practical applications. Additionally, it provides links to other related Python programming resources and books available for download.

Uploaded by

hanoyamaet
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 64

Python Programming Using Problem Solving Harsh

Bhasin download

https://ebookbell.com/product/python-programming-using-problem-
solving-harsh-bhasin-54261446

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Python Programming Using Problem Solving Approach 1st Thareja

https://ebookbell.com/product/python-programming-using-problem-
solving-approach-1st-thareja-24064494

Python Programming Using Problem Solving H Bhasin

https://ebookbell.com/product/python-programming-using-problem-
solving-h-bhasin-50745404

Problem Solving In Data Structures Algorithms Using Python Programming


Interview Guide 1st Edition Hemant Jain

https://ebookbell.com/product/problem-solving-in-data-structures-
algorithms-using-python-programming-interview-guide-1st-edition-
hemant-jain-43260266

Applying Math With Python Practical Recipes For Solving Computational


Math Problems Using Python Programming And Its Libraries Sam Morley

https://ebookbell.com/product/applying-math-with-python-practical-
recipes-for-solving-computational-math-problems-using-python-
programming-and-its-libraries-sam-morley-49184402
Applying Math With Python Practical Recipes For Solving Computational
Math Problems Using Python Programming And Its Libraries Sam Morley

https://ebookbell.com/product/applying-math-with-python-practical-
recipes-for-solving-computational-math-problems-using-python-
programming-and-its-libraries-sam-morley-49849188

An Introduction To Python Programming A Practical Approach Using


Python To Solve Complex Problems With A Burst Of Machine Learning Dr
Krishna Kumar Mohbey Dr Brijesh Bakariya

https://ebookbell.com/product/an-introduction-to-python-programming-a-
practical-approach-using-python-to-solve-complex-problems-with-a-
burst-of-machine-learning-dr-krishna-kumar-mohbey-dr-brijesh-
bakariya-46071826

Python Quickstart Guide The Simplified Beginners Guide To Python


Programming Using Handson Projects Robert Oliver

https://ebookbell.com/product/python-quickstart-guide-the-simplified-
beginners-guide-to-python-programming-using-handson-projects-robert-
oliver-49755838

Linux For Hackers Learn Cybersecurity Principles With Shellpythonbash


Programming Using Kali Linux Tools A Complete Guide For Beginners
Darwin

https://ebookbell.com/product/linux-for-hackers-learn-cybersecurity-
principles-with-shellpythonbash-programming-using-kali-linux-tools-a-
complete-guide-for-beginners-darwin-21882190

Bioinformatics Programming Using Python Mitchell Model

https://ebookbell.com/product/bioinformatics-programming-using-python-
mitchell-model-43326148
PYTHON PROGRAMMING
USING PROBLEM-SOLVING
LICENSE, DISCLAIMER OF LIABILITY, AND LIMITED WARRANTY

By purchasing or using this book (the “Work”), you agree that this license
grants permission to use the contents contained herein, but does not give
you the right of ownership to any of the textual content in the book or
ownership to any of the information or products contained in it. This license
does not permit uploading of the Work onto the Internet or on a network (of
any kind) without the written consent of the Publisher. Duplication or
dissemination of any text, code, simulations, images, etc. contained herein
is limited to and subject to licensing terms for the respective products, and
permission must be obtained from the Publisher or the owner of the content,
etc., in order to reproduce or network any portion of the textual material (in
any media) that is contained in the Work.

MERCURY LEARNING AND INFORMATION (“MLI” or “the Publisher”) and


anyone involved in the creation, writing, production, accompanying
algorithms, code, or computer programs (“the software”), and any
accompanying Web site or software of the Work, cannot and do not warrant
the performance or results that might be obtained by using the contents of
the Work. The author, developers, and the Publisher have used their best
efforts to ensure the accuracy and functionality of the textual material
and/or programs contained in this package; we, however, make no warranty
of any kind, express or implied, regarding the performance of these contents
or programs. The Work is sold “as is” without warranty (except for
defective materials used in manufacturing the book or due to faulty
workmanship).

The author, developers, and the publisher of any accompanying content, and
anyone involved in the composition, production, and manufacturing of this
work will not be liable for damages of any kind arising out of the use of (or
the inability to use) the algorithms, source code, computer programs, or
textual material contained in this publication. This includes, but is not
limited to, loss of revenue or profit, or other incidental, physical, or
consequential damages arising out of the use of this Work.
The sole remedy in the event of a claim of any kind is expressly limited to
replacement of the book and only at the discretion of the Publisher. The use
of “implied warranty” and certain “exclusions” vary from state to state, and
might not apply to the purchaser of this product.
PYTHON PROGRAMMING
USING PROBLEM-SOLVING

HARSH BHASIN

MERCURY LEARNING AND INFORMATION


Dulles, Virginia
Boston, Massachusetts
New Delhi
Reprint and Revision Copyright ©2023 by MERCURY LEARNING AND INFORMATION LLC. All rights
reserved.
Original Copyright ©2022 by NEW AGE International Publishers.
MERCURY LEARNING AND INFORMATION is an imprint of Walter De Gruyter GmbH.

This publication, portions of it, or any accompanying software may not be reproduced in any way,
stored in a retrieval system of any type, or transmitted by any means, media, electronic display or
mechanical display, including, but not limited to, photocopy, recording, Internet postings, or
scanning, without prior permission in writing from the publisher.

Publisher: David Pallai


MERCURY LEARNING AND INFORMATION
22841 Quicksilver Drive
Dulles, VA 20166
[email protected]
www.merclearning.com
800-232-0223

H. Bhasin. Python Programming Using Problem Solving.


ISBN: 978-1-68392-862-1

The publisher recognizes and respects all marks used by companies, manufacturers, and developers
as a means to distinguish their products. All brand names and product names mentioned in this book
are trademarks or service marks of their respective companies. Any omission or misuse (of any kind)
of service marks or trademarks, etc. is not an attempt to infringe on the property of others.

Library of Congress Control Number: 2023934762

232425321 This book is printed on acid-free paper in the United States of America.

Our titles are available for adoption, license, or bulk purchase by institutions, corporations, etc. For
additional information, please contact the Customer Service Dept. at 800-232-0223(toll free).

All of our titles are available in digital format at academiccourseware.com and other digital vendors.
The sole obligation of MERCURY LEARNING AND INFORMATION to the purchaser is to replace the book,
based on defective materials or faulty workmanship, but not based on the operation or functionality
of the product.
To
My Mother
CONTENTS

Preface
SECTION I: ALGORITHMIC PROBLEM-SOLVING AND
PYTHON FUNDAMENTALS
CHAPTER 1: ALGORITHMIC PROBLEM-SOLVING
1.1 Introduction
1.2 Definition and Characteristics
1.3 Notations: Pseudocode and Flow Chart
1.4 Strategies for Problem-Solving: Recursion Versus Iteration
1.5 Asymptotic Notation
1.6 Complexity
1.7 Illustrations
1.7.1 Minimum in a List
1.7.2 Insert a Card in a Pack of Cards (Or Insert an element
in a sorted list). There are ten cards in the pack,
numbered from 1 to 10.
1.7.3 Guess a Number in a Given Range
1.7.4 Tower of Hanoi
1.8 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Application
CHAPTER 2: INTRODUCTION TO PYTHON
2.1 Introduction
2.2 Features of Python
2.2.1 Easy
2.2.2 Type and Run
2.2.3 Syntax
2.2.4 Mixing
2.2.5 Dynamic Typing
2.2.6 Built-in Object Types
2.2.7 Numerous Libraries and Tools
2.2.8 Portable
2.2.9 Free
2.3 The paradigms
2.3.1 Procedural
2.3.2 Object-Oriented
2.3.3 Functional
2.4 Chronology and Uses
2.4.1 Chronology
2.4.2 Uses
2.5 Installation of Anaconda
2.6 Implementation of an Algorithm: Statement, state, Control
Blocks, and Functions
2.6.1 Statement
2.6.2 State
2.6.3 Control Flow
2.7 Conclusion
Glossary
Points to Remember
Resources
Exercises
Multiple Choice Questions
Theory
CHAPTER 3: FUNDAMENTALS
3.1 Introduction
3.2 Basic Input Output
3.2.1 Print Function
3.2.2 Input
3.3 Running a Program
3.3.1 Using the Command Prompt
3.3.2 Executing Programs Written in .py Files
3.3.3 Using Anaconda Navigator
3.4 The Jupyter Notebook
3.5 Value Type and Reference Type
3.6 Tokens, Keywords, and Identifiers
3.6.1 Python Keywords
3.6.2 Python Identifiers
3.6.3 Python Escape Sequence
3.7 Statements
3.7.1 Expression Statement
3.7.2 Assignment Statements
3.7.3 The Assert Statements
3.7.4 The Pass Statements
3.7.5 The Control Statements
3.8 Comments
3.9 Operators
3.10 Types and Examples of Operators
3.10.1 Arithmetic Operators
3.10.2 String Operators
3.10.3 Comparison Operators
3.10.4 Assignment Operators
3.10.5 Logical Operators
3.10.6 Priority of Operators
3.11 Basic Data Types
3.11.1 Integer
3.11.2 Float
3.11.3 String
3.12 Conclusion
Exercises
Multiple Choice Questions
Theory
Explore
SECTION II: PROCEDURAL PROGRAMMING
CHAPTER 4: CONDITIONAL STATEMENTS
4.1 Introduction
4.2 “If,” If-Else, and If-Elif-Else Constructs
4.3 The If-Elif-Else Ladder
4.4 Logical Operators
4.5 The Ternary Operator
4.6 The Get Construct
4.7 Examples
4.8 Summary
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Programming Exercise
CHAPTER 5: LOOPING
5.1 Introduction
5.2 While
5.3 Patterns
5.4 Nesting and Applications of Loops in Lists
5.5 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Programming
CHAPTER 6: FUNCTIONS
6.1 Introduction
6.2 Features of a Function
6.2.1 Modular Programming
6.2.2 Reusability of Code
6.2.3 Manageability
6.2.3.1 Easy debugging
6.2.3.2 Efficient
6.3 Basic Terminology
6.3.1 Name of a Function
6.3.2 Arguments
6.3.3 Return Value
6.4 Definition and Invocation
6.4.1 Working
6.5 Types of Function
6.5.1 Arguments: Types of Arguments
6.6 Implementing Search
6.7 Scope
6.8 Recursion
6.8.1 Rabbit Problem
6.8.2 Disadvantages of Using Recursion
6.9 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Programming Exercise
Questions Based on Recursion
Theory
Extra Questions
CHAPTER 7: FILE HANDLING
7.1 Introduction
7.2 The File handling mechanism
7.3 The open function and file access modes
7.4 Python Functions for File Handling
7.4.1 The Essential Ones
7.4.2 The OS Methods
7.4.3 Miscellaneous Functions and File Attributes
7.5 Command Line Arguments
7.6 Implementation and illustrations
7.7 Conclusion
Points to Remember
Exercises
Multiple Choice Questions
Theory
Programming
CHAPTER 8: LISTS, TUPLE, AND DICTIONARY
8.1 Introduction
8.2 Lists
8.2.1 Accessing Elements: Indexing and Slicing
8.2.2 Mutability
8.2.3 Operators
8.2.4 Traversal
8.2.5 Functions
8.3 Tuple
8.3.1 Accessing Elements of a Tuple
8.3.2 Nonmutability
8.3.3 Operators
8.3.4 Traversal
8.3.5 Functions
8.4 Associate Arrays and Dictionaries
8.4.1 Displaying Elements of a Dictionary
8.4.2 Some Important Functions of Dictionaries
8.4.2.1 The len function returns the number of
elements in a given dictionary.
8.4.2.2 The max function returns the key with
maximum value. If the key is a string, then
the value in the lexicographic ordering
would be returned.
8.4.2.3 The min function returns the key with
minimum value. If the key is a string, then
the value in the lexicographic ordering
would be returned.
8.4.2.4 The sorted function would sort the elements
of a given dictionary by their keys. If the
keys are strings then lexicographic ordering
would be followed.
8.4.2.5 The pop function takes out the element with
the given key from the dictionary.
8.4.3 Input from the User
8.5 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice questions
Theory
Programming exercise
CHAPTER 9: ITERATIONS, GENERATORS, AND
COMPREHENSIONS
9.1 Introduction
9.2 The Power of “For”
9.3 Iterator
9.4 Defining an Iterable Object
9.5 Generators
9.6 Comprehensions
9.7 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Programming Exercise
CHAPTER 10: STRINGS
10.1 Introduction
10.2 Loops Revised
10.3 String Operators
10.3.1 The Concatenation Operator (+)
10.3.2 The Replication Operator (*)
10.3.3 The Membership Operator
10.4 In-Built Functions
10.4.1 len()
10.4.2 Capitalize()
10.4.3 Find()
10.4.4 Count
10.4.5 endswith()
10.4.6 encode
10.4.7 decode
10.4.8 Miscellaneous Functions
10.5 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
SECTION III: OBJECT-ORIENTED PROGRAMMING
CHAPTER 11: INTRODUCTION TO OBJECT-ORIENTED
PARADIGM
11.1 Introduction
11.2 Creating New Types
11.3 Attributes and Functions
11.3.1 Attributes
11.4 Elements of Object-Oriented Programming
11.4.1 Class
11.4.2 Object
11.4.3 Encapsulation
11.4.4 Data Hiding
11.4.5 Inheritance
11.4.6 Polymorphism
11.4.7 Reusability
11.5 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Explore and Design
CHAPTER 12: CLASSES AND OBJECTS
12.1 Introduction to Classes
12.2 Defining a Class
12.3 Creating an Object
12.4 Scope of Data Members
12.5 Nesting
12.6 Constructor
12.7 Multiple __Init__(s)
12.8 Destructors
12.9 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Programming Exercise
CHAPTER 13: INHERITANCE
13.1 Introduction to Inheritance and Composition
13.1.1 Inheritance and Methods
13.1.2 Composition
13.2 Inheritance: Importance and Types
13.2.1 Need for Inheritance
13.2.2 Types of Inheritance
13.2.2.1 Simple inheritance
13.2.2.2 Hierarchical inheritance
13.2.2.3 Multilevel inheritance
13.2.2.4 Multiple inheritance and hybrid inheritance
13.3 Methods
13.3.1 Bound Methods
13.3.2 Unbound Method
13.3.3 Methods are Callable Objects
13.3.4 The Importance and Usage of Super
13.3.5 Calling the Base Class Function Using Super
13.4 Search in Inheritance Tree
13.5 Class Interface and Abstract Classes
13.6 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Programming Exercise
CHAPTER 14: OPERATOR OVERLOADING
14.1 Introduction
14.2 __Init__ Revisited
14.2.1 Overloading __init__(Sort of)
14.3 Methods for Overloading Binary Operators
14.4 Overloading Binary Operators: The Fraction Example
14.5 Overloading the += Operator
14.6 Overloading the > and < Operators
14.7 Overloading the __Bool__ Operator: Precedence of __Bool__
Over __Len__
14.8 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Programming
CHAPTER 15: EXCEPTION HANDLING
15.1 Introduction
15.2 Importance and Mechanism
15.2.1 An Example of Try/Except
15.2.2 Manually Raising Exceptions
15.3 Build-in Exceptions in Python
15.4 The Process
15.4.1 Example
15.4.2 Exception Handling: Try/Except
15.4.3 Raising Exceptions
15.5 Crafting User Defined Exceptions
15.6 An Example of Exception Handling
15.7 Conclusion
Glossary
Points to Remember
Exercises
Multiple Choice Questions
Theory
Programming
SECTION IV: NUMPY, PANDAS, AND MATPLOTLIB
CHAPTER 16: NUMPY–I
16.1 Introduction
16.2 Fundamentals
16.2.1 Similarity and Differences Between a List and a
NumPy Array
16.3 Functions for Generating Sequences
16.3.1 arange()
16.3.2 linspace()
16.4 Aggregate Functions
16.5 Generating Random Numbers Using Numpy
16.6 Zeros, Ones, Eyes, and Full
16.7 Indexing
16.8 Slicing
16.9 Operations: Scalar with an Array
16.9.1 Addition
16.9.1.1 Using the + operator
16.9.1.2 Using the numpy. add function
16.9.2 Subtraction
16.9.2.1 Using the – operator
16.9.2.2 Using the numpy.subtract function
16.9.3 Multiplication
16.9.3.1 Using the * operator
16.9.3.2 Using the numpy.multiply function
16.9.4 Division
16.9.4.1 Using the / operator
16.9.4.2 Using the numpy.divide function
16.9.5 Remainder
16.9.5.1 Using the % operator
16.9.5.2 Using the numpy.remainder function
16.9.6 Power
16.9.6.1 Using the ** operator
16.9.6.2 Using the numpy.power function
16.10 Operations: Array with an Array
16.10.1 Addition
16.10.1.1 Using the + operator
16.10.1.2 Using the numpy.add function
16.10.2 Subtraction
16.10.2.1 Using the — operator
16.10.2.2 Using the numpy.subtract function
16.10.3 Multiplication
16.10.3.1 Using the * operator
16.10.3.2 Using the numpy.multiply function
16.10.4 Division
16.10.4.1 Using the / operator
16.10.4.2 Using the numpy.divide function
16.10.5 Remainder
16.10.5.1 Using the % operator
16.10.5.2 Using the numpy.mod function
16.10.6 Power
16.10.6.1 Using the ** operator
16.10.6.2 Using the numpy.power function
16.11 Conclusion
Exercises
Multiple Choice Questions
Theory
CHAPTER 17: NUMPY–II
17.1 Introduction
17.2 Joining Arrays
17.2.1 hstack
17.2.2 vstack
17.2.3 Concatenate
17.3 Splitting Arrays
17.3.1 hsplit
17.3.2 vsplit
17.3.3 Split
17.3.4 Extract
17.4 Variance
17.5 Covariance
17.6 Correlation
17.7 Conclusion
Exercises
Multiple Choice Questions
Theory
CHAPTER 18: DATA VISUALIZATION-I
18.1 Introduction
18.2 The Plot Function
18.2.1 xlabel
18.2.2 ylabel
18.2.3 axis
18.2.4 xlim, ylim
18.2.5 xticks, yticks
18.2.6 show
18.2.7 savefig
18.3 Plotting Lines and Curves
18.3.1 Plot(X)
18.3.2 Plot(X, Y)
18.3.3 Plot(<2D Array>)
18.3.4 Axis Function
18.3.5 Plotting Points: Scatter Diagram
18.3.6 Sine and Cosine Curves
18.3.7 Comparing Functions
18.3.8 Plotting Multiple Lines
18.4 Additional Arguments
18.4.1 Markers
18.4.2 Color
18.4.3 Linestyle
18.4.4 Linewidth
18.5 The Bar Chart
18.6 Conclusion
Exercises
Multiple Choice Questions
Theory
CHAPTER 19: DATA VISUALIZATION–II
19.1 Introduction
19.2 Box Plot
19.3 Frequency Plots and Histogram
19.4 The Pie Chart
19.5 Conclusion
Exercises
Multiple Choice Questions
Theory
CHAPTER 20: PANDAS–I
20.1 Introduction
20.2 Creating Pandas Series
20.2.1 Using List
20.2.2 Using NumPy Arrays
20.2.3 Using Dictionary
20.3 Indexing, Iloc, Slicing, and Boolean Index
20.3.1 Indexing: loc
20.3.2 Indexing Continued: iloc
20.3.3 Slicing
20.3.4 Functions: Head, Tail, Describe, and index
20.3.4.1 head()
20.3.4.2 tail()
20.3.4.3 index
20.3.4.4 describe()
20.3.5 Boolean Index
20.4 Sorting, Statistical Analysis, and String Functions
20.4.1 sort_values()
20.4.2 Statistical Functions
20.4.3 String Functions
20.5 Creating a Data Frame
20.5.1 Creating a Data Frame Using a Dictionary
20.5.2 Creating a Data Frame Using a Two-Dimensional
Array
20.5.3 Creating the Data Frame Using a Series
20.6 Operations on Rows and Columns of a Data Frame
20.6.1 Adding a Column in a Data Frame
20.6.2 Deleting Column from the Data Frame
20.6.3 Adding a Row in a Data Frame
20.6.4 Deleting Row from the Data Frame
20.7 Dealing with Rows
20.7.1 loc[] and iloc[]
20.7.2 rename
20.8 Iterating a Pandas Data Frame
20.8.1 Iterating Pandas Data Frame Rows
20.8.1.1 iterrows()
20.8.1.2 index
20.8.1.3 itertuples()
20.8.2 Iterating Over Columns
20.8.2.1 iteritems()
20.8.2.2 list
20.9 Conclusion
Exercises
Multiple Choice Questions
Theory
CHAPTER 21: PANDAS–II
21.1 Introduction
21.2 Data Frame Methods: Head, Tail, and Describe
21.2.1 Functions: Head, Tail, and Describe
21.2.1.1 head()
21.2.2 tail()
21.2.3 columns
21.2.4 describe()
21.3 Boolean Index
21.4 Sorting, Descriptive Statistics, and Applying String Functions
21.4.1 sort_values()
21.4.2 Finding Maximum, Minimum, Median, Standard
Deviation, Mean, and Count of Values
21.4.3 String Functions
21.5 Reading from a CSV File: Pandas.read_csv
21.6 Missing Values
21.6.1 To Check Null Values
21.6.2 dropna()
21.6.3 fillna()
21.7 Conclusion
Exercises
Multiple Choice Questions
Theory
APPENDIX A: PROBLEMS FOR PRACTICE: PROGRAMMING
QUESTIONS
APPENDIX B: ANSWERS TO MCQS
REFERENCES
WEB RESOURCES
INDEX
PREFACE

Python is a robust, procedural, object-oriented, and functional language.


The features of the language make it tremendously valuable for web
development, gaming, and scientific programming. Lately, the language has
become incredibly popular. The popularity of the language can be gauged
from the fact that it is currently being used by Google, YouTube, Bit Torrent
and many other companies.
This book deals with problem-solving and programming in Python.
Programming is the soul of computer science, and designing a program
requires involved expertise of the paradigms, along with the ability to use
the standard procedures. To become a virtuous programmer one must,
therefore, not only learn the syntax of the language but also develop an
ability to apply the mastered concepts to solve problems. It may be stated
here that a programming language and its syntax learned by a professional
is of no use until the algorithms that are to be implemented have been well
designed. Thus, a basic knowledge of data structures and algorithms is also
essential. This is the reason that the first section of this book has been
dedicated to problem-solving. One of the most important goals of the book
is to make the readers understand Python’s discriminative features. The
ability of Python to deal with multi-dimensional arrays via NumPy has been
included. Python also helps in visualization via matplotlib. The topic has
also been presented in section IV.

Harsh Bhasin
June 2023
SECTION I
ALGORITHMIC PROBLEM-SOLVING AND
PYTHON FUNDAMENTALS

This section deals with algorithms and introduces Python. It contains three
chapters namely “Introduction to Algorithms,” “Introduction to Python,”
and “Fundamentals.” The first chapter presents the definition of an
algorithm, the features of a good algorithm, and the ways of writing an
algorithm. The asymptotic complexity has also been discussed in the
chapter. The chapter also discusses the differences between recursive and
iterative algorithms. Algorithms of some common problems have also been
included in this chapter. The second chapter introduces Python. The
features of the language, its chronology, and its applications have been
discussed in the third chapter. The chapter also presents a brief overview of
the control structures used in Python. It also describes the installation of
Anaconda, which is an immensely popular Data Science platform. These
chapters are the building blocks of the chapters that follow.
CHAPTER 1

ALGORITHMIC PROBLEM-
SOLVING

Objectives

After reading the chapter, the reader should be able to


Understand the importance of algorithms.
Understand the features of a good algorithm.
Understand the ways of writing an algorithm.
Understand asymptotic notations.
Differentiate between recursive and iterative algorithms.

1.1 INTRODUCTION
This chapter introduces problem-solving and algorithms. Let us begin our
discussion by understanding the term algorithm. The word algorithm comes
from “algorithmi,” from the title “Algoritmi De Numero Indorum,” a book
written by Muhammad Ibn Musa Al-Khwarizmi, who was a Persian
Mathematician. The word was corrupted and became “Algorism.” Finally,
in the nineteenth century, it became algorithm. Interestingly, the book stated
above was on Indian numerals. Lately, the word algorithm is identified with
any procedure applied to accomplish a given computing task.
An algorithm directs how to solve a problem and there can be many
algorithms to solve the same problem. However, not all of them are
effective and efficient. Also, it is desirable that in the sequence of steps for
accomplishing a task, each step should be as basic as possible. The task
should be completed in a finite number of steps. So, a good algorithm
should be finite, and each instruction should be unambiguous.
Algorithms are implemented using programming languages. However,
designing an algorithm cannot be automated as it is, an art [1]. Art cannot
be automated, but you can at least learn approaches like Divide and
Conquer, Backtracking, Branch and Bound, Dynamic programming, Greedy
approaches, etc. Learning these approaches would not only help you in
Computer Science but also help in other disciplines like Computational
Biology, Finance, etc.
Algorithms are used everywhere, right from your set-top box to the
machine that gathers biometric data. The advancements in the field of
algorithms have changed the lives of millions. The page rank algorithm of
Larry Page has helped in the creation of Google, which is a part of our life.
The routing algorithms allowed packets to be transferred from one
computer to another via the shortest paths and helped in the advancement of
communication. Likewise, the pre-processing algorithms for magnetic
resonance imaging have helped scientists to develop computer-aided
techniques for the diagnosis of diseases. The conventional techniques
clubbed together with the latest advancements like Deep Learning have
been able to solve many problems in the society.

1.2 DEFINITION AND CHARACTERISTICS


Having seen the importance of algorithms, let us now move to their formal
definition and understand their features. An algorithm is a sequence of steps
used to accomplish a given task. It processes the input and generates some
output. The most essential elements of an algorithm are input, output,
correctness, efficiency, and definiteness.
The number of input arguments can even be zero. For example, some of
the pseudo-random number generators, do not take any argument to
generate a random number. However, there must be at least one output. The
first thing that should be taken care of while designing an algorithm is its
correctness. An algorithm that is not correct, is of no use. No amount of
fancy controls or sophisticated techniques can replace correctness. Also,
there can be numerous ways to solve a given problem but not all of them
are equally efficient.
The efficiency of an algorithm is also important. The algorithm should
be efficient both in terms of time and space. That is, it should take the
minimum possible time and space. For example, linear search and binary
search are the two most important techniques of searching. The first takes
O(n) time, while the second takes O(log n) time. That is, a list having 1024
elements would take time of order of 1024 units, in the case of linear
search, and would take time proportional to 10 units, in the case of binary
search. Hence, the choice of an efficient algorithm is immensely important
to make an effective model. The meaning of O has been explained in
Section 1.5.
The above discussion can be summarized as follows:
an algorithm takes zero or more input,
it produces at least one output,
it must be correct,
it should be efficient, both in terms of memory and space, and
it should not be ambiguous.

1.3 NOTATIONS: PSEUDOCODE AND FLOW CHART


In order to appreciate the discussion, let us come back to the example of
linear search. In linear search, a list is searched for an item by looking for
the item iteratively, that is at each position of the list. The algorithm for
linear search can be stated as follows (Algorithm 1). Table 1.1 shows the
conventions used for writing algorithms, in this book. The algorithm can
also be represented as a flow chart as shown in Figure 1.1. Pseudocode and
flow chart are the two most commonly used ways of representing an
algorithm. The third way of writing an algorithm can be English-like.
However, this is not preferred, as it can be ambiguous.
Algorithm 1: Linear Search
Input:
List: L
Length of the list: n
Item to be searched: item
Algorithm: Linear Search
Set i=0;
Set Flag=0;
While (i<n)
{
if (L[i]==item)
{
Print("Item found at ",i);
Flag=1;
}
i++;
}
if(Flag==0)
{
Print("Not found");
}
}

Linear Search: Flow Chart


FIGURE 1.1 Flowchart for linear search.

Linear Search: English-Like

1. Set Flag=0
2. Set the value of i to 0 and start scanning the items of the list. If the item
to be searched is found, set Flag to 1.
3. If Flag==0, then print “Not Found”.

TABLE 1.1 Conventions used in algorithms.


1.4 STRATEGIES FOR PROBLEM-SOLVING:
RECURSION VERSUS ITERATION

Algorithms can be recursive or iterative. Recursion is the invocation of a


function inside that function. In order to develop a code using recursion,
one must express a function in terms of itself (with reduced values of the
parameters) and should specify the base condition(s) to serve as the
stopping criteria. For example, the nth Fibonacci term can be expressed as
the sum of the (n-1)th and (n-2)th Fibonacci terms. Since, the evaluation of
nth Fibonacci term requires two previous results of evaluation, two base
conditions must be specified. The first and the second terms of this
sequence are 1 and 1. Therefore the function can be written as follows.
fib(n) = fib(n – 1) + fib(n – 2)
fib(1) = 1
fib(2) = 1
That is, to find the fifth Fibonacci term, we need to find the sum of the
fourth and the third term. The fourth Fibonacci term can be found by adding
the third and the second term. The third Fibonacci term can be found by
adding the second and the first term, both of which are 1. The process has
been depicted in Figure 1.2.

FIGURE 1.2 The evaluation of the fifth Fibonacci term.

Though recursion provides graceful solutions and a way to define a


function mathematically, it is hard to get hold of the way problem is solved
using recursion. As a matter of fact, debugging an intricate program, that
uses recursion, is difficult. Moreover, it is inefficient as it uses function
calls.
However, some problems like the in-order, the pre-order, and the post-
order traversals of trees; the Depth First Search and Breadth First Search of
graphs; binary search, Quicksort and Merge sort, etc., can be easily solved
using recursion. It may be stated here that a problem that can be solved
using recursion can also be solved iteratively.
Recursion uses run-time-stack, which provides a Last-In-First-Out
access. In order to understand this, let us consider the example of
calculating factorial using recursion. The factorial of a number can be
calculated using the following formula.
fac(n) = n * fac(n – 1)
fac(1) = 1
Evaluating fac(3) would require multiplying fac(2) with 3. The
evaluation of fac(2) would require multiplying fac(1) with 2. The value of
fac(1) is 1. So, in the above example, fac(3) calls fac(2) which calls fac(1).
When fac(1) ends, the run-time-stack stores the location of fac(2) to return
to fac(3). Likewise, when fac(2) ends the run-time-stack stores the location
of fac(3) to return to fac(4). The run-time-stack makes backtracking easy.
Chapter 7 deals with recursion in detail.
Another example of recursion is the calculation of the power of a given
number. The power of a number can be calculated using iterative algorithms
as shown in program 1. In the program, the variable p is initialized to 1. The
loop runs b times and each time a is multiplied by p. It may be stated here
that the syntax and the nitty-gritty of programming have been introduced in
the following chapters. However, the reader can revisit this section after
completing the next two units.
Program:
a=int(input('Enter the first number\t'))
b=int(input('Enter the second number\t:'))
p=1
i=1
while (i<=b):
p=p*a
i+=1
print(a, ' to the power of ', b, 'is ',p)

Output:
Enter the first number : 2
Enter the second number :10
2 to the power of 10 is 1024

The above task can also be accomplished using recursion. The


following formula can be used to find a to the power of b.

ab = (ab/2)2, if b is even and

ab = (a(b-1)/2)2 × b, if b is odd
The logic has been implemented in the following program. The output
follows.
Program:
def pow (a, b):
if b==1:
return a
elif b%2==0:
return (pow(a, b/2)**2)
else:
return ((pow(a, int(b/2))**2)*a)
pow(5,1)
pow(5,2)
pow(5,3)
pow(5,4)

Output:
5
25
125
625
3125

1.5 ASYMPTOTIC NOTATION


An algorithm can be analyzed by considering its best and worst case. For
example, in linear search, the best case would be finding the element at the
very first position of the list. The worst case of this algorithm would be the
case where the element is found at the last position or is not found.
The asymptotic growth of a function can be defined in terms of its input
size, for a sufficiently large value of the input size, n. The asymptotic
notations can be used to compare the running time or the space requirement
of algorithms. The best-case running time of an algorithm can be depicted
by its lower bound and the worst-case running time can be depicted by its
upper bound. The lower bound would be henceforth represented by big
omega, that is, Ω(). The upper bound would be henceforth represented by
big Oh, that is, O(). The formal definition of the two follows.
Big O: O()
The worst-case behavior of an algorithm is depicted by the asymptotic
upper bound notation. For any two functions f(n) and g(n)
O(g(n)) = f(n), for all n > 0 and
f(n) ≤ c × g(n)
Omega: W()
The best-case behavior of an algorithm is depicted by the asymptotic lower-
bound notation. For any two functions f(n) and g(n)
W(g(n)) = f(n), for all n > 0 and
f(n) ≥ c × g(n)
Theta: Q()
The asymptotically tight bound for a function f(n) can be defined as follows.
For any two functions f(n) and g(n).
θ(g(n)) = f(n), for all n > 0 and
c1× g(n) ≤ f(n) ≤ c2× g(n)
It may also be noted that,
f(n) = O(g(n)) and
f(n) = W(g(n))
then,
f(n) = q(g(n))

1.6 COMPLEXITY

The algorithm should be efficient both in terms of memory and time. That
is, an algorithm should take the least amount of space and time. In order to
understand the concept, let us consider five different algorithms to solve the
same problem. Assume that the number of elements given as input to the
algorithm is n. The first algorithm takes time proportional to n to
accomplish the given task (O(n)), the second algorithm takes time
proportional to n2 to do the same task (O(n2)), the third takes time
proportional to n3(O(n3)), the fourth takes time proportional to log(n)
(O(log n))and the fifth takes time proportional to n log(n), that is O(n log
n). This implies that, if the number of elements doubles, the time taken to
accomplish the given task by the first algorithm would double, by the
second algorithm would be four times, the third algorithm eight times, and
the increase in time of the fourth would be less than the increase in the first
and the increase in the time by the fifth would be less than the increase in
the second. Therefore, the order of the time complexity would be as
follows:
O(log n) < O(n) < O(n log n) < O(n2) < O(n3)
For example, linear search described in the following section takes O(n)
time whereas binary search takes O(log n) time. Therefore, binary search
takes lesser time as compared to linear search. Merge sort and bubble sort
are the two most popular algorithms for sorting. The merge sort takes O(n
log n) time and bubble sort takes O(n2) time. Therefore, Merge sort has
lesser time complexity vis-à-vis bubble sort and is hence better.

1.7 ILLUSTRATIONS

Having seen the definition, characteristics, and notations used for writing an
algorithm, let us now move to some basic examples. This section presents
four problems and their solutions.

1.7.1 Minimum in a List

Illustration 1.1:
Given a List, L. Write an algorithm to find the minimum valued element in
the list.
Solution:
Let the first element of the list be the minimum valued element (“min” =
L[0]). The list is scanned from left to right. At any point, if we are able to
find an element having a value less than the value stored in “min,” the
value of that element is stored in the variable “min,” The min1 function
performs the requisite task.
Algorithm:
def min1(L):
{
min=L[0];
i=0;
while(i<len(L))
{
if(L[i]<min)
{
min=L[i];
}
i+=1;
}
return min;
}
Test:
min([51,12,71,91,13,19])

Output:
12

1.7.2 Insert a Card in a Pack of Cards (Or Insert an element in


a sorted list). There are ten cards in the pack, numbered
from 1 to 10.

Illustration 1.2:
It is required to insert a card in an ordered pack of cards. The above
problem can also be stated as follows. Given a sorted list, insert an item at
its appropriate position.
Solution:
The given list is sorted and the given item is to be inserted at its appropriate
position. We begin with the last element and shift each element one position
to the right, till an item, smaller than the given item is found. This is
followed by the insertion of the given item at the position.
Algorithm:
def insert(L, item)
{
//L is a sorted list and item is the number to be inserted
n=len(L); //The len function finds the length of the given
list
i=n;//set i to the last position
while(L[i]>item)
{
L[i+1]=L[i];
i=i-1;
}
L[i+1]=item;
print(L)
}
Test:
insert([1,3,4,6,8,9],7)

Expected Output (Implementation in Python):


[1, 3, 4, 6, 7, 8, 9]

1.7.3 Guess a Number in a Given Range

Illustration 1.3:
The computer generates a number, in a given range and you are required to
guess it within 10 trials.
Solution:
The algorithm requires a pseudo-random number generator. The user enters
a range and the program generates a random number in that range. The
computer guides the user, telling the user if the correct number is lesser or
greater than the number guessed by the user. The user is allowed only ten
trials.
Algorithm:
GuessNumber()
{
import random;
n = 0;
//ask the user to enter two numbers

Expected Output
Hi there! I will guess a number between the range entered by you:
1.7.4 Tower of Hanoi
Tower of Hanoi requires the transfer of n disks of increasing sizes kept in
the source peg to the destination peg, moving one disk at a time, in a way so
that a larger disk should not be placed on a smaller disk at any point in time.
The following example illustrates the process. The value of n in this
example is three. Note that in none of the steps, a larger disk is placed
above a smaller disk (Figures 1.3–1.9).
FIGURE 1.3 Initially the first peg (source) has all three disks which are to be transferred to
the second peg (destination).

FIGURE 1.4 Move the smallest disk to the second peg.

FIGURE 1.5 Move the second largest disk to the third peg.

FIGURE 1.6 Move the smallest disk to the third peg and the largest disk to the second peg.
FIGURE 1.7 Now move the smallest disk to the first peg.

FIGURE 1.8 Move the second largest disk to the second peg and place it above the largest
disk.

FIGURE 1.9 Now place the smallest disk above the second largest disk.

Illustration 1.4:
Write an algorithm for the solution to the Tower of Hanoi problem.
Algorithm:
def towerOfHanoi(n, source, destination, intermediate)
{
if(n==1)
{
print("Move ",n," from ", source, " to ",destination);
}
else
{
towerOfHanoi(n-1, source, intermediate, destination);
print("Move ",n," from ", source, " to ",destination);
towerOfHanoi(n-1, intermediate, destination, source);
}
}

Test:
towerOfHanoi(1,'A','B', 'C')

Expected Output
Move 1 from A to B
Test:
towerOfHanoi(2,'A','B', 'C')

Expected Output
Move 1 from A to C
Move 2 from A to B
Move 1 from C to B

Test:
towerOfHanoi(3,'A','B', 'C')

Expected Output
Move 1 from A to B
Move 2 from A to C
Move 1 from B to C
Move 3 from A to B
Move 1 from C to A
Move 2 from C to B
Move 1 from A to B

Test:
towerOfHanoi(4,'A','B', 'C')

Expected Output
Move 1 from A to C
Move 2 from A to B
Move 1 from C to B
Move 3 from A to C
Move 1 from B to A
Move 2 from B to C
Move 1 from A to C
Move 4 from A to B
Move 1 from C to B
Move 2 from C to A
Move 1 from B to A
Move 3 from C to B
Move 1 from A to C
Move 2 from A to B
Move 1 from C to B

1.8 CONCLUSION

Algorithms are the set of steps used to accomplish a given task, efficiently
and effectively. An algorithm must be definite, and each instruction should
be unambiguous. There are many ways of representing the steps to
accomplish the given task: by simply writing the instruction in English, by
drawing the flowchart, or by writing the pseudocode. An algorithm must
generate at least one output. Moreover, a good algorithm should be efficient
both in terms of memory and computation time. The asymptotic complexity
helps us to ascertain the efficiency of an algorithm. Problem-solving using
algorithms is an involved process and requires due deliberation and intricate
analysis. Some algorithms like linear search, binary search, etc., have been
presented in this chapter. Readers, new to programming, may find it
difficult to get hold of some of the procedures presented in this chapter.
However, they should cover the procedural programming presented in
Section II of this book and revisit this chapter. This chapter is a door to the
fascinating world of problem-solving and Python would be your friend in
this long journey. So, let us meet our new friend “Python” in the next
chapter.

GLOSSARY
Algorithm: Set of steps written to accomplish a given computing task.
Features of a good algorithm: Correctness, Definiteness,
Unambiguity, Input, and Output.

POINTS TO REMEMBER

Correctness should be the priority in designing an algorithm.


An algorithm should be
– definite,
– unambiguous, and
– efficient.
Binary search is better for a sorted list.
Big Oh notation represents the upper bound.
Theta is the tight bound.

EXERCISES

Multiple Choice Questions

1. An algorithm should be
(a) Definite
(b) Unambiguous
(c) Both (a) and (b)
(d) None of the above
2. In which of the following algorithms, an input argument may not be
required?
(a) Linear search
(b) Binary search
(c) Pseudo-random number generator
(d) None of the above
3. Which of the following can be used, if the input list is sorted?
(a) Linear search
(b) Binary search
(c) Both are equally efficient
(d) Depends on the input constraints
4. Which of the following would not work if the input array is not sorted?
(a) Linear search
(b) Binary search
(c) Both (a) and (b)
(d) Depends on the problem
5. In a recursive algorithm
(a) The function needs to be expressed in terms of itself
(b) The base case must be stated
(c) Both of the above
(d) None of the above
6. Generally, which of the following has more time complexity?
(a) Recursive algorithm
(b) Iterative algorithm
(c) Both (a) and (b)
(d) None of the above
7. Which of the following represents the upper bound?
(a) Big Oh notation
(b) Omega notation
(c) Theta notation
(d) None of the above
8. Which of the following represents the lower bound?
(a) Big Oh notation
Random documents with unrelated
content Scribd suggests to you:
This eBook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the Project
Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or providing


access to or distributing Project Gutenberg™ electronic works
provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™


electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for


the “Right of Replacement or Refund” described in paragraph 1.F.3,
the Project Gutenberg Literary Archive Foundation, the owner of the
Project Gutenberg™ trademark, and any other party distributing a
Project Gutenberg™ electronic work under this agreement, disclaim
all liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR
NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR
BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH
1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK
OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL
NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF
YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of receiving
it, you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or
entity that provided you with the defective work may elect to provide
a replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.

1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation,


the trademark owner, any agent or employee of the Foundation,
anyone providing copies of Project Gutenberg™ electronic works in
accordance with this agreement, and any volunteers associated with
the production, promotion and distribution of Project Gutenberg™
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of the
following which you do or cause to occur: (a) distribution of this or
any Project Gutenberg™ work, (b) alteration, modification, or
additions or deletions to any Project Gutenberg™ work, and (c) any
Defect you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.

The Foundation’s business office is located at 809 North 1500 West,


Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many
small donations ($1 to $5,000) are particularly important to
maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws regulating


charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states where


we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot make


any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.

Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose network of
volunteer support.
Project Gutenberg™ eBooks are often created from several printed
editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we do not
necessarily keep eBooks in compliance with any particular paper
edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how
to subscribe to our email newsletter to hear about new eBooks.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like