async def track(self, ctx, *country):
        if not len(country):
            embed = discord.Embed(
                description=f"No country provided. **`{ctx.prefix}track <COUNTRY>`** work like **`{ctx.prefix}country <COUNTRY>`** see `{ctx.prefix}help`",
                color=utils.COLOR,
                timestamp=utils.discord_timestamp()
            )
            embed.set_author(
                name=f"{ctx.prefix}track",
                icon_url=self.bot.author_thumb
            )
        elif ''.join(country) == "disable":
            embed = discord.Embed(
                description=f"If you want to reactivate the tracker : **`{ctx.prefix}track <COUNTRY>`**",
                color=utils.COLOR,
                timestamp=utils.discord_timestamp()
            )
            embed.set_author(
                name="Tracker has been disabled!",
                icon_url=self.bot.author_thumb
            )
            try:
                await self.bot.delete_tracker(str(ctx.author.id))
            except:
                pass
        else:

            all_data = await utils.get(self.bot.http_session, "/all/")
            country = ' '.join(country)
            data = utils.get_country(all_data, country)
            if data is not None:
                try:
                    await self.bot.insert_tracker(str(ctx.author.id), str(ctx.guild.id), country)
                except IntegrityError:
                    await self.bot.update_tracker(str(ctx.author.id), country)
                embed = discord.Embed(
                    description=f"{utils.mkheader()}You will receive stats about {data['country']} in DM",
                    color=utils.COLOR,
                    timestamp=utils.discord_timestamp()
                )
                embed.set_author(
                    name="Tracker has been set up!",
                    icon_url=f"https://raw.githubusercontent.com/hjnilsson/country-flags/master/png250px/{data['iso2'].lower()}.png"
                )
            else:
                embed = discord.Embed(
                    description="Wrong country selected.",
                    color=utils.COLOR,
                    timestamp=utils.discord_timestamp()
                )
                embed.set_author(
                    name=f"{ctx.prefix}track",
                    icon_url=self.bot.author_thumb
                )
        embed.set_thumbnail(url=self.bot.thumb + str(time.time()))
        embed.set_footer(
            text="coronavirus.jessicoh.com/api/",
            icon_url=ctx.me.avatar_url
        )
        await ctx.send(embed=embed)
示例#2
0
    async def send_notifications(self):
        channels_id = await self.bot.to_send()
        total_history_confirmed = await utils.get(self.bot.http_session,
                                                  "/history/confirmed/total/")
        total_history_recovered = await utils.get(self.bot.http_session,
                                                  "/history/recovered/total/")
        total_history_deaths = await utils.get(self.bot.http_session,
                                               "/history/deaths/total/")

        history_confirmed = await utils.get(self.bot.http_session,
                                            "/history/confirmed/")
        history_recovered = await utils.get(self.bot.http_session,
                                            "/history/recovered/")
        history_deaths = await utils.get(self.bot.http_session,
                                         "/history/deaths/")

        all_data = await utils.get(self.bot.http_session, "/all/")

        for guild in channels_id:
            # go next, didn't match interval for this guild
            if self.interval_update % guild["next_update"] != 0:
                continue
            try:
                embed = discord.Embed(description=utils.mkheader(),
                                      timestamp=dt.datetime.utcnow(),
                                      color=utils.COLOR)
                path = utils.STATS_PATH
                if guild["country"].lower() in ("all", "world"):
                    country = "World"
                else:
                    country = guild["country"]
                    path = (country.replace(" ", "_") +
                            utils.STATS_PATH).lower()

                data = utils.get_country(all_data, country)
                if data is None or (data['newCases'] <= 0
                                    and data['newDeaths'] <= 0):
                    continue

                confirmed = data["totalCases"]
                recovered = data["totalRecovered"]
                deaths = data["totalDeaths"]
                active = data["activeCases"]
                embed.set_author(
                    name=
                    f"Coronavirus COVID-19 Notification - {data['country']}",
                    icon_url=
                    f"https://raw.githubusercontent.com/hjnilsson/country-flags/master/png250px/{data['iso2'].lower()}.png"
                )
                embed.add_field(
                    name="<:confirmed:688686089548202004> Confirmed",
                    value=f"{confirmed:,}")
                embed.add_field(
                    name="<:recov:688686059567185940> Recovered",
                    value=
                    f"{recovered:,} (**{utils.percentage(confirmed, recovered)}**)"
                )
                embed.add_field(
                    name="<:_death:688686194917244928> Deaths",
                    value=
                    f"{deaths:,} (**{utils.percentage(confirmed, deaths)}**)")

                embed.add_field(
                    name="<:_calendar:692860616930623698> Today confirmed",
                    value=
                    f"+{data['newCases']:,} (**{utils.percentage(confirmed, data['newCases'])}**)"
                )
                embed.add_field(
                    name="<:_calendar:692860616930623698> Today deaths",
                    value=
                    f"+{data['newDeaths']:,} (**{utils.percentage(confirmed, data['newDeaths'])}**)"
                )
                embed.add_field(
                    name="<:bed_hospital:692857285499682878> Active",
                    value=
                    f"{active:,} (**{utils.percentage(confirmed, active)}**)")
                embed.add_field(
                    name="<:critical:752228850091556914> Serious critical",
                    value=
                    f"{data['seriousCritical']:,} (**{utils.percentage(confirmed, data['seriousCritical'])}**)"
                )
                if data["totalTests"]:
                    percent_pop = ""
                    if data["population"]:
                        percent_pop = f"(**{utils.percentage(data['population'], data['totalTests'])}**)"

                    embed.add_field(
                        name="<:test:752252962532884520> Total test",
                        value=f"{data['totalTests']:,} {percent_pop}")

                if not os.path.exists(path) and country != "World":
                    await plot_csv(
                        path,
                        utils.get_country_history(history_confirmed, country),
                        utils.get_country_history(history_recovered, country),
                        utils.get_country_history(history_deaths, country))
                elif not os.path.exists(path):
                    await plot_csv(path, total_history_confirmed,
                                   total_history_recovered,
                                   total_history_deaths)

                with open(path, "rb") as p:
                    img = discord.File(p, filename=path)
                embed.set_image(url=f'attachment://{path}')
                embed.set_thumbnail(url=self.bot.thumb + str(time.time()))
                channel = self.bot.get_channel(int(guild["channel_id"]))
                try:
                    embed.set_footer(
                        text="coronavirus.jessicoh.com/api/ | " +
                        utils.last_update(all_data[0]['lastUpdate']))
                except Exception as e:
                    pass
                await channel.send(file=img, embed=embed)
            except Exception as e:
                pass
        logger.info("Notifications sent")
示例#3
0
async def notification_command(bot,
                               ctx: Union[commands.Context, SlashContext],
                               country="all",
                               interval: int = None,
                               interval_type=None,
                               state: list = []):
    if type(ctx) == commands.Context:
        country, interval, interval_type = unpack_notif(state, "every")
        print(country, interval, interval_type)
        guild_permissions = ctx.message.author.guild_permissions
    elif type(ctx) == SlashContext:
        interval = int(interval)
        guild_permissions = ctx.author.guild_permissions
    else:
        raise ContextError(f"Context error : {ctx}")
    if not guild_permissions.administrator:
        return await ctx.send(
            "You need to have Administrator permission to set notification on !"
        )
    try:
        prefix = await bot.getg_prefix(ctx.guild.id)
    except:
        prefix = "c!"
    if len(state) or interval is not None:
        all_data = await utils.get(bot.http_session, "/all/")
        try:
            data = utils.get_country(all_data, country)
            try:
                await bot.insert_notif(str(ctx.guild.id), str(ctx.channel.id),
                                       country, interval)

            except IntegrityError:
                await bot.update_notif(str(ctx.guild.id), str(ctx.channel.id),
                                       country, interval)
            finally:
                if country != "all":
                    embed = discord.Embed(
                        description=
                        f"You will receive a notification in this channel on data update. `{prefix}notififcation disable` to disable the notifications"
                    )
                    embed.set_author(
                        name="Notifications successfully enabled",
                        icon_url=
                        f"https://raw.githubusercontent.com/hjnilsson/country-flags/master/png250px/{data['iso2'].lower()}.png"
                    )
                    embed.add_field(name="Country",
                                    value=f"**{data['country']}**")
                    embed.add_field(
                        name="Next update",
                        value=
                        f"**{interval // convert_interval_type(interval_type)} {interval_type}**"
                    )
                elif country == "all":
                    embed = discord.Embed(
                        description=
                        f"You will receive a notification in this channel on data update. `{prefix}notififcation disable` to disable the notifications"
                    )
                    embed.set_author(name="Notifications successfully enabled",
                                     icon_url=bot.author_thumb)

                    embed.add_field(name="Country", value=f"**World stats**")
                    embed.add_field(
                        name="Next update",
                        value=
                        f"**{interval // convert_interval_type(interval_type)} {interval_type}**"
                    )
        except Exception as e:
            embed = discord.Embed(
                title=f"{prefix}notification",
                description=
                f"Make sure that you didn't have made any mistake, please retry\n`{prefix}notification <country | disable> [every NUMBER] [hours | days | weeks]`\n__Examples__ : `{prefix}notification usa every 3 hours` (send a message to the current channel every 3 hours about United States), `{prefix}notification united states every 1 day`, `{prefix}notification disable`"
            )
            embed.add_field(
                name="Report this error to the developer please ! :heart:",
                value=f"{type(e).__name__} : {e}")
            logger.exception(e, exc_info=True)

        if country == "disable":
            await bot.delete_notif(str(ctx.guild.id))
            embed = discord.Embed(
                title="Notifications successfully disabled",
                description="Notifications are now interrupted in this channel."
            )
    else:
        embed = discord.Embed(
            title=f"{prefix}notification",
            description=
            f"Make sure that you didn't have made any mistake, please retry\n`{prefix}notification <country | disable> [every NUMBER] [hours | days | weeks]`\n__Examples__ : `{prefix}notification usa every 3 hours` (send a message to the current channel every 3 hours about United States), `{prefix}notification united states every 1 day`, `{prefix}notification disable`"
        )

    embed.color = utils.COLOR
    embed.timestamp = utils.discord_timestamp()
    embed.set_thumbnail(url=bot.thumb + str(time.time()))
    embed.set_footer(text="coronavirus.jessicoh.com/api/ | " +
                     utils.last_update(all_data[0]["lastUpdate"]),
                     icon_url=bot.user.avatar_url)
    await ctx.send(embed=embed)
    async def notification(self, ctx, *state):
        if len(state):
            all_data = await utils.get(self.bot.http_session, "/all/")
            country, interval, interval_type = self._unpack_notif(state, "every")
            try:
                data = utils.get_country(all_data, country)
                try:
                    await self.bot.insert_notif(str(ctx.guild.id), str(ctx.channel.id), country, interval)

                except IntegrityError:
                    await self.bot.update_notif(str(ctx.guild.id), str(ctx.channel.id), country, interval)
                finally:
                    if country != "all":
                        embed = discord.Embed(
                            description=f"You will receive a notification in this channel on data update. `{ctx.prefix}notififcation disable` to disable the notifications"
                        )
                        embed.set_author(
                            name="Notifications successfully enabled",
                            icon_url=self.bot.author_thumb
                        )
                        embed.add_field(
                            name="Country",
                            value=f"**{data['country']}**"
                        )
                        embed.add_field(
                            name="Next update",
                            value=f"**{interval // self._convert_interval_type(interval_type)} {interval_type}**"
                        )
                    elif country == "all":
                        embed = discord.Embed(
                            description=f"You will receive a notification in this channel on data update. `{ctx.prefix}notififcation disable` to disable the notifications"
                        )
                        embed.set_author(
                            name="Notifications successfully enabled",
                            icon_url=self.bot.author_thumb
                        )
                        embed.add_field(
                            name="Country",
                            value=f"**World stats**"
                        )
                        embed.add_field(
                            name="Next update",
                            value=f"**{interval // self._convert_interval_type(interval_type)} {interval_type}**"
                        )
            except Exception as e:
                embed = discord.Embed(
                    title=f"{ctx.prefix}notification",
                    description=f"Make sure that you didn't have made any mistake, please retry\n`{ctx.prefix}notification <country | disable> [every NUMBER] [hours | days | weeks]`\n__Examples__ : `{ctx.prefix}notification usa every 3 hours` (send a message to the current channel every 3 hours about United States), `{ctx.prefix}notification united states every 1 day`, `{ctx.prefix}notification disable`"
                )
                print(e)

            if country == "disable":
                await self.bot.delete_notif(str(ctx.guild.id))
                embed = discord.Embed(
                    title="Notifications successfully disabled",
                    description="Notifications are now interrupted in this channel."
                )
        else:
            embed = discord.Embed(
                title=f"{ctx.prefix}notification",
                description=f"Make sure that you didn't have made any mistake, please retry\n`{ctx.prefix}notification <country | disable> [every NUMBER] [hours | days | weeks]`\n__Examples__ : `{ctx.prefix}notification usa every 3 hours` (send a message to the current channel every 3 hours about United States), `{ctx.prefix}notification united states every 1 day`, `{ctx.prefix}notification disable`"
            )

        embed.color = utils.COLOR
        embed.timestamp = utils.discord_timestamp()
        embed.set_thumbnail(url=self.bot.thumb + str(time.time()))
        embed.set_footer(
            text="coronavirus.jessicoh.com/api/ | " + utils.last_update(all_data[0]["lastUpdate"]),
            icon_url=ctx.me.avatar_url
        )
        await ctx.send(embed=embed)
示例#5
0
def generate_plot(data, df_all_prediction):
    COLORS = d3["Category10"][10]

    tooltips = f"""
            <div>
                <p>
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre de cas : </span>
                    <span style="font-size: 12px; color: {COLORS[0]}; font-weight: bold;font-family:century gothic;">@total_cases</span>
                <br> 
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre de nouveaux cas : </span>
                    <span style="font-size: 12px; color: {COLORS[1]}; font-weight: bold;font-family:century gothic;">@new_cases</span>
                <br> 
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre de deces : </span>
                    <span style="font-size: 12px; color: {COLORS[3]}; font-weight: bold;font-family:century gothic;">@total_deaths</span>
                <br> 
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre nouveaux deces : </span>
                    <span style="font-size: 12px; color: {COLORS[5]}; font-weight: bold;font-family:century gothic;">@new_deaths</span>
                <br> 
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Date : </span>
                    <span style="font-size: 12px; color: black; font-weight: bold;font-family:century gothic;">@date_str</span>
                </p>
            </div>
        """

    tooltips_predictions = (f"""
            <div>
                <p>
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Prédiction nombre de cas : </span>
                    <span style="font-size: 12px; color: {COLORS[0]}; font-weight: bold;font-family:century gothic;">@median_display</span>
                <br> 
                    <span style="font-size: 12px; color: black;font-family:century gothic;">Date : </span>
                    <span style="font-size: 12px; color: black; font-weight: bold;font-family:century gothic;">"""
                            + """@date_str</span>
                </p>
            </div>
        """)

    hover = bkm.tools.HoverTool(names=["line_total"],
                                tooltips=tooltips,
                                mode="vline")

    hover_prediction = bkm.tools.HoverTool(
        names=["prediction"],
        tooltips=tooltips_predictions,
    )

    # --- define all DataSource needed --- #

    source_all = bkm.ColumnDataSource(data)
    country = "World"
    source = bkm.ColumnDataSource(get_country(data, country))

    source_all_prediction = bkm.ColumnDataSource(df_all_prediction)
    source_prediction = bkm.ColumnDataSource(
        get_country(df_all_prediction, country))

    date_end_training = np.unique(
        get_country(df_all_prediction, country)["date_end_train"])[-1]
    source_prediction_end_date = bkm.ColumnDataSource(
        get_country(df_all_prediction, country)[get_country(
            df_all_prediction, country).date_end_train == date_end_training])

    slider = bkm.Slider(
        start=0,
        end=len(
            np.unique(
                get_country(df_all_prediction, country)["date_end_train"])) -
        1,
        value=0,
        step=1,
        title="Days dropped for prediction",
    )

    # ----------- #

    p = bkp.figure(
        y_axis_type="linear",
        x_axis_type="datetime",
        sizing_mode="stretch_both",
        title=f"Covid 19 evolution: {country}",
        x_axis_label="date",
        y_axis_label="Total number of Covid 19 cases",
        tools=[hover, "pan", "wheel_zoom", "reset"],
        x_range=[
            get_country(data, country).date.min(),
            get_country(data, country).date.max() + datetime.timedelta(days=1),
        ],
        y_range=[
            -get_country(data, country).total_cases.max() * 0.05,
            get_country(data, country).total_cases.max() * 1.1,
        ],
    )
    p.yaxis.formatter = bkm.formatters.NumeralTickFormatter(format="0,0")
    p.xaxis.formatter = bkm.formatters.DatetimeTickFormatter(
        days=["%d/%m", "%d%a"], months=["%m/%Y", "%b %Y"])
    p.add_tools(hover_prediction)
    p.toolbar.active_drag = None

    # p.toolbar.active_scroll = p.select_one(bkm.WheelZoomTool)

    y_extra_range_max = np.max([
        np.max(get_country(data, country).new_cases.values),
        np.max(get_country(data, country).total_deaths.values),
    ])

    p.extra_y_ranges = {
        "Number of deaths":
        bkm.Range1d(start=-0.05 * y_extra_range_max,
                    end=1.1 * y_extra_range_max)
    }
    p.add_layout(
        bkm.LinearAxis(
            y_range_name="Number of deaths",
            axis_label="New Covid 19 cases",
            formatter=bkm.formatters.NumeralTickFormatter(format="0,0"),
        ),
        "right",
    )

    # --- plot total cases --- #

    p.line(
        source=source,
        x="date",
        y="total_cases",
        name="line_total",
        color=COLORS[0],
        legend_label="total cases",
        muted_alpha=0.1,
    )
    p.circle(source=source,
             x="date",
             y="total_cases",
             color=COLORS[0],
             muted_alpha=0.1)

    # --- plot new cases --- #

    p.vbar(
        source=source,
        x="date",
        top="new_cases",
        color=COLORS[1],
        width=50e6,
        alpha=0.5,
        name="bar",
        y_range_name="Number of deaths",
        legend_label="new cases",
        muted_alpha=0.1,
    )

    # --- plot total death --- #

    p.line(
        source=source,
        x="date",
        y="total_deaths",
        color=COLORS[3],
        y_range_name="Number of deaths",
        name="line_death",
        legend_label="total deaths",
        muted_alpha=0.1,
    )
    p.circle(
        source=source,
        x="date",
        y="total_deaths",
        color=COLORS[3],
        y_range_name="Number of deaths",
        muted_alpha=0.1,
    )

    # --- plot new death --- #

    p.vbar(
        source=source,
        x="date",
        top="new_deaths",
        color=COLORS[5],
        width=50e6,
        alpha=0.5,
        y_range_name="Number of deaths",
        legend_label="new deaths",
        muted_alpha=0.1,
    )

    button_click_count = bkm.ColumnDataSource({"clicks": [0]})

    select = bkm.Select(title="Country: ",
                        value=country,
                        options=list(data.location.unique()))
    button_log = bkm.Button(label="Log Scale", button_type="primary")

    # --- Predictions --- #

    median_prediction = p.line(
        source=source_prediction_end_date,
        x="date",
        y="median",
        line_color=COLORS[0],
        name="prediction",
    )
    prediction_cases_line = p.line(
        source=source_prediction_end_date,
        x="date",
        y="derivative",
        color=COLORS[1],
        y_range_name="Number of deaths",
    )

    band_low = bkm.Band(
        source=source_prediction_end_date,
        base="date",
        lower="25%",
        upper="median",
        fill_color=COLORS[0],
        level="underlay",
        fill_alpha=0.1,
        line_width=0.5,
        line_color="black",
    )

    band_high = bkm.Band(
        source=source_prediction_end_date,
        base="date",
        lower="median",
        upper="75%",
        fill_color=COLORS[0],
        level="underlay",
        fill_alpha=0.1,
        line_width=0.5,
        line_color="black",
    )

    median_prediction.visible = False
    prediction_cases_line.visible = False
    band_low.visible = False
    band_high.visible = False

    p.add_layout(band_low)
    p.add_layout(band_high)

    button_prediction = bkm.Button(label="Show predictions",
                                   button_type="primary")

    # -- Callback -- #

    callback = bkm.CustomJS(
        args=dict(
            source=source,
            source_all=source_all,
            select=select,
            x_range=p.x_range,
            y_range_left=p.y_range,
            y_range_right=p.extra_y_ranges["Number of deaths"],
            title=p.title,
            button_click_count=button_click_count,
            slider=slider,
            source_all_prediction=source_all_prediction,
            source_prediction=source_prediction,
            source_prediction_end_date=source_prediction_end_date,
            median_prediction=median_prediction,
            band_low=band_low,
            prediction_cases_line=prediction_cases_line,
            band_high=band_high,
        ),
        code="""
        var country = select.value
    
        var date = source_all.data['date']
        var date_str = source_all.data['date_str']
        var location = source_all.data['location']
        var total_cases = source_all.data['total_cases']
        var new_cases = source_all.data['new_cases']
        var total_deaths = source_all.data['total_deaths']
        var new_deaths = source_all.data['new_deaths']
    
    
        var new_date = []
        var new_date_str = []
        var new_total_cases = []
        var new_new_cases = []
        var new_total_deaths = []
        var new_new_deaths = []
    
    
        for(var i=0; i < date.length; i++){
            if(location[i]==country){
                new_date.push(date[i]);
                new_date_str.push(date_str[i])
                new_total_cases.push(total_cases[i]);
                new_new_cases.push(new_cases[i]);
                new_total_deaths.push(total_deaths[i]);
                new_new_deaths.push(new_deaths[i]);
            }
        }
    
        source.data['date']=new_date;
        source.data['date_str']=new_date_str;
        source.data['total_cases']=new_total_cases;
        source.data['new_cases']=new_new_cases;
        source.data['total_deaths']=new_total_deaths;
        source.data['new_deaths']=new_new_deaths;
    
        const new_cases_no_Nan = new_new_cases.filter(function (value) {
            return !Number.isNaN(value);
        });
        const cases_no_Nan = new_total_cases.filter(function (value) {
            return !Number.isNaN(value);
        });
    
        y_range_right.setv({"start": -0.05*Math.max.apply(Math, new_cases_no_Nan.concat(new_total_deaths)), 
                            "end": 1.1*Math.max.apply(Math, new_cases_no_Nan.concat(new_total_deaths))})
    
        y_range_left.setv({"start": -0.05*Math.max.apply(Math, cases_no_Nan), 
                           "end": 1.1*Math.max.apply(Math, cases_no_Nan)})
    
        x_range.setv({"start": Math.min.apply(Math, new_date), "end": 1.0001*Math.max.apply(Math, new_date)})
    
        title.text = "Evolution du nombre de cas en " + country
    
        source.change.emit();
    
    
        // change value of predictions
    
        button_click_count.data.clicks = 0
    
        median_prediction.visible = false
        band_low.visible = false
        band_high.visible = false
        prediction_cases_line.visble = false
    
        var date_end_prediction = source_all_prediction.data['date_end_train']
    
        var location = source_all_prediction.data['location']
        var date = source_all_prediction.data['date']
        var date_str = source_all_prediction.data['date_str']
        var quantile_1 = source_all_prediction.data['25%']
        var quantile_2 = source_all_prediction.data['median']
        var quantile_3 = source_all_prediction.data['75%']
        var new_cases = source_all_prediction.data['derivative']
        var median_prediction = source_all_prediction.data['median_display']
    
        var new_date = []
        var new_date_str = []
        var new_date_end_prediction = []
        var new_quantile_1 = []
        var new_quantile_2 = []
        var new_quantile_3 = []
        var new_new_cases = []
        var new_median_prediction = []
    
        for(var i=0; i < quantile_1.length; i++){
            if(location[i]==country){
                new_date.push(date[i])
                new_date_str.push(date_str[i])
                new_date_end_prediction.push(date_end_prediction[i])
                new_quantile_1.push(quantile_1[i]);
                new_quantile_2.push(quantile_2[i]);
                new_quantile_3.push(quantile_3[i]);
                new_new_cases.push(new_cases[i]);
                new_median_prediction.push(median_prediction[i]);
            }
        }   
        source_prediction.data['date']=new_date
        source_prediction.data['date_str']=new_date_str
        source_prediction.data['date_end_train']=new_date_end_prediction
        source_prediction.data['25%']=new_quantile_1;
        source_prediction.data['median']=new_quantile_2;
        source_prediction.data['75%']=new_quantile_3;
        source_prediction.data['derivative']=new_new_cases;
        source_prediction.data['median_display']=new_median_prediction;
    
    
        var n = new_date.length
        var max_date = Math.max.apply(Math, new_date_end_prediction)
    
        var new_date_bis = []
        var new_date_str_bis = []
        var new_date_end_prediction_bis = []
        var new_quantile_1_bis = []
        var new_quantile_2_bis = []
        var new_quantile_3_bis = []
        var new_new_cases_bis = []
        var new_median_prediction_bis = []
    
        for(var i=0; i < n; i++){
            if(new_date_end_prediction[i]==max_date){
                new_date_bis.push(new_date[i])
                new_date_str_bis.push(new_date_str[i])
                new_date_end_prediction_bis.push(new_date_end_prediction[i])
                new_quantile_1_bis.push(new_quantile_1[i]);
                new_quantile_2_bis.push(new_quantile_2[i]);
                new_quantile_3_bis.push(new_quantile_3[i]);
                new_new_cases_bis.push(new_new_cases[i]);
                new_median_prediction_bis.push(new_median_prediction[i]);
            }
        }
    
        var n = new_date_bis.length
        var max_date = Math.max.apply(Math, new_date_end_prediction_bis)
    
        source_prediction_end_date.data['date']=new_date_bis
        source_prediction_end_date.data['date_str']=new_date_str_bis
        source_prediction_end_date.data['date_end_train']=new_date_end_prediction_bis
        source_prediction_end_date.data['25%']=new_quantile_1_bis;
        source_prediction_end_date.data['median']=new_quantile_2_bis;
        source_prediction_end_date.data['75%']=new_quantile_3_bis;
        source_prediction_end_date.data['derivative']=new_new_cases_bis;
        source_prediction_end_date.data['median_display']=new_median_prediction_bis;
    
        source_prediction.change.emit();
        source_prediction_end_date.change.emit()
    
    
    
        const unique = (value, index, self) => {
                   return self.indexOf(value) === index
               }
    
        // change slider value
    
        slider.setv({"end": new_date_end_prediction.filter(unique).length - 1, "value": 0})
    
        """,
    )

    callback_button = bkm.CustomJS(
        args=dict(y_axis=p.left, title=p.title),
        code="""
        console.log(y_axis)
        y_axis = LogAxis()
    """,
    )

    select.js_on_change("value", callback)
    button_log.js_on_click(callback_button)

    callback_button = bkm.CustomJS(
        args=dict(
            source=source,
            source_prediction=source_prediction,
            source_all_prediction=source_all_prediction,
            source_prediction_end_date=source_prediction_end_date,
            select=select,
            button_prediction=button_prediction,
            median_prediction=median_prediction,
            band_low=band_low,
            prediction_cases_line=prediction_cases_line,
            band_high=band_high,
            button_click_count=button_click_count,
            x_range=p.x_range,
            y_range_left=p.y_range,
            y_range_right=p.extra_y_ranges["Number of deaths"],
        ),
        code="""
           // function to get unique value of an array
           const unique = (value, index, self) => {
               return self.indexOf(value) === index
           }

           var date = source.data['date'];
           var total_cases = source.data['total_cases'];
           var new_cases = source.data['new_cases'];
           var total_deaths = source.data['total_deaths'];

           var date_prediction = source_prediction.data['date'];
           var total_cases_prediction = source_prediction.data['75%'];

           const new_cases_no_Nan = new_cases.filter(function (value) {
               return !Number.isNaN(value);
           });
           const cases_no_Nan = total_cases.filter(function (value) {
               return !Number.isNaN(value);
           });

           var country = select.value
           button_click_count.data.clicks ++
           var show_prediction = (button_click_count.data.clicks % 2) == 1

           var locations_predicted = source_all_prediction.data['location'].filter(unique)

           if (locations_predicted.includes(country) == false){
               window.alert("This country doesn't have prediction: Available countries are: " + locations_predicted);
           }
           else{
               if (show_prediction == true){
                   median_prediction.visible = true
                   band_low.visible = true
                   band_high.visible = true
                   prediction_cases_line.visble = true
                   const y_range_right_values = [].concat([].slice.call(new_cases_no_Nan), [].slice.call(total_deaths))

                   y_range_left.setv({"start": -0.05*Math.max.apply(Math, total_cases_prediction), "end": 1.1 * Math.max.apply(Math, total_cases_prediction)})
                   y_range_right.setv({"start": -0.05*Math.max.apply(Math, y_range_right_values) * Math.max.apply(Math, total_cases_prediction) / Math.max.apply(Math, cases_no_Nan),
                                       "end": 1.1*Math.max.apply(Math, y_range_right_values) * Math.max.apply(Math, total_cases_prediction) / Math.max.apply(Math, cases_no_Nan)})

                   x_range.setv({"start": Math.min.apply(Math, date_prediction), "end": 1.0001*Math.max.apply(Math, date_prediction)})
               }
               else{
                   median_prediction.visible = false
                   band_low.visible = false
                   band_high.visible = false
                   prediction_cases_line.visble = false
                   const y_range_right_values = [].concat([].slice.call(new_cases_no_Nan), [].slice.call(total_deaths))

                   y_range_left.setv({"start": -0.05*Math.max.apply(Math, cases_no_Nan), "end": 1.1*Math.max.apply(Math, cases_no_Nan)})
                   y_range_right.setv({"start": -0.05*Math.max.apply(Math, y_range_right_values), "end": 1.1*Math.max.apply(Math, y_range_right_values)})
                   x_range.setv({"start": Math.min.apply(Math, date), "end": 1.0001*Math.max.apply(Math, date)})

               }
           }


           """,
    )

    button_prediction.js_on_click(callback_button)

    callback_slider = bkm.CustomJS(
        args=dict(
            source=source,
            source_prediction=source_prediction,
            source_all_prediction=source_all_prediction,
            source_prediction_end_date=source_prediction_end_date,
            select=select,
            prediction_cases_line=prediction_cases_line,
            slider=slider,
            button_click_count=button_click_count,
            x_range=p.x_range,
            y_range_left=p.y_range,
            y_range_right=p.extra_y_ranges["Number of deaths"],
        ),
        code="""

                           // function to get unique value of an array
                           const unique = (value, index, self) => {
                               return self.indexOf(value) === index
                           }

                           var slider_value = slider.value
                           var country = select.value

                           var date_prediction = source_prediction.data['date']
                           var date_str = source_prediction.data['date_str']
                           var date_end_prediction = source_prediction.data['date_end_train']
                           var quantile_1 = source_prediction.data['25%'];
                           var quantile_2 = source_prediction.data['median']
                           var quantile_3 = source_prediction.data['75%']
                           var new_cases = source_prediction.data['derivative'];
                           var median_prediction = source_prediction.data['median_display']

                           var unique_end_prediction = date_end_prediction.filter(unique)

                           var show_prediction = (button_click_count.data.clicks % 2) == 1
                           var locations_predicted = source_all_prediction.data['location'].filter(unique)

                           if (show_prediction == true && locations_predicted.includes(country)){
                                var new_date_prediction = []
                                var new_date_str = []
                                var new_date_end_prediction = []
                                var new_quantile_1 = []
                                var new_quantile_2 = []
                                var new_quantile_3 = []
                                var new_new_cases = []
                                var new_median_prediction = []

                                for(var i=0; i < quantile_1.length; i++){
                                    if(date_end_prediction[i]==unique_end_prediction[slider.end - slider_value]){
                                        new_date_prediction.push(date_prediction[i])
                                        new_date_str.push(date_str[i])
                                        new_date_end_prediction.push(date_end_prediction[i])
                                        new_quantile_1.push(quantile_1[i]);
                                        new_quantile_2.push(quantile_2[i]);
                                        new_quantile_3.push(quantile_3[i]);
                                        new_new_cases.push(new_cases[i]);
                                        new_median_prediction.push(median_prediction[i]);
                                    }
                                }   


                                source_prediction_end_date.data['date']=new_date_prediction
                                source_prediction_end_date.data['date_str']=new_date_str
                                source_prediction_end_date.data['date_end_train']=new_date_end_prediction
                                source_prediction_end_date.data['25%']=new_quantile_1;
                                source_prediction_end_date.data['median']=new_quantile_2;
                                source_prediction_end_date.data['75%']=new_quantile_3;
                                source_prediction_end_date.data['derivative']=new_new_cases;
                                source_prediction_end_date.data['median_display']=new_median_prediction;

                                source_prediction_end_date.change.emit();

                                var date_prediction = source_prediction_end_date.data['date'];
                                var total_cases_prediction = source_prediction_end_date.data['75%'];

                                const new_cases_no_Nan = new_cases.filter(function (value) {
                                    return !Number.isNaN(value);
                                 });
                                const cases_no_Nan = quantile_2.filter(function (value) {
                                   return !Number.isNaN(value);
                                 });


                                // y_range_left.setv({"start": -0.05*Math.max.apply(Math, total_cases_prediction), "end": 1.1*Math.max.apply(Math, total_cases_prediction)})
                                // x_range.setv({"start": Math.min.apply(Math, date_prediction), "end": 1.0001*Math.max.apply(Math, date_prediction)})

                           }

                                   """,
    )

    slider.js_on_change("value", callback_slider)

    p.legend.location = "top_left"
    p.legend.click_policy = "mute"

    return select, button_prediction, slider, p