File size: 4,156 Bytes
5ca0c3c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from datetime import datetime

import pandas as pd
import streamlit as st


def months_between_dates(start_date, end_date):
    return (end_date.year - start_date.year) * 12 + (end_date.month - start_date.month)

def calculate_lifespan(row):
    if pd.notna(row["Churned"]):
        return (row["Churned"] - row["Date"]).days
    else:
        return (datetime.now() - row["Date"]).days
    
def date_filtered_df(df, start_date, end_date):
    return df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]

def average_customer_lifespan_calculation(
        df,
        start_date,
        end_date,
    ) -> float:
    df.sort_values(by=['Customer', 'Date'], inplace=True)
    mask = (df['Date'] >= start_date) & (df['Date'] <= end_date)
    df = df.loc[mask]
    df["Lifespan"] = df.apply(calculate_lifespan, axis=1)
    df = df.dropna(subset=["Value"])
    # Calculate average customer lifespan
    return round(df["Lifespan"].mean(), 0)


def icon_select(value):
    if value >= 7:
        return 'πŸš€'
    elif value >= 5:
        return 'πŸ”₯'
    elif value > 3.5:
        return 'πŸ’€'
    else:
        return 'πŸ’€'

@st.cache_data(ttl="5m")
def get_data(file_link):
    
    if 'dl=0' in file_link:
        file_link = file_link.replace('dl=0', 'dl=1')
    all_data_df = pd.read_excel(file_link)
    return all_data_df


st.title('Customer LTV Calculator')

file_link = st.text_input(
    'Link to data file',
)

if not file_link:
    st.stop()

all_data_df = get_data(file_link)

col1, col2, col3 = st.columns(3)
with col1:
    start_date = st.date_input(
        'Start Date:',
        value=pd.to_datetime('2022-09-01'),
        max_value=pd.to_datetime(datetime.now().date()),
        format='DD-MM-YYYY',
    )
with col2:
    end_date = st.date_input(
        'End Date:',
        value=pd.to_datetime(datetime.now().date()),
        max_value=pd.to_datetime(datetime.now().date()),
        format='DD-MM-YYYY',
    )
with col3:
    start_datetime = pd.to_datetime(start_date)
    end_datetime = pd.to_datetime(end_date)
    number_of_months = months_between_dates(start_datetime, end_datetime)
    st.write(str(number_of_months), 'months')

calculated_acl = average_customer_lifespan_calculation(
    all_data_df,
    start_datetime,
    end_datetime,
)

if start_date < end_date:
    # Filter the dataframe based on the selected date range
    mask = (all_data_df['Date'] >= start_datetime) & (all_data_df['Date'] <= end_datetime)
    all_data_df = all_data_df.loc[mask]
else:
    st.error('Error: End date must be after the start date.')

all_data_date_filtered = date_filtered_df(all_data_df, start_datetime, end_datetime)
average_order_size = all_data_date_filtered['Value'].mean()
formatted_num = "Β£{:,.2f}".format(average_order_size)
st.write('Average order size (AOS):', str(formatted_num))

purchase_frequency = all_data_date_filtered.groupby('Customer')['Date'].nunique()
average_purchase_frequency_rate = purchase_frequency.mean()/number_of_months
st.write('Average purchase frequency rate (APFR) per customer per month:', str(round(average_purchase_frequency_rate, 2)))
customer_value = average_order_size * average_purchase_frequency_rate
customer_value_formatted = "Β£{:,.2f}".format(customer_value)
st.write('Customer Value (AOS x APFR):', customer_value_formatted)

average_customer_lifespan = 12
average_customer_lifespan = st.slider(
    f'Average Customer Lifespan (months) - calculated value {calculated_acl} days',
    min_value=1,
    max_value=50,
    step=1,
    value=12,
)
customer_lifetime_vale = average_customer_lifespan * customer_value
customer_lifetime_vale_formatted = "Β£{:,.2f}".format(customer_lifetime_vale)
st.write('Customer Lifetime Value (CLV):', customer_lifetime_vale_formatted)

acquisition_cost = 50
acquisition_cost = st.slider('Cost of acquisition', min_value=0, max_value=1000, step=10, value=50)
clv_cac_ratio = customer_lifetime_vale/acquisition_cost

all_data_df['year_month'] = all_data_df['Date'].dt.to_period('M')
all_data_df = all_data_df.sort_values(by='Date')

st.write(
    'CLV to CAC ratio:',
    "{:,.2f}".format(clv_cac_ratio),
    ': 1',
    icon_select(clv_cac_ratio),
)