#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Assgn 2

@author: hk
"""
def isPrime(n):
    """Assumes n>1"""
    ans=None
    if n>1:
        if n==2:
            ans=True
        elif n%2==0:
            ans=False
        else:
            for i in range(3,n//2,2):
                if n%i==0:
                    ans=False
                    break
            else:
                ans=True
    return ans

def primes(n):
    if n>=1:
        print(2)
        i=1
        p=3
        while i<n:
            if isPrime(p):
                print(p)
                i+=1
            p+=2
                
def twinPrimes(n):
    """Assumes n>0"""
    if n>0:
        i=0
        p=3
        while i<n:
         if isPrime(p) and isPrime(p+2):
             print(p, p+2)
             i+=1
         p+=2
        
def isPerfect(n):
    sum=0
    lim=n//2
    div=1
    while div<=lim:
        if n%div==0:
            sum+=div
        div+=1
    return sum==n
def perfectNos(n):
    """Be careful when executing. The fifth perfect number has
    8 digits."""
    i=0
    p=2
    while i<n:
        if isPerfect(p):
            print(p)
            i+=1
        p+=2
  
def daysInMonth(m,y):
    days=28
    if m==4 or m==6 or m==9 or m==11:
        days=30
    elif m==2:
        if (y%400==0 or (y%4==0 and y%100!=0)):
            days=29
    else:
        days=31
    return days

def days1(d1,m1,y1,d2,m2,y2):
    """Assumes the first date is <= to second date and both
    dates are legitimate. The program simply advances the date 
    one day at a time and checks if we have reached the second 
    date. For a more efficient version see function days2. 
    It will be more efficient to store days-in-a=month in 
    a tuple or list.
    """
    days=0
    while d1!=d2 or m1!=m2 or y1!=y2:
        if d1<=daysInMonth(m1,y1):
            days+=1
            d1+=1
        elif m1<12:
            d1=1
            m1+=1
        else:#beginning of a new year
            y1+=1
            m1=1
            d1=1
    return days       
           

def days2(d1,m1,y1,d2,m2,y2):
    """Assumes date d1,m1,y1 is earlier or same as d2,m2,y2
    and both dates are legitimate. Breaks up code into
    smaller functions for clarity. More efficient."""
    def daysTillYearEnd(d,m,y):
        if d==1 and m==1:#whole year
            days=366 if y1%400==0 or (y1%4==0 and y1%100!=0) else 365
        else:# part of an year
            days=daysInMonth(m,y)-d+1
            for m in range(m+1,13):
                days+=daysInMonth(m,y)
        return days                       
    def daysBetTwoDatesInSameYear(d1,m1,d2,m2,y):
        #Assumes first date<=second date
        days=0
        while m1<m2:
            days+=daysInMonth(m1,y)-d1+1
            d1=1
            m1+=1
        days+=d2-d1
        return days
    days=0
    while y1<y2:
        days+=daysTillYearEnd(d1,m1,y1)
        d1=1
        m1=1
        y1+=1
    #y1 equals y2 and d1,m1<=d2,m2
    days+=daysBetTwoDatesInSameYear(d1,m1,d2,m2,y1)
    return days