Module 2 - Nurturing Session

strip

"text with some spaces at end      ".strip() # removing trainling whilte spaces (space, tab and \n)
'text with some spaces at end'
line = "test with some new line at end     \n"
line.strip() # this strip white space as well as \n
'test with some new line at end'
line.strip("\n")
'test with some new line at end     '

Paste

%load_problem paste-cmd
Problem: Paste

Write a program paste.py that takes two files as command-line arguments and contacenates the corresponding lines in those two files with a tab character and prints it.

For example, of the first file files/a.txt has the following contents:

A
B
C
D

and the second file files/b.txt has the following:

1
2
3
4

The output should be:

$ python paste.py files/a.txt files/b.txt
A       1
B       2
C       3
D       4

Note that the first line is "A\t1".

For simplicity, assume that both the files have exactly same number of lines.

Hint:

You can use the strip method on a string to remove the new line character.

>>> "a\n".strip("\n")
"a"

You can verify your solution using:

%verify_problem paste-cmd

%%file paste.py
# your code here


%%file a.txt
A
B
C
D
Writing a.txt
%%file b.txt
1
2
3
4
Writing b.txt
A   1
B   2
C   3
D   4
%%file a.txt
  A
B
C
D
Overwriting a.txt
  A    1
B   2
C   3
D   4

string formating

print(f"{date} {sales_by_date[date]}")
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[13], line 1
----> 1 print(f"{date} {sales_by_date[date]}")

NameError: name 'date' is not defined
date = "2024-07-06"
value = 175
f"{date} {value}"
'2024-07-06 175'
f"{date} {value:.2f}"
'2024-07-06 175.00'
f"{date} {value:.3f}"
'2024-07-06 175.000'
value = 175.3453454
f"{date} {value:.3f}"
'2024-07-06 175.345'
filename1 = "a.txt"
filename2 = "b.txt"
with open(filename1) as f1:
    with open(filename2) as f2:
        for l1, l2 in zip(f1, f2):
            
  Cell In[20], line 2
    filename2 =
                ^
SyntaxError: invalid syntax

Longest line

%load_problem longest-line
Problem: 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.

You can verify your solution using:

%verify_problem longest-line

%%file longest_line.py
# your code here


words = ["one", "two", "three", "four", "five"]
max(words) # this will not give longest word!
'two'
max(words, key=len) # longest word!
'three'
print(max(f, key=len)) # longest line!
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[26], line 1
----> 1 print(max(f, key=len)) # longest line!

NameError: name 'f' is not defined

Sum File

%load_problem sumfile
Problem: 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

You can verify your solution using:

%verify_problem sumfile

%%file sumfile.py
# your code here


%%file nums.txt
1
2
3
4
5
Overwriting nums.txt

Invert Dict

%load_problem invertdict
Problem: Invert Dict

Write a function invertdict to interchange the keys and values in a dictionary.

The function should take a dictionary as an argument and return a new dictionary with keys and values interchanged. For simplicity, assume that the values in the dictionary are unique.

>>> invertdict({"x": 1, "y": 2, "z": 3})
{1: "x", 2: "y", 3: "z"}

You can verify your solution using:

%verify_problem invertdict

# your code here


{k:v for ....} # if key -> value
  Cell In[31], line 1
    {k:v for ....} # if key -> value
             ^
SyntaxError: cannot assign to ellipsis
{v:k for ...} # dictionary comprehension
  Cell In[32], line 1
    {v:k for ...} # dictionary comprehension
             ^
SyntaxError: cannot assign to ellipsis

Line with Most Words

%load_problem line-with-most-words
Problem: 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

You can verify your solution using:

%verify_problem line-with-most-words

%%file line_with_most_words.py
# your code here


def wordcount(line):
    return len(line.strip().split())
max(f, key=wordcount) # this will find a line with maximum word count
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[35], line 1
----> 1 max(f, key=wordcount) # this will find a line with maximum word count

NameError: name 'f' is not defined

Sequence of numbers

%load_problem seq
Problem: Sequence of Numbers

Write a program seq.py that takes a number n as argument and prints numbers from 1 to n. It should support the following two flags.

-s START --start START
    print number from START to n instead of 1 to n

-r --reverse
    print the numbers in the reverse order

The program should also print approprate help message when used with -h or --help flags.

Use the standard library module argparse or typer module for doing this. You may want to checkout the argparse or typer tutorial to know how to use that module.

Expected Output:

$ python seq.py 5
1
2
3
4
5

$ python seq.py -s 3 5
3
4
5

$ python seq.py -r -s 3 5
5
4
3

You can verify your solution using:

%verify_problem seq

%%file seq.py
# your code here
import typer

def seq(start, reverse):
    pass


if __name__ == "__main__":
    typer.run(seq)
Writing seq.py
!python seq.py --help
                                                                                
 Usage: seq.py [OPTIONS] START REVERSE                                          
                                                                                
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
│ *    start        TEXT  [default: None] [required]                           │
│ *    reverse      TEXT  [default: None] [required]                           │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --help          Show this message and exit.                                  │
╰──────────────────────────────────────────────────────────────────────────────╯
%%file seq.py
# your code here
import typer

def seq(start:int=1, reverse:bool=False):
    pass


if __name__ == "__main__":
    typer.run(seq)
Overwriting seq.py
!python seq.py --help
                                                                                
 Usage: seq.py [OPTIONS]                                                        
                                                                                
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --start                      INTEGER  [default: 1]                           │
│ --reverse    --no-reverse             [default: no-reverse]                  │
│ --help                                Show this message and exit.            │
╰──────────────────────────────────────────────────────────────────────────────╯
%%file seq.py
# your code here
import typer

def seq(start:int=typer.Option(1, "-s", "--start", help="Defalt start value"), reverse:bool=False):
    pass


if __name__ == "__main__":
    typer.run(seq)
Overwriting seq.py
!python seq.py --help
                                                                                
 Usage: seq.py [OPTIONS]                                                        
                                                                                
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --start    -s                  INTEGER  Defalt start value [default: 1]      │
│ --reverse      --no-reverse             [default: no-reverse]                │
│ --help                                  Show this message and exit.          │
╰──────────────────────────────────────────────────────────────────────────────╯
%%file seq.py
# your code here
import typer

def seq(start:int=typer.Option(1, "-s", "--start", help="Defalt start value"), 
        reverse:bool=typer.Option(False, "-r", "--reverse", help="In case ypu want to reverse the sequesnce give this flag")):

    print("start" , start)
    print("reverse?", reverse)


if __name__ == "__main__":
    typer.run(seq)
Overwriting seq.py
!python seq.py --help
                                                                                
 Usage: seq.py [OPTIONS]                                                        
                                                                                
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --start    -s      INTEGER  Defalt start value [default: 1]                  │
│ --reverse  -r               In case ypu want to reverse the sequesnce give   │
│                             this flag                                        │
│ --help                      Show this message and exit.                      │
╰──────────────────────────────────────────────────────────────────────────────╯
!python seq.py -s 5
start 5
reverse? False
!python seq.py -s 5 -r
start 5
reverse? True
for i in range(2, 5):
    print(i)
2
3
4
for i in reversed(range(2, 5)):
    print(i)
4
3
2
%%file seq.py
# your code here
import typer

def seq(n:int, start:int=typer.Option(1, "-s", "--start", help="Defalt start value"), 
        reverse:bool=typer.Option(False, "-r", "--reverse", help="In case ypu want to reverse the sequesnce give this flag")):

    print("start" , start)
    print("reverse?", reverse)


if __name__ == "__main__":
    typer.run(seq)
Overwriting seq.py
!python seq.py --help
                                                                                
 Usage: seq.py [OPTIONS] N                                                      
                                                                                
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
│ *    n      INTEGER  [default: None] [required]                              │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --start    -s      INTEGER  Defalt start value [default: 1]                  │
│ --reverse  -r               In case ypu want to reverse the sequesnce give   │
│                             this flag                                        │
│ --help                      Show this message and exit.                      │
╰──────────────────────────────────────────────────────────────────────────────╯

copy a file

%load_problem copy-file
Problem: Copy File

Write a program copy_file.py to copy contents of one file to another.

The program should accept a source file and a destination file as arguments and copy the source to the destination.

$ python copyfile.py files/five.txt 5.txt

Note: Don't call this file copy.py as that interfere with a standard library module with the same name.

You can verify your solution using:

%verify_problem copy-file

%%file copy_file.py
# your code here


with open("a.txt" , "rb") as rf:
    with open("dest.txt", "wb") as wf:
        wf.write(rf.read())
!cat dest.txt
  A
B
C
D

Double a Point

%load_problem point-double
Problem: Double a Point

Add a method double to the Point class that doubles both x and y coordinates of the point.

You can start with this code for Point class.

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

The expected behavior:

>>> p = Point(2, 3)
>>> p2 = p.double()
>>> p2
Point(4, 6)
>>> p.double().double()
Point(8, 12)

You can verify your solution using:

%verify_problem point-double


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

    # Add double method here
p = Point(4, 5)
dp = Point(2*p.x, 2*p.y)
dp
Point(8, 10)

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

    # Add double method here
    def double(self):
        return Point()

Sales by Day

%load_problem sales-by-day
Problem: Sales by Day

Write a program sales.py to compute the total sale amount per day, given a text file with details of transactions with three columns Order Id, Date and Amount.

Here is a sample input file.

$ cat files/orders.txt
1001 2023-01-01 100
1002 2023-01-01 50
1003 2023-01-02 50
1004 2023-01-02 150
1005 2023-01-01 25

The file contains multiple transactions, one in row. Each row will have three fields, Order Id, Date and Amount, seperated by a space.

YOur program should take the order file as a command-line argument and print the total same amount per day. The output should be sorted by date.

$ python sales.py files/orders.txt
2023-01-01 175
2023-01-02 200

Please note that you are expected to parse the file yourself and not use pandas.

You can verify your solution using:

%verify_problem sales-by-day

%%file sales.py
# your code here

# make use of dictionary to find total value for every date
Writing sales.py