While loop

The while loop checks the condition before the block is executed, this control structure is also called pre-test loop.

In [1]:
n = 1000
a = 1
while a ** 3 < n:
    print(a ** 3, end=' ')  # to print them in one line
    a = a + 1
print("end")
1 8 27 64 125 216 343 512 729 end

Let's write a loop that reads numbers until a certain condition is met!

Example: Write a code that reads numbers until get 0, then stops and prints the sum of the numbers.

In [2]:
n = 0
a = float(input())         # input first
while a != 0:
    n = n + a
    a = float(input())     # input second
print(n)
1
2
0
3.0

In this program we repeated a part of the code!

Example: Rewrite the previous program without code repetition!

In [3]:
n = 0
while True:                 # beginning of the loop
    a = float(input())      # input and convert once, no repetition
    if a == 0:              # halt condition
        break               # exit out from the loop
    n += a                  # if the loop is continued (same as n = n + a)
print(n)
1
2
0
3.0

As you can see certain parts of the code is repeated: read the first number than read inside the while loop.

In other languages there is a do...while which checks the condition at the end of the loop. That one is called post-test loop. Two typical forms are

do ... while ...

or

do... until ...

This is missing from python by design. It can be replaced with the following:

while True:
    <preparation>
    if <halt condition>:
        break
    <further commands>

Basic programming elements

General purpose, commmon programming techniques.

Accumulation (summation)

If you have a series of numbers (or any other objects) and you want to collect (or accumulate) some information about them then you can use this paradigm.

Example: Calculate the sum of some numbers different from 0. Read the numbers from the standard input, where 0 means the end of sequence.

In [4]:
sum = 0                 # accumulator variable
while True:             # loop
    a = float(input())  # input and convert
    if a == 0:          # halt condition
        break
    sum += a            # summation
print(sum)
1
2
0
3.0

Question: What do we have to get if the sequence of numbers is empty?

Example: Multiply the numbers reading from the standard input. What de we have to get when the sequence of numbers is empty? Now, mark the end of the sequence with an empty string, that is, an empty ENTER in the input field. Beware, an empty string cannot be converted to a number!

In [5]:
prod = 1                # accumulator
while True:             # loop
    a = input()         # input
    if a == "":         # halt condition
        break
    prod *= float(a)    # convert and product
print(prod)
23
110

2530.0

Counting

For a series of objects we wish to count the number of elemnets with a given property.

Exercise: In a sequence of integer numbers not containing 0, count the odd numbers. The end of sequence is given by 0.

In [6]:
counter = 0             # counter
while True:             # loop
    a = int(input())    # input and convert
    if a == 0:          # halt condition
        break
    if a % 2 == 1:      # check the desired property
        counter += 1    # increase counter
print(counter)
1
11
111
2
4
0
3

Example: Read strings until an empty string arrives and count the words containing the letter ő !

In [7]:
counter = 0        
while True:
    string = input()
    if string == "":
        break
    if "ő" in string:
        counter += 1
print(counter)
erdő, mező
Erdős Pál
tree, forest, field

2

Finding extremum

For a given set of objects which are comparable, one wishes to find the best/worst element. E.g. it can be smallest/largest.

Example: Find the largest of some non negative numbers.

In [8]:
largest = 0              # default extremum
while True:              # halt condition
    a = float(input())   # read and convert
    if a <= 0:           # halt condition
        break
    if largest < a:      # compare to previous extremum
        largest = a      # update extremum
print("the largest =", largest)
12
432
1
-2
the largest = 432.0

Example: Change the code for any type of numbers (pozitive or negative). The empty input means the end of sequence.

In [9]:
largest = float('-inf')   # -∞ is the largest for an empty set
while True:               # loop
    a = input()           # input
    if a == "":           # halt condition
        break
    f = float(a)          # convert here!
    if largest < f:       # compare
        largest = f       # refresh the extremum 
print("The largest =", largest)
-234
-3
-55

The largest = -3.0

Find any

Find out if any of a given set of objects satisfy some condition.

Example: Write a prime testing program for integers greater than 1 with searching a divisor up to the square root of the given number.

In [10]:
n = int(input())                 # read a number
d = 2                            # d is iterating over the possible divisors
hit = False                      # remembers whether the condition is met
while d**2 <= n and not hit:     # halt if a divisor is found 
    if n % d == 0:               # is d a divisor?
        hit = True               # it's a hit
    d += 1                       # go for the next
if not hit:                      # n is prime if no divisor found
    print("The number {0} is a prime.".format(n))
else:
    print("{0} is a composite number.".format(n))
499
The number 499 is a prime.

Combining these programming elements

For more complicated tasks, you may combine the technics given above. It is not the only way to solve programming exercises but it's a good start. Feel free to experiment with different solutions.

Example: How many primes are there under 1000? Put a find any (prime test) inside a counting code!

In [11]:
num = 2                           # first number to check
primes = 0                        # counter
while num <= 1000:                # counting starts here
    divisor = 2                       # the embedded "find any" starts here
    composite = False                 # hit bool variable
    while divisor**2 <= num:          # loop for "find any"
        if num % divisor == 0:        # check for hit
            composite = True          # set hit variable
            break
        divisor += 1                  # next element to check in "find any"
    if not composite:             # if found 
        primes += 1               #         then increase the counter
    num += 1                      # the next number to check
print(primes)
168

Lists

Lists are containers for a sequences of objects. For example store numbers:

In [12]:
l = [1, 2, 5]
type(l)
Out[12]:
list

Don't call a list object list because it is already the name of the type!

The list can be given with a square bracket, the emelents are comma separated list between the brackets. The elements of the list can be various objects, not necessarily of the same type (even lists).

In [13]:
l = [1, 5.3, "dog", [1, 2, 5], 12, "cat"]
In [14]:
l
Out[14]:
[1, 5.3, 'dog', [1, 2, 5], 12, 'cat']

List indexing, sublists

A given element can be accessed by index:

In [15]:
l = ["a", "b", "c"]
print(l[0], l[1], l[2])
a b c

As you can see the list indices start with $0$ and goes up to $n-1$ where $n$ is the length of the list.

The connection between indexing from 1 to n and indexing in Python from 0 is explained by this figure:

 ____ ____ ____ ____ ____ 
|    |    |    |    |    |
| e1 | e2 | e3 |....| en |
|____|____|____|____|____|
Λ    Λ    Λ    Λ    Λ    Λ
0    1    2    ... n-1   n
-n  1-n  2-n        -1

How to access a sublist. Mind that intervals are inclusive from left and exclusive from right.

In [16]:
l = [0, 1, 2, 3, 4, 5]
print(l[1:3])       # from 1 to 3 (1 is actually the second)
print(l[2:])        # from index 2 to the end
print(l[:3])        # from the beginning up to index 3 (index 3 is not included)
print(l[0:4:2])     # from the start to index 4, take every second element
print(l[-1::-1])    # from last to first with -1 steps (reverse)
[1, 2]
[2, 3, 4, 5]
[0, 1, 2]
[0, 2]
[5, 4, 3, 2, 1, 0]
In [17]:
l[-2] # negative index is calculated from the back
Out[17]:
4

You can concatenate lists just like strings:

In [18]:
print([1, 2, 5] + [8, 5, 3])
[1, 2, 5, 8, 5, 3]

All the above works for strings (as they are list of characters):

In [19]:
s = "trio"
print(s[1:4])
print(s[-2::-1] + s[-1])
print(s[::2])
print(s[1::2])
rio
irto
ti
ro

There are differences between strings and lists. One can assign a given value in a list (mutable) but not in a string (immutable).

In [20]:
l = [1, 2, 555]
l[2] = 3
print(l)
[1, 2, 3]

The same cannot be done with strings:

In [21]:
s = "puppy"
s[1] = "a"
print(s)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-2e77e6442470> in <module>
      1 s = "puppy"
----> 2 s[1] = "a"
      3 print(s)

TypeError: 'str' object does not support item assignment

You can manipulate strings but not this way!

Methods for list manipulations

We learn some practical functions/methods for lists.

Range

The range object can be used to create a list. It is a “lazy iterable” in the sense that it doesn’t generate every number that it “contains” when we create it. Instead it gives those numbers to us as we need them when looping over it. (It is not an iterator, what we will learn later.)

In [22]:
list(range(4))
Out[22]:
[0, 1, 2, 3]
In [23]:
range(4) == [0, 1, 2, 3]
Out[23]:
False
In [24]:
list(range(4, 10))
Out[24]:
[4, 5, 6, 7, 8, 9]
In [25]:
list(range(3, 15, 3))
Out[25]:
[3, 6, 9, 12]

As you can see, it works like list indexing:

range(start, end, step)
  • If you give one parameter (end), then its the last index (zero included, the last excluded)
  • If you give two parameters, then its a [from...to) list
  • The optional third parameter is the step size (1 by default)

They can be manipulated as lists.

In [26]:
range(0, 5, 2)[2]
Out[26]:
4
In [27]:
range(1, 10, 2)[1::2]
Out[27]:
range(3, 11, 4)
In [28]:
list(range(1, 10, 2)[1::2])  # [1, 3, 5, 7, 9] -> [3, 7]
Out[28]:
[3, 7]

New elements / erasing elements

The append method inserts a new elements at the end:

In [29]:
l = [1, 2, 5]
l.append(4)
print(l)
[1, 2, 5, 4]
In [31]:
l = []
while True:
    a = input()
    if a == "":
        break
    l.append(a)
print(l)
apple
tree
2

['apple', 'tree', '2']

The insert method inserts a new element to a given place:

In [32]:
l = [1, 2, 5]
l.insert(1, 'X')
print(l)
[1, 'X', 2, 5]

The pop method erases an element with a given index. This function return the deleted element. Calling with empty argument list delete the last element.

In [33]:
print(l.pop(1))
print(l)
X
[1, 2, 5]
In [34]:
print(l.pop())
print(l)
5
[1, 2]

The remove method erases the first occurrance of the given element:

In [35]:
l = [1, 2, 3, 2, 2, 5]
l.remove(2)
print(l)
[1, 3, 2, 2, 5]
In [36]:
while 2 in l:
    l.remove(2)
print(l)
[1, 3, 5]

The del command is deleting elements with given indices:

In [37]:
l = list(range(8))
del l[::2]
print(l)
del l[1::2]
print(l)
del l[:]            # delete everythin, like l.clear()
print(l)
[1, 3, 5, 7]
[1, 5]
[]

Further list operations

The len function gives the length:

In [38]:
l = [1, 2, 5]
print(len(l))
3

The count method gives how many times occurrs a given element:

In [39]:
l = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
print(l.count(1), l.count(4), l.count(15))
4 3 0

The sort method sorts changing the list. The sorted function construct a new (sorted) list.

In [40]:
l = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
l.sort()
print(l)
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5]
In [41]:
l = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
sorted(l)
Out[41]:
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5]
In [42]:
l
Out[42]:
[1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]

For loop

In Python the for loop and lists are hand-in-hand. A for loop can iterate through lists (and other iterable objects):

for <loop variable> in <iterable object>:
    <statements>
else:
    <statements>
In [43]:
l = ["puppy", "cat", "mouse", "cicada"]
for e in l:
    print(e, end=" -> ")
print("...")
puppy -> cat -> mouse -> cicada -> ...

One can iterate index-wise instead of element-wise. Use the range in that case:

In [44]:
# element-wise
l = [2, 3, 5, 7, 11]
for i in l:
    print(i, end=" ")
2 3 5 7 11 
In [45]:
# index-wise
l = [2, 3, 5, 7, 11]
for i in range(len(l)):
    print(l[i], end=" ")
2 3 5 7 11 
In [46]:
# print index and element
l = [2, 3, 5, 7, 11]
for i in range(len(l)):
    print("index:", i, "element:", l[i])
index: 0 element: 2
index: 1 element: 3
index: 2 element: 5
index: 3 element: 7
index: 4 element: 11

What happen when we have an else-branch in the for-loop?

In [47]:
for e in range(0,10,2):
    if e % 2 == 1:
        break
    print(e, end=" ")
else:                     # the else-branch is exetuted at the end  
    print("all are even") # as we never jumped out from the for-loop
0 2 4 6 8 all are even
In [48]:
l = [0, 2, 4, 5, 6, 8]    # there is an odd number in this list
for e in l:
    if e % 2 == 1:
        break
    print(e, end=" ")
else:                     # now the else-barnch is not executed
    print("all are even")
0 2 4 

Programming elements for lists

Accumulation/Summation

In [49]:
l = [1, 2, 5]
n = 0
for e in l:
    n += e
print(n)
8

Counting

In [50]:
l = [1, 2, 5, 6, 4, 6, 7, 8]
c = 0
for e in l:
    if e % 3 == 0:
        c += 1
print(c)
2

Finding extremum

In [51]:
l = [1, 2, 5, 6, 15, 4, 6, 7, 8]
largest = l[0]    # for the case when the list is surely not empty
for e in l[1:]:
    if largest < e:
        largest = e
print(largest)
15

Find any

In [52]:
lista = [0, 2, 4, 5, 6, 8]
for elem in lista:
    if elem % 2 == 1:
        print("there is an odd")
        break
else:
    print("all are even")
there is an odd

Combining programming elements

Example: Let's count how many "e" letters are in those strings which contain the letter "a" !

In [53]:
words = ["puppy", "elf", "cat", "elephant", "littlecat"]
c = 0
for word in words:
    if "a" in word:
        for i in range(len(word)):
            if word[i] == "e":
                c += 1
print(c)
3

With the use of the count method, you only have to use a counting paradigm:

In [54]:
words = ["puppy", "elf", "cat", "elephant", "littlecat"]
c = 0
for word in words:
    if "a" in word:
        c += word.count("e")
print(c)
3
In [ ]: