Oct 11-15, 2021 Vikrant Patil
These notes are available online at https://notes.pipal.in/2021/arcesium_finop_batch2/
© Pipal Academy LLP
We will be using jupyter hub from https://lab2.pipal.in for this training.
create a notebook with name module2-day2
def factors(n):
return [f for f in range(1, n+1) if n%f==0]
def is_prime(n):
return factors(n) == [1,n]
def is_prime(n):
return len(factors(n))
is_prime(7)
True
2 == 3
False
2 == 2
True
[1, 2] == [1, 2]
True
[1, 1] == [3, 4]
False
factors(7)
[1, 7]
factors(10) == [1, 10]
False
factors(10)
[1, 2, 5, 10]
[2*i for i in range(1, 11)]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
[[n*i for i in range(1, 11)] for n in range(1, 6)]
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], [3, 6, 9, 12, 15, 18, 21, 24, 27, 30], [4, 8, 12, 16, 20, 24, 28, 32, 36, 40], [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]]
tables = [[n*i for i in range(1, 11)] for n in range(1, 6)]
tables
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], [3, 6, 9, 12, 15, 18, 21, 24, 27, 30], [4, 8, 12, 16, 20, 24, 28, 32, 36, 40], [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]]
tables[0] # accessing zeroth row
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tables[1] # first row
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
tables[-1] # last row
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
# lets try to access 2nd index column
tables[0][2]
3
tables[1][2]
6
tables[2][2]
9
tables[3][2]
12
def column(data2d, n):
rowcount = len(data2d)
return [data2d[r][n] for r in range(rowcount)]
column(tables, 2)
[3, 6, 9, 12, 15]
column(tables, 0)
[1, 2, 3, 4, 5]
def column(data2d, n):
return [row[n] for row in data2d]
column(tables, 0)
[1, 2, 3, 4, 5]
def transpose(data2d):
"""finds transpose of 2d list,
but assumption is that every row has same number of columns!
"""
colcount = len(data2d[0])
return [column(data2d, i) for i in range(colcount)]
tables
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], [3, 6, 9, 12, 15, 18, 21, 24, 27, 30], [4, 8, 12, 16, 20, 24, 28, 32, 36, 40], [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]]
transpose(tables)
[[1, 2, 3, 4, 5], [2, 4, 6, 8, 10], [3, 6, 9, 12, 15], [4, 8, 12, 16, 20], [5, 10, 15, 20, 25], [6, 12, 18, 24, 30], [7, 14, 21, 28, 35], [8, 16, 24, 32, 40], [9, 18, 27, 36, 45], [10, 20, 30, 40, 50]]
%%file zen.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Writing zen.txt
import os
os.getcwd()
'/home/vikrant/trainings/2021/arcesium_finop_batch2'
with open("zen.txt") as f: # f is file reading handle provided by open()
contents = f.read() # this reads complete file as multiine text data!
print(contents, "X"*10)
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! XXXXXXXXXX
contents
"The Zen of Python, by Tim Peters\n\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n"
with open("zen.txt") as f: # f is file reading handle provided by open()
contents1 = f.read() # this reads complete file as multiine text data!
contents2 = f.read() # this will not work because f is an iterator! it allows us going through file only once
print(contents1)
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
print(contents2)
contents1
"The Zen of Python, by Tim Peters\n\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n"
contents2
''
with open("zen.txt") as file:
for item in file:
print(item, end="")
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
with open("zen.txt") as file:
lines = []
for line in file:
lines.append(line)
with open("zen.txt") as file:
lines = [line for line in file]
lines
['The Zen of Python, by Tim Peters\n', '\n', 'Beautiful is better than ugly.\n', 'Explicit is better than implicit.\n', 'Simple is better than complex.\n', 'Complex is better than complicated.\n', 'Flat is better than nested.\n', 'Sparse is better than dense.\n', 'Readability counts.\n', "Special cases aren't special enough to break the rules.\n", 'Although practicality beats purity.\n', 'Errors should never pass silently.\n', 'Unless explicitly silenced.\n', 'In the face of ambiguity, refuse the temptation to guess.\n', 'There should be one-- and preferably only one --obvious way to do it.\n', "Although that way may not be obvious at first unless you're Dutch.\n", 'Now is better than never.\n', 'Although never is often better than *right* now.\n', "If the implementation is hard to explain, it's a bad idea.\n", 'If the implementation is easy to explain, it may be a good idea.\n', "Namespaces are one honking great idea -- let's do more of those!\n"]
f = open("zen.txt")
f.readline() # this will read only one line from file
'The Zen of Python, by Tim Peters\n'
f.readline()
'\n'
f.readline()
'Beautiful is better than ugly.\n'
f.read() # read remaining data as single string
"Explicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n"
f.readline()
''
f.read()
''
f.close()
with open("zen.txt") as f:
print(f.read())
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
I have created a subfolder 'test' in current directory, inside that created a test.txt
with open("test.txt") as f:
print(f.read())
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-59-0256699640d8> in <module> ----> 1 with open("test.txt") as f: 2 print(f.read()) FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
filepath = os.path.join("test", "test.txt")
filepath
'test/test.txt'
with open(filepath) as f:
print(f.read())
dsfds dshfkjds hf kjfkjd hfkjhd kjfhdslkjfhd kjhgjfdhg khkjdhg fgaskwyrsdf hdsfkjdsg hkjhdgkjhgfhdkjg kjhgkjfdhg 'wa jhgdfdhgkjfdhg kjhfkjdshf
absoulte_path = "/home/vikrant/trainings/2021/arcesium_finop_batch2/test/test.txt"
filepath # relative path , is always with respect to current working directory
'test/test.txt'
os.getcwd()
'/home/vikrant/trainings/2021/arcesium_finop_batch2'
with open(filepath) as testdata:
print(testdata.read())
dsfds dshfkjds hf kjfkjd hfkjhd kjfhdslkjfhd kjhgjfdhg khkjdhg fgaskwyrsdf hdsfkjdsg hkjhdgkjhgfhdkjg kjhgkjfdhg 'wa jhgdfdhgkjfdhg kjhfkjdshf
nums = [1, 2, 3, 4, 5]
numsi = iter(nums)
next(numsi)
1
next(numsi)
2
next(numsi)
3
next(numsi)
4
next(numsi)
5
next(numsi)
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-78-79969bd8d815> in <module> ----> 1 next(numsi) StopIteration:
with open("zen.txt") as f:
print(next(f), end="")
print(next(f), end="")
print(next(f), end="")
The Zen of Python, by Tim Peters Beautiful is better than ugly.
cat is unix command which takes filename as argument and prints contets of it on screen
%%file cat.py
import sys
def cat(filename):
with open(filename) as f:
print(f.read())
filename = sys.argv[1]
cat(filename)
Writing cat.py
!python3 cat.py zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
import cat #? what is meaning of sys.argv when I import module
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-82-43eb8ecdf7be> in <module> ----> 1 import cat #? what is meaning of sys.argv when I import module ~/trainings/2021/arcesium_finop_batch2/cat.py in <module> 6 7 filename = sys.argv[1] ----> 8 cat(filename) ~/trainings/2021/arcesium_finop_batch2/cat.py in cat(filename) 2 3 def cat(filename): ----> 4 with open(filename) as f: 5 print(f.read()) 6 FileNotFoundError: [Errno 2] No such file or directory: '-f'
!python3 cat.py zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
def foo():
print("hello")
%%file testmodule.py
print(__name__) # dunder name--> two underscors at start and at end!
Writing testmodule.py
!python3 testmodule.py
__main__
import testmodule
testmodule
%%file anotherpyfile.py
print(__name__)
Writing anotherpyfile.py
!python3 anotherpyfile.py
__main__
import anotherpyfile
anotherpyfile
%%file cat.py
# defination part
import sys
def cat(filename):
with open(filename) as f:
print(f.read())
# execution part
if __name__ == "__main__":
filename = sys.argv[1]
cat(filename)
Overwriting cat.py
!python3 cat.py zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
import cat
cat.cat("zen.txt")
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
problems
head.py which mimics unix command head . It should take number of lines to shown and filename from commandline arguments. and then only print first n lines from the file.!python3 head.py 4 zen.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
csvparse which will take .csv filename as parameter name and read the file and it will return 2D list.>>> csvparse("tables.csv")
[[1,2,3,4,5,6,7,8,9,10],
[2,4,8,10,12,14,16,18,20],
[3,6,9,12,15,18,21,24,27,30]]
%%file tables.csv
1,2,3,4,5,6,7,8,9,10
2,4,8,10,12,14,16,18,20
3,6,9,12,15,18,21,24,27,30
Writing tables.csv
print("hello")
hello
for i in range(5):
print("hello")
hello hello hello hello hello
!python cat.py # sys.argv - > ['cat.py']
Traceback (most recent call last):
File "cat.py", line 10, in <module>
filename = sys.argv[1]
IndexError: list index out of range
!python cat.py zen.txt # sys.argv - > ['cat.py', 'zen.txt']
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
!python cat.py zen.txt 123 # sys.argv - > ['cat.py', 'zen.txt', '123']
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
print([line[n] for line in f ] if n<range(len(f.readlines()))])
# whenever we want to create a list finally, see if list comprehension can be used
# if no list creation is to be done... then for loop
for i in range(n):
line = f.readline()
print(line)
i = 0
while i<n:
print(f.readline())
i = i+1
%%file head.py
import sys
def head(n, filename):
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
# execution part
if __name__ == "__main__":
filename = sys.argv[2]
n = int(sys.argv[1])
head(n, filename)
Overwriting head.py
!python3 head.py 4 zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit.
line = "1,2,3,4,5"
line.split(",")
['1', '2', '3', '4', '5']
[int(item) for item in line.split(",")]
[1, 2, 3, 4, 5]
!python3 cat.py tables.csv
1,2,3,4,5,6,7,8,9,10 2,4,8,10,12,14,16,18,20 3,6,9,12,15,18,21,24,27,30
def csvparse(filename):
with open(filename) as f:
data2d = []
for line in f:
data2d.append(line.split(","))
return data2d
csvparse("tables.csv")
[['1', '2', '3', '4', '5', '6', '7', '8', '9', '10\n'], ['2', '4', '8', '10', '12', '14', '16', '18', '20\n'], ['3', '6', '9', '12', '15', '18', '21', '24', '27', '30\n']]
" \n\tdsfjdshf".strip()
'dsfjdshf'
def csvparse(filename):
with open(filename) as f:
data2d = []
for line in f:
row = line.strip().split(",")
row = [int(item) for item in row]
data2d.append(row)
return data2d
csvparse("tables.csv")
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [2, 4, 8, 10, 12, 14, 16, 18, 20], [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]]
def csvparse(filename):
with open(filename) as f:
return [line.strip().split(",") for line in f]
csvparse("tables.csv")
[['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['2', '4', '8', '10', '12', '14', '16', '18', '20'], ['3', '6', '9', '12', '15', '18', '21', '24', '27', '30']]
def csvparse(filename):
def convertint(items):
return [int(item) for item in items]
with open(filename) as f:
return [convertint(line.strip().split(",")) for line in f]
csvparse("tables.csv")
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [2, 4, 8, 10, 12, 14, 16, 18, 20], [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]]
%%file indexdata.csv
symbol,day,price
IBM,Monday,111.343
IBM,Tuesday,112.3232
MICROSOFT,Monday,234.454
MICROSOFT,Tuesday,343.54
APPLE,Monday,454.5
APPLE,Tuesday,465.5
Overwriting indexdata.csv
def parse_indexdata(filename):
with open(filename) as f:
headers = f.readline()
data = []
for line in f:
row = line.strip().split(",")
row[2] = float(row[2])
data.append(row)
return data
parse_indexdata("indexdata.csv")
[['IBM', 'Monday', 111.343], ['IBM', 'Tuesday', 112.3232], ['MICROSOFT', 'Monday', 234.454], ['MICROSOFT', 'Tuesday', 343.54], ['APPLE', 'Monday', 454.5], ['APPLE', 'Tuesday', 465.5]]
with open("numbers.txt", "w") as f:
f.write("one")
f.write("two")
f.write("three")
!python3 cat.py numbers.txt
onetwothree
with open("numbers.txt", "w") as f:
f.write("one\n")
f.write("two\n")
f.write("three\n")
!python3 cat.py numbers.txt
one two three
mode meaing
w Write in text mode. Create new file if does not exist. overwrite if exists
a Write in text mode, do not overwrite, just append to end.
with open("numbers.txt", "a") as f:
f.write("last line!")
!python3 cat.py numbers.txt
one two three last line!
def writecsv(data2d, filename):
with open(filename, "w") as fw:
for row in data2d:
strrow = [str(item) for item in row]
line = ",".join(strrow)
fw.write(line)
fw.write("\n")
writecsv(tables, "mytables.csv")
!python3 cat.py mytables.csv
1,2,3,4,5,6,7,8,9,10 2,4,6,8,10,12,14,16,18,20 3,6,9,12,15,18,21,24,27,30 4,8,12,16,20,24,28,32,36,40 5,10,15,20,25,30,35,40,45,50
"{symbol},{day},{price}"
'{symbol},{day},{price}'
"{symbol},{day},{price}".format(symbol="IBM", day="Monday", price=141.33)
'IBM,Monday,141.33'
indexdata = parse_indexdata("indexdata.csv")
indexdata
[['IBM', 'Monday', 111.343], ['IBM', 'Tuesday', 112.3232], ['MICROSOFT', 'Monday', 234.454], ['MICROSOFT', 'Tuesday', 343.54], ['APPLE', 'Monday', 454.5], ['APPLE', 'Tuesday', 465.5]]
def write_indedata(indexdata, filename):
with open(filename, "w") as fw:
fw.write("symbol,day,price\n")
for row in indexdata:
fw.write("{symbol},{day},{price}\n".format(symbol=row[0],
day=row[1],
price=row[2]))
write_indedata(indexdata, "myindexdata.csv")
!python3 cat.py myindexdata.csv
symbol,day,price IBM,Monday,111.343 IBM,Tuesday,112.3232 MICROSOFT,Monday,234.454 MICROSOFT,Tuesday,343.54 APPLE,Monday,454.5 APPLE,Tuesday,465.5
"{symbol},{day},{price}".format(symbol="IBM", day="Monday", price=141.33)
'IBM,Monday,141.33'
"{0},{1},{2}".format("IBM","Monday", 141.33)
'IBM,Monday,141.33'
symbol = "IBM"
day = "Monday"
price = 242.5
f"{symbol},{day},{price}"
'IBM,Monday,242.5'