# Jamal A. Rizvi
# UC Berkeley - Bootcamp: UCB-VIRT-FIN-PT-03-2021-U-B-TTH
# Modlue 1 Challenge - Create a Python program that automates the tasks associated with valuing microlending loans
# Due Date -  Apr 4, 2021 11:59pm
# coding: utf-8

import csv
from pathlib import Path

"""Part 1: Automate the Calculations.

Automate the calculations for the loan portfolio summaries.

First, let's start with some calculations on a list of prices for 5 loans.
    1. Use the `len` function to calculate the total number of loans in the list.
    2. Use the `sum` function to calculate the total of all loans in the list.
    3. Using the sum of all loans and the total number of loans, calculate the average loan price.
    4. Print all calculations with descriptive messages.
"""
# List of loan costs
loan_costs = [500, 600, 200, 1000, 450]

# 1. Calculate & Print the total number of loans in the list using 'len' function.
total_number_of_loans = len(loan_costs)
print(f"Total number of loans in the list: {total_number_of_loans}")

# 2. Calculate & print the total of all loans in the list using 'sum' function.
total_of_all_loans = sum(loan_costs)
print(f"The total of all loans in the list: ${total_of_all_loans: .2f}")

# 3. Calculate & print the average loan price using sum of all loans and the total number of loans.
average_loan_amount = sum(loan_costs)/len(loan_costs)
print(f"The average loan price is: ${average_loan_amount: .2f}")

"""Part 2: Analyze Loan Data.

Analyze the loan to determine the investment evaluation.

Using more detailed data on one of these loans, follow these steps to calculate a Present Value, or a "fair price" for what this loan would be worth.

1. Use get() on the dictionary of additional information to extract the **Future Value** and **Remaining Months** on the loan.
    a. Save these values as variables called `future_value` and `remaining_months`.
    b. Print each variable.

    @NOTE:
    **Future Value**: The amount of money the borrower has to pay back upon maturity of the loan (a.k.a. "Face Value")
    **Remaining Months**: The remaining maturity (in months) before the loan needs to be fully repaid.

2. Use the formula for Present Value to calculate a "fair value" of the loan. Use a minimum required return of 20% as the discount rate.
3. Write a conditional statement (an if-else statement) to decide if the present value represents the loan's fair value.
    a. If the present value of the loan is greater than or equal to the cost, then print a message that says the loan is worth at least the cost to buy it.
    b. Else, the present value of the loan is less than the loan cost, then print a message that says that the loan is too expensive and not worth the price.

    @NOTE:
    If Present Value represents the loan's fair value (given the required minimum return of 20%), does it make sense to buy the loan at its current cost?
"""

# Given the following loan data, you will need to calculate the present value for the loan
loan = {
    "loan_price": 500,
    "remaining_months": 9,
    "repayment_interval": "bullet",
    "future_value": 1000,
}

# 1. Extract & print the Future Value and Remaining Months on the loan (each variable).
future_value = loan.get("future_value")
print (f"The future value is: ${future_value: .2f}")
remaining_months = loan.get("remaining_months")
print (f"The remaining months are: {remaining_months}")

# 2. Calculate  "fair value" of the loan using Present Value formula.
#       Use a minimum required return of 20% as the discount rate.
#       Use the **monthly** version of the present value formula.
#   HINT: Present Value = Future Value / (1 + Discount_Rate/12) ** remaining_months

# Declare variable "discount_rate" to be used in the formula
discount_rate = .20

# Start of present value calculation
present_value = future_value / (1 + discount_rate/12) ** remaining_months
print (f"The present value of the loan is ${present_value: .2f}")
# End of calculation

# 3. Use conditional statement (an if-else statement) to decide if the present value represents the loan's fair value.
#    If the present value of the loan is greater than or equal to the cost, print a message "the loan is worth at least the cost to buy it."
#    Else, the present value of the loan is less than the loan cost, then print a message "the loan is too expensive and not worth the price."

# Declare variable "loan_price" to capture "laon_price" values from the list "loan"
loan_price = loan.get("loan_price")

# Start of conditional logic
if present_value >= loan_price:
   print ("The loan is worth at least the cost to buy it.")
elif present_value < loan_price:
    print ("The loan is too expensive and not worth the price.")
# End of conditional logic

"""Part 3: Perform Financial Calculations.

Perform financial calculations using functions.

1. Define a new function that will be used to calculate present value.
    a. This function should include parameters for `future_value`, `remaining_months`, and the `annual_discount_rate`
    b. The function should return the `present_value` for the loan.
2. Use the function to calculate the present value of the new loan given below.
    a. Use an `annual_discount_rate` of 0.2 for this new loan calculation.
"""

# Given the following loan data, you will need to calculate the present value for the loan
new_loan = {
    "loan_price": 800,
    "remaining_months": 12,
    "repayment_interval": "bullet",
    "future_value": 1000,
}

# 1. Define a new function that will be used to calculate present value.
#    This function should include parameters for `future_value`, `remaining_months`, and the `annual_discount_rate`
#    The function should return the `present_value` for the loan.

# Start of logic
def calculate_present_value(future_value, remaining_months,annual_discount_rate ):
    present_val = future_value / (1 + discount_rate/12) ** remaining_months
    return present_val
# End of logic


# 2. Use the function (calculate_present_value) to calculate the present value of the new loan given below.
#     Use an `annual_discount_rate` of 0.2 for this new loan calculation.

# Start of logic
future_value = new_loan.get("future_value")
remaining_months = new_loan.get("remaining_months")
annual_discount_rate = .20
present_value = calculate_present_value(future_value, remaining_months,annual_discount_rate )
print(f"The present value of the loan is: ${present_value: .2f}")
# End of logic


"""Part 4: Conditionally filter lists of loans.

In this section, you will use a loop to iterate through a series of loans and select only the inexpensive loans.

1. Create a new, empty list called `inexpensive_loans`.
2. Use a for loop to select each loan from a list of loans.
    a. Inside the for loop, write an if-statement to determine if the loan_price is less than 500
    b. If the loan_price is less than 500 then append that loan to the `inexpensive_loans` list.
3. Print the list of inexpensive_loans.
"""

loans = [
    {
        "loan_price": 700,
        "remaining_months": 9,
        "repayment_interval": "monthly",
        "future_value": 1000,
    },
    {
        "loan_price": 500,
        "remaining_months": 13,
        "repayment_interval": "bullet",
        "future_value": 1000,
    },
    {
        "loan_price": 200,
        "remaining_months": 16,
        "repayment_interval": "bullet",
        "future_value": 1000,
    },
    {
        "loan_price": 900,
        "remaining_months": 16,
        "repayment_interval": "bullet",
        "future_value": 1000,
    },
]

# 1. Create an empty list called `inexpensive_loans`
inexpensive_loans = []

# 2. Loop through all the loans and append any that cost $500 or less to the `inexpensive_loans` list
#How to use For Loop for String
#use a for loop over a collection

# Start of logic
for dic in loans:
     if dic['loan_price'] <= 500:
        if "loan_price" in dic:
            inexpensive_loans.append (dic)
# End of logic
    
# 3. Print the `inexpensive_loans` list
print (f"New entries in Inexpensive loan: {inexpensive_loans}")
         
"""Part 5: Save the results.

Output this list of inexpensive loans to a csv file
    1. Use `with open` to open a new CSV file.
        a. Create a `csvwriter` using the `csv` library.
        b. Use the new csvwriter to write the header variable as the first row.
        c. Use a for loop to iterate through each loan in `inexpensive_loans`.
            i. Use the csvwriter to write the `loan.values()` to a row in the CSV file.

    Hint: Refer to the official documentation for the csv library.
    https://docs.python.org/3/library/csv.html#writer-objects

"""

# Set the output header
header = ["loan_price", "remaining_months", "repayment_interval", "future_value"]

# Set the output file path
output_path = Path("inexpensive_loans.csv")

# 1. Use the csv library and `csv.writer` to write the header row
#    and each row of `loan.values()` from the `inexpensive_loans` list.

# Start of logic
with open('inexpensive_loan.csv', mode='w', newline='') as csv_file:
        writer = csv.DictWriter(csv_file, fieldnames=header)
        writer.writeheader()
        for line in inexpensive_loans:
            writer.writerow(line)
# End of logic
