Spaces:
Runtime error
Runtime error
| import io | |
| import cv2 | |
| import datetime | |
| import calendar | |
| import numpy as np | |
| import pandas as pd | |
| import gradio as gr | |
| import matplotlib.pyplot as plt | |
| from PIL import ImageFont, ImageDraw, Image | |
| from datetime import date, timedelta | |
| from collections import Counter | |
| from typing import NamedTuple | |
| class Reward(): | |
| def __init__(self): | |
| self.stellar_jade = {} | |
| self.special_pass = {} | |
| self.oneiric_shard = 0 | |
| def weekday_count(start_date, end_date): | |
| week = {} | |
| for i in range((end_date - start_date).days): | |
| day = calendar.day_name[(start_date + datetime.timedelta(days=i+1)).weekday()] | |
| week[day] = week[day] + 1 if day in week else 1 | |
| return week | |
| def daterange(start_date, end_date): | |
| for n in range(int((end_date - start_date).days)): | |
| yield start_date + timedelta(n) | |
| def estimator(start_patch, end_patch, mode, equilibrium, data_patch, updating, play_memory_of_chaos, EXPRESS_SUPPLY, BP): | |
| limited_event, permanent_event, explore, moc_n_pf = updating | |
| duration = abs(start_patch - end_patch).days | |
| n_weekdays = weekday_count(start_patch, end_patch) | |
| n_weeks = Counter(n_weekdays.values()).most_common(1)[0][0] | |
| if mode == 1: | |
| start_half = start_patch | |
| end_half = start_half + datetime.timedelta(days = duration // 2 ) | |
| duration = abs(start_half - end_half).days | |
| if mode == 2: | |
| start_half = start_patch + datetime.timedelta(days = duration // 2 ) | |
| end_half = end_patch | |
| duration = abs(start_half - end_half).days | |
| reward = Reward() | |
| reward_SU = {0:75, 1:75, 2:105, 3:135, 4:165, 5:195, 6:225} | |
| reward.stellar_jade['daily_quest'] = 60 * duration | |
| # reward.stellar_jade['chat'] = 5 * duration | |
| if (mode == 0 or mode == 1) : | |
| reward.stellar_jade['update'] = 600 | |
| reward.stellar_jade['permanent_event'] = np.sum([permanent_event[i]['reward'] for i in permanent_event]) | |
| reward.stellar_jade['explore'] = explore | |
| special_event = 'gift_odyssey' | |
| if mode == 0: | |
| reward.stellar_jade['daily_login'] = 80 | |
| reward.stellar_jade['SU'] = reward_SU[equilibrium] * n_weekdays['Monday'] | |
| reward.stellar_jade['character_tryout'] = 20 * data_patch['n_character_banner'] | |
| reward.stellar_jade['character_quest'] = 100 * np.sum([data_patch['n_character_quest'][i] for i in data_patch['n_character_quest']]) | |
| reward.special_pass['Ember'] = 5 * Counter([single_date.day for single_date in daterange(start_patch, end_patch)])[1] | |
| #edit every patch | |
| reward.stellar_jade['event'] = np.sum([limited_event[i]['reward'] for i in limited_event if i != special_event]) | |
| reward.special_pass['event'] = limited_event[special_event]['reward'] | |
| if play_memory_of_chaos: | |
| reward.stellar_jade['moc_n_pf'] = 720 * moc_n_pf['MoC'] | |
| reward.stellar_jade['moc_n_pf'] += 720 * moc_n_pf['PF'] | |
| if EXPRESS_SUPPLY: | |
| reward.stellar_jade['EXPRESS_SUPPLY'] = 90 * duration | |
| reward.oneiric_shard = int(300 * np.ceil(duration/30)) | |
| if BP: | |
| reward.stellar_jade['BP'] = 680 | |
| reward.special_pass['BP'] = 4 | |
| reward.stellar_jade['redeem_code_next_patch'] = 300 | |
| else: | |
| reward.stellar_jade['daily_login'] = 40 | |
| reward.stellar_jade['SU'] = reward_SU[equilibrium] * (n_weekdays['Monday'] // 2) | |
| #companion quest | |
| if mode == 1: reward.stellar_jade['character_quest'] = 100 * data_patch['n_character_quest']['first_half'] | |
| elif mode == 2: reward.stellar_jade['character_quest'] = 100 * data_patch['n_character_quest']['second_half'] | |
| #temporary | |
| reward.stellar_jade['character_tryout'] = 20 * (data_patch['n_character_banner'] // 2) | |
| reward.special_pass['Ember'] = 5 * Counter([single_date.day for single_date in daterange(start_half, end_half)])[1] | |
| #edit every patch | |
| reward.stellar_jade['event'] = np.sum([limited_event[i]['reward'] for i in limited_event if (i != special_event) and (limited_event[i]['date'][0] >= start_half and limited_event[i]['date'][0] + datetime.timedelta(days = 7) < end_half)]) | |
| reward.special_pass['event'] = limited_event[special_event]['reward'] if (limited_event[special_event]['date'][0] >= start_half and start_half + datetime.timedelta(days = 7) < end_half) else 0 | |
| if play_memory_of_chaos: | |
| if mode == 1: | |
| reward.stellar_jade['moc_n_pf'] = 720 * (moc_n_pf['MoC'] + moc_n_pf['PF'] - 1) | |
| else: | |
| reward.stellar_jade['moc_n_pf'] = 720 | |
| if EXPRESS_SUPPLY: | |
| reward.stellar_jade['EXPRESS_SUPPLY'] = 90 * duration | |
| reward.oneiric_shard = int(300 * np.ceil(duration/30)) | |
| if BP: | |
| if mode == 2: | |
| reward.stellar_jade['BP'] = 680 | |
| reward.special_pass['BP'] = 4 | |
| if mode == 2 : reward.stellar_jade['redeem_code_next_patch'] = 300 | |
| return reward | |
| def export_to_image(data): | |
| template = cv2.imread('./template.png') | |
| font = ImageFont.truetype("./DMSans-Regular.ttf", 80) | |
| color = (0, 78, 53) | |
| image_rgb = cv2.cvtColor(template, cv2.COLOR_BGR2RGB) | |
| pil_image = Image.fromarray(image_rgb) | |
| draw = ImageDraw.Draw(pil_image) | |
| pos = [(500, 50), (500, 280), (500, 530)] | |
| text = [int(sum(data.stellar_jade.values())), int(sum(data.special_pass.values())), int(data.oneiric_shard)] | |
| for d, position in zip(text, pos): | |
| draw.text(position, str(d), font=font, fill=color) | |
| return pil_image | |
| def export_to_graph(data): | |
| df = pd.DataFrame(sorted(data.stellar_jade.items(), key = lambda x:x[1], reverse = True), columns = ['source', 'stellar jade']) | |
| source_map = {'daily_quest':'Daily Quest', 'explore':'Exploration', 'permanent_event':'Permanent Event', 'event':'Limited Event', 'moc_n_pf': 'MoC & Pure Fiction', 'SU':'Simulate Universe', 'update':'Update', 'redeem_code_next_patch':'Code live next patch', 'character_quest':'Companion Quest', 'daily_login':'Website daily login', 'character_tryout':'Character trial', 'EXPRESS_SUPPLY':'Express supply', 'BP':'Battle pass', 'chat':'Daily Chat'} | |
| filtered = df[df['stellar jade'] != 0] | |
| source = [source_map[i] for i in filtered['source']] | |
| filtered['source'] = source | |
| df = filtered | |
| df['stellar jade'] = df['stellar jade'].astype('int') | |
| total_jade = df['stellar jade'].sum() | |
| # Figure Size | |
| fig, ax = plt.subplots(figsize =(16, 9)) | |
| stellar_jade = df['stellar jade'] | |
| # Horizontal Bar Plot | |
| ax.barh(source, stellar_jade) | |
| # Remove axes splines | |
| for s in ['top', 'bottom', 'left', 'right']: | |
| ax.spines[s].set_visible(False) | |
| # Remove x, y Ticks | |
| ax.xaxis.set_ticks_position('none') | |
| ax.yaxis.set_ticks_position('none') | |
| # Add padding between axes and labels | |
| ax.xaxis.set_tick_params(pad = 5) | |
| ax.yaxis.set_tick_params(pad = 10) | |
| # Add x, y gridlines | |
| ax.grid(color ='grey',linestyle ='--', linewidth = 0.5,alpha = 0.4) | |
| # Show top values | |
| ax.invert_yaxis() | |
| # Add annotation to bars | |
| for index, i in enumerate(ax.patches): | |
| if index < 3 : | |
| number_color = 'red' | |
| elif index < 6: | |
| number_color = 'orange' | |
| else: number_color = 'grey' | |
| plt.text(i.get_width()+10, i.get_y()+0.5, | |
| str(round((i.get_width()), 2)) + ' ({0}%)'.format(round(100 * (i.get_width() / total_jade), 2)), | |
| fontsize = 10, | |
| color = number_color) | |
| title = 'The Stellar Jade Counter' | |
| ax.set_title(title, | |
| loc ='left', ) | |
| # Add Text watermark | |
| fig.text(0.9, 0.15, 'CHAYEN', fontsize = 12, | |
| color ='grey', ha ='right', va ='bottom', | |
| alpha = 0.7) | |
| buf = io.BytesIO() | |
| fig.savefig(buf) | |
| buf.seek(0) | |
| img = Image.open(buf) | |
| return img | |