Assignment 02
Solutions to Assignment 02.
Despace
Write a function despace to remove all the spaces from a string.
>>> despace("hello world")
'helloworld'
>>> despace("a b c d e")
'abcde'
>>> despace("pi seconds is a nano century")
'pisecondsisananocentury'Solution
def despace(text):
return text.replace(" ", "")Sort Words
Write a function sort_words to rearrange the words in a sentense in the sorted or order.
>>> sort_words("one two three four five")
'five four one three two'
>>> sort_words("white cat and black dog")
'and black cat dog white'
>>> sort_words("have a nice day")
'a day have nice'Solution
def sort_words(sentence):
words = sentence.split()
return " ".join(sorted(words))Minimum of Three Numbers
Write a function minimum3 to compute the minimum of three numbers.
You are not allowed to use any built-in functions in this implementation.
>>> minimum3(1, 2, 3)
1
>>> minimum3(3, 2, 1)
1
>>> minimum3(1, 1, 1)
1Solution
def minimum(a, b):
if a < b:
return a
else:
return b
def minimum3(a, b, c):
return minimum(minimum(a, b), c)Longest Line
Write a program longest_line.py to print the longest line from a file.
The program should take a filename as a command-line argument and print the longest line from it.
$ python longest_line.py files/five.txt
three
$ python longest_line.py files/zen-of-python.txt
There should be one-- and preferably only one --obvious way to do it.
$ python longest_line.py files/bumper-stickers.txt
The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.
Solution
import sys
path = sys.argv[1]
lines = open(path).readlines()
longest = max(lines, key=len)
print(longest, end="")Line with Most Words
Write a program line_with_most_words.py that takes a filename as command-line argument and prints the line with the most number of words from the file.
$ cat files/words.txt
one
one two
one two three
one two three four
one two three four five
two three four five
three four five
four five
five
one-two-three-four-five-six-seven
$ python line_with_most_words.py files/words.txt
one two three four five
Solution
import sys
filename = sys.argv[1]
lines = open(filename).readlines()
def word_count(line):
return len(line.split())
longest = max(lines, key=word_count)
print(longest.strip("\n"))List Files
Write a program ls.py to list files in a directory.
The program should take path to a directory as command-line argument and print all the files (and sub-directories) in that directory.
$ python ls.py files/abc
a.txt
b.txt
c.txt
Solution
import sys
import os
path = sys.argv[1]
for f in os.listdir(path):
print(f)Sum File
Write a program sumfile.py that takes a filename as argument and prints sum of all numbers in the file. It is assumed that the file contains one number per line.
$ python sumfile.py files/ten.txt
55
Solution
import sys
filename = sys.argv[1]
numbers = [int(line) for line in open(filename)]
print(sum(numbers))Grep Command
Implement Unix command grep in Python.
Write a program grep.py that takes a pattern and a file as command-line arguments and print all the lines in the file that contain that pattern.
The pattern could be any text and there is no need to support regular expressions.
$ cat files/zen-of-python.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 grep.py never files/zen-of-python.txt
Errors should never pass silently.
Now is better than never.
Although never is often better than *right* now.
$ grep the files/zen-of-python.txt
Special cases aren't special enough to break the rules.
In the face of ambiguity, refuse the temptation to guess.
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.
Solution
import sys
pat = sys.argv[1]
filename = sys.argv[2]
for line in open(filename):
if pat in line:
print(line, end="")Cumulative Sum
Cumulative sum of a list [a, b, c, ...] is defined as [a, a+b, a+b+c, ...].
Write a function cumulative_sum to compute the cumulative sum of a list of numbers.
>>> cumulative_sum([1, 2, 3, 4])
[1, 3, 6, 10]
>>> cumulative_sum([4, 3, 2, 1])
[4, 7, 9, 10]
Solution
def cumulative_sum(numbers):
result = []
csum = 0
for n in numbers:
csum += n
result.append(csum)
return resultCount Increased
Given a list of numbers, count the number of times a number in the list increases from the previous number.
For example:
Given the list of numbers as [3, 5, 4, 9, 2, 8]
3 (N/A - no previous number)
5 (increased)
4 (decreased)
9 (increased)
2 (decreased)
8 (increased)
So the number of times a number increased from the previous number is 3.
Write a function count_increased that takes a list of numbers as arguments and returns the number of times a number in that list is increased from the previous one.
>>> count_increased([3, 5, 4, 9, 2, 8])
3
Credits: this problem is modelled after Day 1 problem of Advent of Code 2021.
Solution
def count_increased(numbers):
return sum([a > b for a, b in zip(numbers[1:], numbers)])Discussion
Let’s consider the example carefully and try to solve it by hand.
3 5 4 9 2 8
How do we find if a number is more than it’s previous number?
We could repeats the numbers in two rows and shift the first one to right by one position and see if each number is increased from the above number.
- 3 5 4 9 2 8
3 5 4 9 2 8 -
--------------
1 0 1 0 1
As you can see there are three cases where a number is increased from its previous number.
A naive approach to do this with code, would be to go over the numbers using index and see if current number is bigger than the one at the previous index.
def count_increased(numbers):
count = 0
for i in range(1, len(numbers)):
prev = numbers[i-1]
current = numbers[i]
if current > prev:
count += 1
return countThere are a couple of issues with this approach.
- Accessing elements using index feels too low-level in Python
- Updating the count in the loop is tedius. There must be a better way.
Lets see if we can align the numbers in the list with their previous values.
numbers = [3, 5, 4, 9, 2, 8]
print(numbers[1:])
print(numbers)[5, 4, 9, 2, 8] [3, 5, 4, 9, 2, 8]
As you can see, we have managed to align the numbers with their previous ones.
Now we could use the zip function to put the pairs together.
pairs = zip(numbers[1:], numbers)
list(pairs)[(5, 3), (4, 5), (9, 4), (2, 9), (8, 2)]
for a, b in zip(numbers[1:], numbers):
print(a, b, a > b)5 3 True 4 5 False 9 4 True 2 9 False 8 2 True
As you can see there are three increases.
We could write a list comprehension to get just the True/False values.
[a > b for a, b in zip(numbers[1:], numbers)][True, False, True, False, True]
In Python, True is eqvivalant of 1 and False is 0. So we could just sum the result to get the number of True values.
sum([a > b for a, b in zip(numbers[1:], numbers)])3
Let’s put in a function now.
def count_increased(numbers):
return sum([a > b for a, b in zip(numbers[1:], numbers)])