<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Sebastian Raschka
Step1:  Sorting Algorithms
Overview
Step2:  Bubble sort
[back to top]
Quick note about Bubble sort
I don't want to get into the details about sorting algorithms here, but there is a great report
"Sorting in the Presence of Branch Prediction and Caches - Fast Sorting on Modern Computers" written by Paul Biggar and David Gregg, where they describe and analyze elementary sorting algorithms in very nice detail (see chapter 4).   
And for a quick reference, this website has a nice animation of this algorithm.
A long story short
Step4:  Bubble sort implemented in (C)Python
Step6:  <br>
Below is a improved version that quits early if no further swap is needed.
Step7:  Verifying that all implementations work correctly
Step8:  Performance comparison
<ASSISTANT_TASK:>
Python Code:
import time
print('Last updated: %s' %time.strftime('%d/%m/%Y'))
Explanation: Sebastian Raschka
End of explanation
import platform
import multiprocessing
def print_sysinfo():
    
    print('\nPython version  :', platform.python_version())
    print('compiler        :', platform.python_compiler())
    print('\nsystem          :', platform.system())
    print('release         :', platform.release())
    print('machine         :', platform.machine())
    print('processor       :', platform.processor())
    print('CPU count       :', multiprocessing.cpu_count())
    print('interpreter     :', platform.architecture()[0])
    print('\n\n')
Explanation: Sorting Algorithms
Overview
End of explanation
print_sysinfo()
Explanation: Bubble sort
[back to top]
Quick note about Bubble sort
I don't want to get into the details about sorting algorithms here, but there is a great report
"Sorting in the Presence of Branch Prediction and Caches - Fast Sorting on Modern Computers" written by Paul Biggar and David Gregg, where they describe and analyze elementary sorting algorithms in very nice detail (see chapter 4).   
And for a quick reference, this website has a nice animation of this algorithm.
A long story short: The "worst-case" complexity of the Bubble sort algorithm (i.e., "Big-O")
 $\Rightarrow \pmb O(n^2)$
End of explanation
def python_bubblesort(a_list):
     Bubblesort in Python for list objects (sorts in place).
    length = len(a_list)
    for i in range(length):
        for j in range(1, length):
            if a_list[j] < a_list[j-1]:
                a_list[j-1], a_list[j] = a_list[j], a_list[j-1]
    return a_list
Explanation: Bubble sort implemented in (C)Python
End of explanation
def python_bubblesort_improved(a_list):
     Bubblesort in Python for list objects (sorts in place).
    length = len(a_list)
    swapped = 1
    for i in range(length):
        if swapped: 
            swapped = 0
            for ele in range(length-i-1):
                if a_list[ele] > a_list[ele + 1]:
                    temp = a_list[ele + 1]
                    a_list[ele + 1] = a_list[ele]
                    a_list[ele] = temp
                    swapped = 1
    return a_list
Explanation: <br>
Below is a improved version that quits early if no further swap is needed.
End of explanation
import random
import copy
random.seed(4354353)
l = [random.randint(1,1000) for num in range(1, 1000)]
l_sorted = sorted(l)
for f in [python_bubblesort, python_bubblesort_improved]:
    assert(l_sorted  == f(copy.copy(l)))
print('Bubblesort works correctly')
Explanation: Verifying that all implementations work correctly
End of explanation
# small list
l_small = [random.randint(1,100) for num in range(1, 100)]
l_small_cp = copy.copy(l_small)
%timeit python_bubblesort(l_small)
%timeit python_bubblesort_improved(l_small_cp)
# larger list
l_small = [random.randint(1,10000) for num in range(1, 10000)]
l_small_cp = copy.copy(l_small)
%timeit python_bubblesort(l_small)
%timeit python_bubblesort_improved(l_small_cp)
Explanation: Performance comparison
End of explanation
<END_TASK>