Getting Started With Python
When stepping into the world of Python programming, one of the first concepts you will encounter is identifiers, the names that give meaning to your code. Python’s powerful, flexible types system offers a vast range of options from numbers to strings, helping define how data is stored and manipulated. Every object in Python tells its own story, and as you work with variables and create assignment statements, you will see how effortlessly Python handles complex data. Whether it’s handling multiple or pairwise assignments, efficiently deleting a name or adhering to naming conventions for constants, Python’s simplicity and precision make it a developer’s favorite tool. Let’s dive deep into these foundational concepts that drive the language.
Check out the code bundle here: https://github.com/codeaihub1998/Ultimate_Python_1-to-21
Table of Content
- Identifiers
- Python Types
- Objects
- Variables and assignment statement
- Multiple and Pairwise Assignments
- Deleting a name
- Naming convention for constants
Before you start writing programs, it is important to have a strong base in the
fundamentals of Python. This section will introduce you to the basic
concepts and building blocks that are used to construct a Python program.
While many of the concepts presented in this section will be explored in
more depth later in the sections, it is important to familiarize yourself with
certain terms right from the beginning. This section will provide a gentle
introduction to these terms and offering you a solid foundation to build upon as
we move to more comprehensive discussions in the following sections.
In this section, you will learn how to name things in Python, what type your
data can be, what operators you can use, how to input and output data from
your program, how to structure your program and many more things. Even
if you have programmed in any other language before, the subject matter
presented in the section will prove to be useful because you will find that
Python operates differently in many aspects. If you dive into coding without
having a solid foundation, you will always find yourself looking back at the
basics. While you may manage to make your programs work to some extent,
you will lack a comprehensive understanding of how they work and the
underlying processes going on. A strong grasp of the fundamentals will serve
as a solid framework for further exploration and growth in your Python
programming journey.
Identifiers
As you start writing programs, you will create different program elements
like variables, functions, classes, modules, instance objects, etc. To identify
these elements in a program, you will have to give them some names. These names are called identifiers as they are used to identify program elements.
There are some rules and conventions for naming identifiers. You have to
follow the rules to prevent any errors and make your program work.
Following the conventions increases the readability of your code and makes
it easier to understand and maintain. Let us first see the rules for naming
identifiers.
- The first character should be a letter or an underscore.
- The rest of the characters can be any combination of letters (A to Z, a
to z), digits (0 to 9) and underscores. Special characters like @, %, $,
#, & are not allowed. - There is no limit on the length of an identifier.
- Identifiers are case-sensitive. For example, marks, Marks and
MARKS are considered different identifiers.
Here, are some examples of valid and invalid identifiers.
Valid
- p
- part3
- min_length
- Student
Invalid
- cost$
- min-length
- 3rd_part
- cost
- price
cost$ is invalid as it contains the illegal character dollar sign, min-
length is invalid as it contains the illegal character dash, 3rd_part is
invalid as it starts with a number, and cost price is invalid as it contains
a space.
There are some special words that programmers cannot use for naming their
program elements even though they satisfy all these rules. Here, is the list of
those words.
False class from or
None continue global pass
True def if raise
and del import return
as elif in try
assert else is while
async except lambda with
await finally nonlocal yield
break for not
You cannot use any of these words for naming your program elements. For
example, you cannot have a variable named import or a function named
raise. These names are reserved by the language for specific purposes;
they are called keywords of the language. These keywords have predefined
meanings in the language so you cannot use these names for naming your
program elements. You can see the list of keywords in the interactive shell
by using help.
>>> help('keywords')
These were the rules that need to be followed while naming identifiers. Now,
let us see some conventions.
It is good to choose meaningful and descriptive names for identifiers. The
name should indicate the purpose; for example, a variable name should
describe the contents of the variable, a function name should indicate what
the function does, and so on. This approach makes your code self-documenting and therefore, easy to understand. For example,
shortest_path and spath are both valid identifiers but the former
makes more sense. Similarly, min_height is better than mheight.
However, there are some exceptions where single-letter or abbreviated
names are fine. For example, names like i, j, k are generally used for loop
indices. When names have to be used in big and complex expressions, longer
names would make the code harder to read so in these cases also we can
think of shorter names.
We have seen that spaces are not allowed in identifiers, so when we need
names with multiple words, we can use underscore as the word separator
(eg. marks_maths, calculate_tax). For most of the names, all
lowercase letters are used, but for class names, we generally use the
CapWords convention, in which the initial letters of all the words are
capitalized. As we proceed through the sections and get introduced to
different program elements, we will see the naming conventions for them.
There are some built-in names, like all, any, print, sum, max, etc. that
you should not use as identifiers, although Python will not complain if you use them. Using these names as your identifiers will overwrite the built-in
names and may cause subtle problems in your program. To view the built-in
names.
>>> dir(__builtins__)
When you write your program, you will notice that the editor will highlight
different terms in your program with different colors. For example, IDLE
will highlight the keywords and built-in names in orange and purple colors,
respectively. This feature of text editors is called syntax highlighting. They
can recognize the category of a term and highlight it accordingly. So, in
IDLE, if a word is highlighted in orange, it means that it is a keyword and
you cannot use it for your identifier name, if you try to do so, you will get an
error. If a word is highlighted in purple, it is a built-in name, and it is better
not to use it for your identifiers.
Another convention is to avoid names that start with single or double leading
underscores. However, a single underscore on its own can be used as an
identifier and it has special meaning in the interactive mode.
Python Types
The programs that we write mainly store and process data and data can be in
different forms, it can be numeric, text, or a list. Data can be categorized and each category is called data type or simply type. A data type represents a
domain of values and a set of possible operations that can be performed on
those values. For example, for integer data type, the domain of values
contains all integers, and the set of possible operations are addition,
subtraction, multiplication etc. The data types that are predefined in Python
are called built-in data types. Python has a variety of data types that you can
use to represent your data.
- integar
- float
- complex
- string
- boolean
- list
- tuple
- set
- dictionary
You can also define your own types by combining these types. We will see
how to do that later when we learn how to define classes. In this section, we
will look at some of Python’s basic built-in data types. Before looking at
Python types, let us see what the term literal means. A literal is a notation for a constant value of some built-in type. A literal can be a number or some
text that appears in a program, it is just a value.
- 12
- 35.2
- 'hello'
- True
12 is a literal of type int, 35.2 is a literal of type float, 'hello' is a
literal of string type str, and True is a literal of boolean type bool. Now,
let us see the types in detail. The first one that we will see is int type.
- 34
- 123
- 1233
- 6532216
Integer values can be arbitrarily long. There is no limit on the size of
integers in Python. In practice, they are limited by the size of your
computer’s memory. If we enter an int literal on the interactive prompt, it
prints the literal back. We can also perform simple arithmetic operations on
integers at the interactive prompt.
>>> 25
Output
25
>>> 3 + 42
Output
45
>>> 6 ** 200
Output
426825223812027400796974891518773732342988745354489
429495479078935112929549619739
019072139340757097296812815466676129830954465240517
595242384015591919845376
In the last example, we are performing an exponentiation operation which
gives us the value of 6200. We can have such big integers in Python, they can
be of unlimited size. While performing arithmetic calculations on integers,
we do not have to think about overflow.
By default, the integer literal values are expressed in decimal base number
system, but they can also be expressed in hexadecimal, octal or binary
base.
- In Hexadecimal form — (Base 16) Prefix 0x (or 0X)
- In Octal form (Base 8) — Prefix 0o (or 0O)
- In Binary form (Base 2) — Prefix 0b (or 0B)
If you want to express an integer value in hexadecimal then you have to
prefix the value with zero and letter x for octal, you have to prefix the value
with zero and letter o; and for binary, you have to prefix the value with zero
and letter b.
- 0x1abc
- 0X1ABC
- 0o1776
- 0b11000011
The first 2 integers are expressed in hexadecimal, the third integer is in octal
base and the fourth one is in binary base. If you enter these numbers on the
interactive prompt, it will print them in decimal form.
>>> 0x1abc
Output
6844
>>> 0X1ABC
Output
6844
>>> 0o1776
Output
1022
>>> 0b11000011
Output
195
Floating-point values are numbers with a decimal point and an optional
exponent represented by lowercase or uppercase E.
- 2.34
- 5.8
- 3e5
- 7.2e42
- 6.5E-24
When the letter e or E is used, the floating-point value is said to be in
scientific notation. This letter separates the number from the exponent. You
can easily represent very large or very small values using this notation. For
example, the value 6.54e25 denotes 6.54 x 1025, which is a very big
number and the value 5.32e-13 denotes 5.32 x 10-13, which is a
very small number.
In general mathematics, we use commas in large numbers for clarity for
example, we would write one million as 1,000,000. In Python, commas are
not allowed inside numbers, but you can use underscores to separate the
digits of numeric literal values so that you can write 1 million as 1_000_000. This feature was added in 3.6 to enhance the readability of
numeric values.
- 45_345_678
- 0x_234_CAB
- 0o_231_354
- 23_456.678_566
Python supports a Boolean type bool, which takes a value of either True
or False. These are the only literal values for bool type. The first letter is
capitalized in both True and False and both of these are keywords. bool
type is generally used in comparisons; we will see it in detail when we learn
about operators.
The complex number type is mostly used in scientific applications. Complex
numbers have a real part and an imaginary part. The imaginary part is
denoted with a suffix of lowercase or uppercase J.
- 3 + 5j
- 2 + 4j
- 3 + 6j
The string type str is the most commonly used type. We will explore
strings in detail in the next chapter. We have already used strings inside the
print function. A string is just a group of characters placed inside a pair of
quotes. In Python, you can enclose a string literal within a pair of single
quotes (’...’) or a pair of double quotes ("..."). You can even use triple
quotes, but the most commonly used delimiters are single quotes.
- 'Bareilly'
- '430164'
- '$129'
- 'Enter your
name: '
Python has a special type NoneType, which can be used to represent no
value or nothing. It has a single literal value None. There is only one None
object and all references to None refer to that same object. So, whenever
you want to make any null object in your program, you can use None.
You can use the built-in type function to check the type of any value.
>>> type(23)
Output
<class 'int'>
>>> type(True)
Output
<class 'bool'>
>>> type(2.3)
Output
<class 'float'>
>>> type('hi')
Output
<class 'str'>
>>> type("Hello")
Output
<class 'str'>
>>> type(None)
Output
<class 'NoneType'>
Objects
Everything in Python is implemented as an object. Any data value you write,
like any number or a string, is an object. Program elements like functions,
classes, and modules are also implemented as objects. An object is just a
chunk of memory used to store some data. So, objects are Python’s
abstraction for data.
Whenever we write any literal value in our program, Python identifies its
type because of its notation and creates an object of the appropriate type. If it
sees a sequence of digits, it will create an int object; if it sees text inside
quotes, it will create a str object. For example, if we write the literal 56 in
our program, Python recognizes it as an integer literal and creates an object
of type int. Similarly, for the string literal 'Hello’, it creates an object of
str type.
Python uses objects to hold data values. Every object has a type, a value and
an identity. For the first object, 15031263572 is the identity or the id, 56
is the value, and the type is int. For the second object, 18043139781 is
the id, 'Hello' is the value, and str is the type. The value of an object is
the data that it contains, and the type of an object determines what kind of operations can be performed on the value. For example, we can slice str
values but not int values, and we can divide two int values but not str
values.
The identity(id) of an object is an integer that is guaranteed to be unique
among simultaneously existing objects. Each object in our program will
have a different id which will never change during its lifetime. An object is
stored in memory, and typically, the identity of an object is the memory
address of that object, i.e., the location in the memory where the object is
stored. We can use the built-in id() function to get the identity of an object
in our program.
Variables and Assignment Statement
We have seen that Python uses objects to store values. If we want to work
with a value later on in our program, we can associate a name with the object
that contains the value. So, objects contain values, and to access these
objects and manipulate them in our program, we can create names and bind
them to objects. In the following example, the name x is bound to int
object with value 56 and the name p is bound to the str object with value
'Hello’.
Whenever we write the name x in our program, the value 56 will be used and whenever we write p, the string 'Hello' will be used. The names x
and p are variables. In Python, variables are just names that refer or point to objects; the actual data is contained in the objects. So, objects are chunks
of memory that store the actual values, and variables are names that link to
objects by storing the memory address or location of the object. We can
think of variables as object references, they are just names attached to
objects.
Now, let us see how to create a variable in our program and bind it to an
object. For that, we need to write an assignment statement.
>>> x = 56
When Python executes this statement, it creates an object of type int with
value 56. It also creates a variable named x and will make that variable refer
to this object, or we can say that it binds the name x to this object. After the
execution of this statement, whenever x appears in an expression, it will be substituted with the value of the object that is bound to the name x. The
value 56 is contained within the object and we can refer to the object by
using the name x. At the prompt, typing just the name of the variable will
display its value. In the program file, we have to use the print function to
print the value of the variable on the output screen.
>>> x
Output
56
>>> print(x)
Output
56
Since x refers to an int object, we can perform all operations on x that
make sense for int type.
>>> x + 5
Output
61
If we send a variable to the type() or id() function, we will get the type
or id of the object that the variable is currently referring to.
>>> type(x)
Output
<class 'int'>
id(x)
Output
15031263572
This statement will create an object of type str with the value
'hello’ and it will create and bind the variable named p to this object.
>>> p = 'Hello'
Now, whenever we write p, it will give us the value of the object bound to
the name p.
>>> p
Output
'Hello'
>>> print(p)
Output
Hello
Variables x and p will be available in the interactive session until we exit it. This assignment statement will create a new variable named z.
>>> z = x
The name z will also refer to the same object to which x is referring.
Now, both x and z refer to the same object, so now, we can access this object by any of these two names. We have created an alias for x.
This assignment statement creates one more variable named y and
it is bound to the object to which the name z is bound.
>>> y = z
Now, all three variables, x, y and z are bound to the same object, and any
of them can be used to access the underlying object. This is known as object
sharing or aliasing.
>>> x
Output
56
>>> y
Output
56
>>> z
Output
56
When we apply the id function to a variable name, we get the identity of the
object that the variable is referring to. The following output proves that all
three variables, x, y, and z refer to the same object.
>>> id(x)
Output
15031263572
>>> id(y)
Output
15031263572
>>> id(z)
Output
15031263572
Any variable can be made to refer to another value that is why it is called a
variable. Let us see what happens when we try to change x by writing the
following assignment statement.
>>> x = 25
A new integer object with value 25 will be created and the variable x will
refer to this newly created object.
The first time, when x appeared on the left-hand side of the assignment
statement, the variable name x was created and was bound to an object. The
second time, when x appeared on the left-hand side of the assignment
statement, the name x already existed, so this time, it was rebound to an
object. Now the value of x is 25 and its id has also changed.
>>> x
Output
25
>>> id(x)
Output
15031264562
Can you guess what happens when we write this assignment
statement?
>>> z = z + 3
First, the expression on the right-hand side is evaluated, the value of z is 56,
56+3 is 59 and the value on the right-hand side is 59, so a new int object
with value 59 is created and z is now bound to this new object.
The statement z = z + 3 does not in any way change the object that z
was referring to originally instead, it rebounds z to another object. The
variable y is still referring to the object with value 56. Now, we write this statement.
>>> y = 3.6
A new float object is created, and y is now rebounding to this object.
Variable names have no types associated with them. They are just names
and they can refer to any type of object. The variable y was initially
referring to an int; now it is referring to a float. You can make it refer to
any other type of object later on. This is why Python is called a dynamically
typed language. A variable in Python can be associated with any type of
object and it can later be rebound to any other type of object. To see the type
of the object that a variable is currently referring to, we can use the type
function.
>>> type(y)
Output
<class 'float'>
We can see that the object 56 has been orphaned there is no variable name
referring to it. Python will notice this and its garbage collector will
automatically remove it from the memory. The memory that was occupied
by this object can be used for some other purpose.
In our examples, we have taken single-lettered variables. In real
applications, variables with more meaningful names will be used. While
naming variables, we need to follow the same general rules that we had seen
in naming identifiers. The convention for naming variables is to use
lowercase letters with underscores separating words.
- area
- marks_in_english
- total_marks
- simple_interest
If you have programmed in C, C++, or Java, you might be wondering how
we can use a variable without declaring it in advance. These languages are
statically typed; they require you to declare a variable along with its type
information before it can be used in the program, and once you declare a
variable, you can never change its type. For example, if you declare a
variable of type float, it will be a float for the whole duration of the program and you can store only float values in it. So, in these languages, variables
have predetermined types and a variable can be used to hold values of only
that type. Python is a dynamically typed language, so there is no need to
declare the type of a variable. Variables do not have fixed types in Python, they are generic in nature. Instead, objects have types. A variable is just a
name and it can refer to any type of object.
In statically typed languages, a variable is considered as a storage box that
can store a value of a specific type. The variable names represent fixed
places in memory, and we need to declare the type because the amount of
space reserved depends upon the type. In Python, a variable is visualized as
a kind of label or tag that can be attached to an object of any type. There is
no need to predeclare variables in Python as they automatically come into
existence when they are initially assigned (assigned first time) and there is
no need to specify a type because variables do not have any type associated
with them. The initial assignment introduces the name of the variable in the
program and binds it to an object, and all other future assignments to the
variable rebind it.
Multiple and Pairwise Assignment
We have seen that a variable can be created or rebound using a simple
assignment statement. More than one variable can be created or rebound in a
single assignment statement by using multiple and pairwise assignments.
We can assign multiple variables simultaneously with a common value. For
example in the following assignment, variables a, b and c are assigned in a
single line and all of them refer to the same object.
>>> a = b = c = 10
If any of these variable names do not exist before this assignment statement,
they will be created. Variables that already exist will be reassigned.
Pairwise assignment can be done by using commas.
>>> x, y, z = 1, 2.5, 3
The values 1, 2.5, and 3 are assigned to variables x, y and z respectively.
As usual, if this assignment is the first for any of these variables, then it will
be created and if the variable name already exists, then it will be reassigned.
For pairwise assignment, the number of variables on the left side should be
equal to the number of values on the right side.
Deleting a Name
The del statement can be used to delete a variable name. It consists of the
del keyword followed by the name that has to be deleted.
del name
Suppose we have three variables, x, y and z, referring to the same object.
To delete the variable name x, we can write the following statement.
>>> del x
This statement will unbind the name x from the object and will also delete
the name x. It will not delete the object referred to by x, which means that
it will not free the memory occupied by the object. An object will be
automatically garbage collected by Python only if there is no other name
referring to it, you can never explicitly destroy an object.
While the program is running, objects are automatically created and
reclaimed automatically when they become unreachable. This automatic reclamation of the space occupied by an unreachable object is called garbage
collection. It is done to free up space so that it can be used for other objects
that may be created later on in the program. This memory management is
automatically done by Python; programmers do not have to bother about
freeing up space that is no longer in use. There is no need to manage
memory manually by writing allocation and deallocation code that is
required in other languages like C and C++. In these languages, the
programmer is responsible for allocating and de-allocating memory. This is
error-prone and can cause memory leaks if not done properly. Automatic
garbage collection in Python reduces efforts and minimizes the chances of
memory management problems.
The process of garbage collection depends on the Python implementation
typically, a reference counting mechanism is used. In each object, a
reference counter is stored which keeps track of the number of references
referring to the object. When this number drops to 0, the object is
automatically reclaimed, which means that the memory allocated for the
object is freed. Programmers do not need to worry about how the garbage
collector works the whole process is hidden and automatic.
Continuing our example, suppose we delete the name y and reassign the
name z.
>>> del y
>>> z = 10
Now, there is no variable name referring to object 25, so it will be garbage
collected.
We can use the del statement to delete more than one name by using
commas.
>>> del a, b, c
The del statement is used very rarely; variable names have a lifetime and
they are deleted automatically when their lifetime is over. We will discuss
this later in the upcoming sections.
Naming Convention For Constants
In some languages, we can define names which cannot be reassigned. Once
they are given a value, they cannot be changed throughout the execution of
the program. They are called constants. In Python, there is no concept of
constants, there is no way to define names that cannot be reset to a different
value. All names in Python can be reassigned at any time. However, there is
a widely used naming convention to indicate that you do not want a name to
be reassigned. The convention is to use all capital letters with underscores separating words.
PI = 3.14159
MAXIMUM_SIZE = 100
RATE_OF_INTEREST = 5
Use all lowercase letters in the names of variables whose values might
change and use all uppercase letters for names that should never be
reassigned values. But remember that this is just a convention and not a
restriction, these names with all uppercase letters can be reassigned and the
interpreter will not complain. By using all caps, you are not instructing the
interpreter that it is a constant, you are telling the programmer that it should
be treated as a constant and should not be changed.
So, why do we need such names that do not change? We could just use the
literal value 3.14159 instead of the name PI or 100 instead of
MAXIMUM_SIZE. The reason is that they can help in documenting the
program. When you need to use these literals in many places, it is better to
give them a name. The number 100 does not give any real information,
while the name MAXIMUM_SIZE is clear and understandable. Using these
descriptive labels is better than literal numbers scattered throughout your
program.
Another reason is that they are good for code maintenance. Suppose that
after some time, you decide to change the maximum size from 100 to 150
then, you will need to change it at only one place where you have defined
this name. If you use the number 100 instead of this name, then you will
have to find every single place where this number 100 is used as e
maximum size and change it to 150 which is time consuming and
definitely error prone.
Conclusion
understanding the fundamental building blocks of Python identifiers, types and objects is crucial to mastering the language. Identifiers provide unique labels, while Python types and objects define the structure and behavior of data. Variables, through assignment statements, allow for dynamic control, making Python versatile in handling diverse tasks. Exploring multiple and pairwise assignments showcases Python’s elegance in simplifying complex operations. Deleting names ensures cleaner code, while following naming conventions for constants promotes clarity and consistency. Together, these foundational elements empower you to write efficient, readable and maintainable Python code, unlocking your full programming potential.