Assignment 06
Solutions to Assignment 06.
Reverse Lines
Write a program reverse.py that takes a filename as command-line argument and prints all the lines in that file in the reverse order.
$ cat files/five.txt
one
two
three
four
five
$ python reverse.py files/five.txt
five
four
three
two
one
Solution
import sys
filename = sys.argv[1]
lines = open(filename).readlines()[::-1]
for line in lines:
print(line, end="")Generate Password
Write a function generate_password to generate random password of given length.
The function should take length n as argument and generate a password using mix of letters from lowercase, uppercase from English alphabet and digits. It should not have any other characters.
>>> generate_password(8)
'rBZLcP8V'
>>> generate_password(25)
'JU938tUT36QRvVEPh9OLrxlrB'
Hint
- See
random.choicefunction from therandommodule - See
string.ascii_lettersandstring.digitsfrom the string module
Solution
import string
import random
def generate_password(n):
text = string.ascii_letters + string.digits
return "".join([random.choice(text) for i in range(n)])Weekly Average
Daily average prices of some symbols are given each for five days of a week. Data consists of list of records for each day. Every record consists of (symbol, day, stock price). Write a function weekly_average to compute weekly average for given symbol using this data. it should work as given below
>>> prices = [('IBM', 'Monday', 111.71436961893693),
('IBM', 'Tuesday', 141.21220022208635),
('IBM', 'Wednesday', 112.40571010053796),
('IBM', 'Thursday', 137.54133351926248),
('IBM', 'Friday', 140.25154281801224),
('MICROSOFT', 'Monday', 235.0403622499107),
('MICROSOFT', 'Tuesday', 225.0206535036475),
('MICROSOFT', 'Wednesday', 216.10342426936444),
('MICROSOFT', 'Thursday', 200.38038844494193),
('MICROSOFT', 'Friday', 235.80850482793264),
('APPLE', 'Monday', 321.49182055844256),
('APPLE', 'Tuesday', 340.63612771662815),
('APPLE', 'Wednesday', 303.9065277507285),
('APPLE', 'Thursday', 338.1350605764038),
('APPLE', 'Friday', 318.3912296144338)]
>>> weekly_average(prices, "APPLE")
324.51215324332736
Solution
def weekly_average(prices, symbol):
values = [price for sym, day, price in prices if sym == symbol]
return sum(values)/len(values)Sort Command
Write a program sort.py that takes filename as a command-line argument and prints lines in that file in the sorted order.
This program should support the following flags.
-i --ignore-case ignore the case while sorting
-n --numeric-sort compare according to string numerical value
-r --reverse print the results in the reverse order
$ python sort.py files/sort/names.txt
alice
bob
charlie
dave
$ python sort.py -r files/sort/names.txt
dave
charlie
bob
alice
$ python sort.py files/sort/names-with-case.txt
Alice
Dave
bob
charlie
$ python sort.py -i files/sort/names-with-case.txt
Alice
Dave
bob
charlie
$ python sort.py files/sort/numbers.txt
1
10
100
1000
2
20
200
2000
$ python sort.py -n files/sort/numbers.txt
1
2
10
20
100
200
1000
2000
$ python sort.py -nr files/sort/numbers.txt
2000
1000
200
100
20
10
2
1
Hint: use argparse
Solution
import argparse
p = argparse.ArgumentParser()
p.add_argument("-i", "--ignore-case", action="store_true", default=False, help="ignore case")
p.add_argument("-n", "--numeric-sort", action="store_true", default=False, help="numeric sort")
p.add_argument("-r", "--reverse", action="store_true", default=False, help="reverse order")
p.add_argument("filename")
args = p.parse_args()
def get_key(args):
if args.numeric_sort:
return int
elif args.ignore_case:
return str.lower
else:
return None
key = get_key(args)
reverse = args.reverse
lines = sorted(open(args.filename), key=key, reverse=reverse)
for line in lines:
print(line, end="")Hosts Writer
Write a module hosts with two functions tostring and write to serialize a dictionary with hosts to IP address mapping.
The tostring function takes a dictionary with host to ip mapping to a string in /etc/hosts file format.
The write function takes a filename and a dictionary as arguments and writes the dictionary in /etc/hosts file format to the specified file.
>>> import hosts
>>> data = {"web": "1.2.3.4", "db": "1.2.3.5"}
>>> print(hosts.tostring(data))
1.2.3.4 web
1.2.3.5 db
>>> data = {"web1": "1.2.3.4", "web2": "1.2.3.4", "db": "1.2.3.5"}
>>> print(hosts.tostring(data))
1.2.3.4 web1 web2
1.2.3.5 db
>>> hosts.write("hosts.txt", data)
>>> print(open("hosts.txt").read())
1.2.3.4 web1 web2
1.2.3.5 db
Also write a test_hosts.py with test cases to verify if your solution is correct.
Solution
# hosts.py
def tostring(hosts):
ips = {}
for host, ip in hosts:
ips.setdefault(ip, []).append(host)
lines = [" ".join([ip] + names) for ip, names in ips.items()]
return "\n".join(lines)
def write(filename, hosts):
with open(filename, "w") as f:
f.write(tostring(hosts))