<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Generator expressions
Step1:  Tuples as Records
Step2:  Tuple Unpacking
Step3:  Named tuples
Step5:  Slicing
Step6:  Assigning to Slices
Step7:  Using + and * with Sequences
Step8:  Building Lists of Lists
Step9:  Augmented Assignment with Sequences
Step10:  A += Assignment Puzzler
Step11:  • Putting mutable items in tuples is not a good idea.
• Augmented assignment is not an atomic operation—we just saw it throwing an exception after doing part of its job.
• Inspecting Python bytecode is not too difficult, and is often helpful to see what is going on under the hood.
list.sort and the sorted Built-In Function
sorted() makes a new list, doesn't touch the original.
sort() changes list in place.
Step12:  Next
Step13:  Inserting with bisect.insort
Step14:  Arrays
Step15:  To sort an array, use a = array.array(a.typecode, sorted(a)). To keep it sorted while adding to it, use bisect.insort.
Memory Views
The built-in memorview class is a shared-memory sequence type that lets you handle slices of arrays without copying bytes.
Step16:  NumPy and SciPy
Step17:  Loading, saving, and operating
Step18:  a hidden cost
<ASSISTANT_TASK:>
Python Code:
symbols = '$#%^&'
[ord(s) for s in symbols]
tuple(ord(s) for s in symbols)
(ord(s) for s in symbols)
for x in (ord(s) for s in symbols):
    print(x)
import array
array.array('I', (ord(s) for s in symbols))
colors = ['black', 'white']
sizes = ['S', 'M', 'L']
for tshirt in ((c, s) for c in colors for s in sizes):
    print(tshirt)
for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):
    print(tshirt)
Explanation: Generator expressions
End of explanation
lax_coordinates = (33.9425, -118.408056)
city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')]
for passport in sorted(traveler_ids):
    print('%s/%s' % passport)
for country, _ in traveler_ids:
    print(country)
Explanation: Tuples as Records
End of explanation
import os
_, filename = os.path.split('/home/kyle/afile.txt')
print(filename)
a, b, *rest = range(5)
a, b, rest
a, b, *rest = range(3)
a, b, rest
a, b, *rest = range(2)
a, b, rest
a, *body, c, d = range(5)
a, body, c, d
*head, b, c, d = range(5)
head, b, c, d
metro_areas = [('Tokyo','JP',36.933,(35.689722,139.691667)),
               ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
               ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
               ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
               ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
              ]
print('{:15} | {:^9} | {:^9}'.format('', 'lat.', 'long.'))
fmt = '{:15} | {:9.4f} | {:9.4f}'
fmt
for name, cc, pop, (latitude, longitude) in metro_areas:
    if longitude <= 0:
        print(fmt.format(name, latitude, longitude))
Explanation: Tuple Unpacking
End of explanation
from collections import  namedtuple
City = namedtuple('City', 'name country population coordinates')
tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
tokyo
tokyo.population
tokyo.name
tokyo.coordinates
tokyo[1]
# a few useful methods on namedtuple
City._fields
LatLong = namedtuple('LatLong', 'lat long')
delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
delhi = City._make(delhi_data)  # instantiate a named tuple from an iterable
delhi._asdict()
for key, value in delhi._asdict().items():
    print(key + ':', value)
Explanation: Named tuples
End of explanation
# why slices and range exclude the last item
l = [10,20,30,40,50,60]
l[:2]
l[2:]
# slice objects
s = 'bicycle'
s[::3]
s[::-1]
s[::-2]
invoice = 
0.....6.................................40........52...55........
1909  Pimoroni PiBrella                     $17.50    3    $52.50
1489  6mm Tactile Switch x20                $4.95    2      $9.90
1510  Panavise Jr. - PV-201                 $28.00    1    $28.00
1601  PiTFT Mini Kit 320x240                $34.95    1    $34.95
SKU = slice(0,6)
DESCRIPTION = slice(6, 40)
UNIT_PRICE = slice(40, 52)
QUANTITY = slice(52, 55)
ITEM_TOTAL = slice(55, None)
line_items = invoice.split('\n')[2:]
for item in line_items:
    print(item[UNIT_PRICE], item[DESCRIPTION])
Explanation: Slicing
End of explanation
l = list(range(10))
l
l[2:5] = [20, 30]
l
del l[5:7]
l
l[3::2] = [11, 22]
l
l[2:5] = 100
l
l[2:5] = [100]
l
Explanation: Assigning to Slices
End of explanation
l = [1, 2, 3]
l * 5
5 * 'abcd'
Explanation: Using + and * with Sequences
End of explanation
board = [['_'] *3  for i in range(3)]
board
board[1][2] = 'X'
board
Explanation: Building Lists of Lists
End of explanation
l = [1, 2, 3]
id(l)
l *= 2
id(l)  # same list
t=(1,2,3)
id(t)
t *= 2
id(t)  # new tuple was created
Explanation: Augmented Assignment with Sequences
End of explanation
import dis
dis.dis('s[a] += b')
Explanation: A += Assignment Puzzler
End of explanation
fruits = ['grape', 'raspberry', 'apple', 'banana']
sorted(fruits)
fruits
sorted(fruits, reverse=True)
sorted(fruits, key=len)
sorted(fruits, key=len, reverse=True)
fruits
fruits.sort()  # note that sort() returns None
fruits
Explanation: • Putting mutable items in tuples is not a good idea.
• Augmented assignment is not an atomic operation—we just saw it throwing an exception after doing part of its job.
• Inspecting Python bytecode is not too difficult, and is often helpful to see what is going on under the hood.
list.sort and the sorted Built-In Function
sorted() makes a new list, doesn't touch the original.
sort() changes list in place.
End of explanation
breakpoints=[60, 70, 80, 90]
grades='FDCBA'
bisect.bisect(breakpoints, 99)
bisect.bisect(breakpoints, 59)
bisect.bisect(breakpoints, 75)
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
    i = bisect.bisect(breakpoints, score)
    return grades[i]
[grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
grade(4)
grade(93)
Explanation: Next: use bisect module to better search sorted lists.
Managing Ordered Sequences with bisect
End of explanation
import bisect
import random
SIZE = 7
random.seed(1729)
my_list = []
for i in range(SIZE):
    new_item = random.randrange(SIZE*2)
    bisect.insort(my_list, new_item)
    print('%2d ->' % new_item, my_list)
Explanation: Inserting with bisect.insort
End of explanation
from array import array
from random import random
floats = array('d', (random() for i in range(10**7)))
floats[-1]
fp = open('floats.bin', 'wb')
floats.tofile(fp)
fp.close()
floats2 = array('d')
fp = open('floats.bin', 'rb')
floats2.fromfile(fp, 10**7)
fp.close()
floats2[-1]
floats2 == floats
Explanation: Arrays
End of explanation
# Changing the value of an array item by poking one of its bytes
import array
numbers = array.array('h', [-2, -1, 0, 1, 2])
memv = memoryview(numbers)
len(memv)
memv[0]
memv_oct = memv.cast('B')  # ch type of array to unsigned char
memv_oct.tolist()
memv_oct[5] = 4
numbers
Explanation: To sort an array, use a = array.array(a.typecode, sorted(a)). To keep it sorted while adding to it, use bisect.insort.
Memory Views
The built-in memorview class is a shared-memory sequence type that lets you handle slices of arrays without copying bytes.
End of explanation
import numpy
a = numpy.arange(12)
a
type(a)
a.shape
a.shape = 3, 4  # turn a into three units of 4
a
a[2]
a[2, 1]
a[:, 1]
a.transpose()
Explanation: NumPy and SciPy
End of explanation
from collections import deque
dq = deque(range(10), maxlen=10)
dq
dq.rotate(3)
dq
dq.rotate(-4)
dq
dq.appendleft(-1)
dq
dq.extend([11, 22, 33])
dq
dq.extendleft([10, 20, 30, 40])
dq
Explanation: Loading, saving, and operating:
Use numpy.loadtxt()
Deques and Other Queues
Inserting and removing from the left of a list (the 0-index end) is costly. collections.deque is a thread-safe double-ended queue designed for fast inserting and removing from both ends.
End of explanation
# but a workaround with `key`
l = [28, 14, '28', 5, '9', '1', 0, 6, '23', 19]
sorted(l, key=int)
sorted(l, key=str)
Explanation: a hidden cost: removing items from the middle of a deque is not as fast
On using single type in list: "we put items in a list to process them later, which implies that all items should support at least some operation in common".
End of explanation
<END_TASK>